From f325b2fa5bf7f88dd358298937bb53695b11326c Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 06 2018 18:40:08 +0000 Subject: import libreoffice-5.0.6.2-15.el7_4 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6db8906 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +SOURCES/0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz +SOURCES/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip +SOURCES/185d60944ea767075d27247c3162b3bc-unowinreg.dll +SOURCES/1f24ab1d39f4a51faf22244c94a6203f-xmlsec1-1.2.14.tar.gz +SOURCES/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip +SOURCES/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip +SOURCES/a7983f859eafb2677d7ff386a023bc40-xsltml_2.1.2.zip +SOURCES/libreoffice-5.0.6.2.tar.xz +SOURCES/libreoffice-base-symbolic.svg +SOURCES/libreoffice-calc-symbolic.svg +SOURCES/libreoffice-draw-symbolic.svg +SOURCES/libreoffice-help-5.0.6.2.tar.xz +SOURCES/libreoffice-impress-symbolic.svg +SOURCES/libreoffice-main-symbolic.svg +SOURCES/libreoffice-math-symbolic.svg +SOURCES/libreoffice-translations-5.0.6.2.tar.xz +SOURCES/libreoffice-writer-symbolic.svg diff --git a/.libreoffice.metadata b/.libreoffice.metadata new file mode 100644 index 0000000..6e0dadc --- /dev/null +++ b/.libreoffice.metadata @@ -0,0 +1,17 @@ +452eba922e4f41603539c9dc39947d2271e47093 SOURCES/0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz +7168b0f40aa5c72267899601c116d2348d2f56ec SOURCES/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip +0619ed3a89644bef318df67db12045b2b590585b SOURCES/185d60944ea767075d27247c3162b3bc-unowinreg.dll +8f949ae74a6d66278a595bd063f13e0ad196d14a SOURCES/1f24ab1d39f4a51faf22244c94a6203f-xmlsec1-1.2.14.tar.gz +1acea86fd399ed7817879d36370d3d1f8b109050 SOURCES/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip +8a90669029e107b61953b90ba11545fef586c2ca SOURCES/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip +2d49e11b0b711970f494294dc3698f05eb294853 SOURCES/a7983f859eafb2677d7ff386a023bc40-xsltml_2.1.2.zip +ba2784668b0cbded6595904207912e5f3d1905c1 SOURCES/libreoffice-5.0.6.2.tar.xz +54fc749ba924f9ca4e0391caaf579ab344302038 SOURCES/libreoffice-base-symbolic.svg +9de544172d736d59589767000c1f657034a5d53d SOURCES/libreoffice-calc-symbolic.svg +0f6dc4726da0920869354fbe4b2924f9ac569b4a SOURCES/libreoffice-draw-symbolic.svg +0ee2fa2cd239171796951e6d30537f7236d479cc SOURCES/libreoffice-help-5.0.6.2.tar.xz +8c74dd667c660cc643c4d715dd50491ba92146d5 SOURCES/libreoffice-impress-symbolic.svg +c77acd04a7647b09745f9424ab0f65d52dfcd397 SOURCES/libreoffice-main-symbolic.svg +3857a55644148eb25ed1a594bd00d1262761fb39 SOURCES/libreoffice-math-symbolic.svg +9e945fc4f220d4198f67a8bb88619dcf23c3d201 SOURCES/libreoffice-translations-5.0.6.2.tar.xz +d4f0674ad46a832120db956cc01a27fdc2060458 SOURCES/libreoffice-writer-symbolic.svg diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/0001-Fix-export-of-tdf-93675-to-.docx-as-much-as-is-possi.patch b/SOURCES/0001-Fix-export-of-tdf-93675-to-.docx-as-much-as-is-possi.patch new file mode 100644 index 0000000..4e29046 --- /dev/null +++ b/SOURCES/0001-Fix-export-of-tdf-93675-to-.docx-as-much-as-is-possi.patch @@ -0,0 +1,1328 @@ +From b8e0c4739524504385955180df09f67887b3cb10 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 3 Sep 2015 15:07:49 +0100 +Subject: [PATCH] Fix export of tdf#93675 to .docx as much as is possible + +convert Axis constants to an enum and hilight suspicious absence + +that compiler warnings then shows (which I saw manually in the first place) +of AXIS_SECONDARY_X + +Change-Id: I873623141020633ea73f14f5c93322c2346b8efb +(cherry picked from commit 90ea1221856340860c406357e274000771b5b127) + +Related: tdf#93676 'new' ms-alike numbering has same problem as old numbering + +when it comes to nodes which were numbered, but have their number deleted, +where the indent from the numbering is still in effect in writer, but not +in msoffice. + +(cherry picked from commit 54f9576aa43e3d6d687469aa0b2ea56ce0bbaca3) + +Change-Id: I700f34171d8c9e9f6fb725d115ff1fe704ceb4bb + +Related: tdf#93676 unwanted duplicate axis title exported + +translateFromChart2AxisIndexToOox toggles between just two +states, so convert consumers/suppliers of that to bool + +Then in exportAxesId toggle between primary/seconday pairs based on that, vs +always exporting AXIS_PRIMARY_X + primary/secondary y + +Change-Id: I2649f5fc07323a73a3a215fdc52d5f1a5c31c349 +(cherry picked from commit 24560df316de86cea93a37edd38e02a2f2d9c0c2) + +use correct axis type in secondary x axis export + +Change-Id: Ic21d88b55b22c650de4fd69479b51d0f640fec6f +(cherry picked from commit befef6a79feae0490bd3a1cf72b1134e5ff86111) + +that change looked wrong + +Change-Id: Id40a6802536120501133968d003267f21aaf5c27 +(cherry picked from commit cfb717133c7276a7b154379d049e6fac0e5a49da) + +related tdf#93676: make the bold property explicit for run export + +Change-Id: I5f7f993f2cf0604ec62cea3460b651c07a7b4383 +(cherry picked from commit a052479f3c85bdedddfa38cb03b0858003c965c3) + +foo + +Change-Id: I6e175b3f3b031535488660d45dbb62b998d47e66 + +related tdf#93676, we want to export all significant digits + +The code comment mentions correctly that we want to show all significant +digits but a value of -1 means that the last digit before the decimal +point is rounded away. + +Change-Id: Id91a6076e37629502281c5dda426018f93d1e465 +(cherry picked from commit 442eb1ab9d8c1ad970993ef6c8a49e89601b7432) + +related tdf#93676, also fix chart::CommonFunctors::DoubleToOUString + +Change-Id: I8d63d942c7cb7876b864a9720e9a8adbc7345172 +(cherry picked from commit bb5d638065590cba700ff46f5a0a1ffbe03b6f1a) + +Related: tdf#93676 in msword chart appears with axis positioned between ticks + +(cherry picked from commit 694419d813c14f6135aa4463d77f72c3a24a5cc5) + +Change-Id: Ibd16d255a45a220faf7681a74785549c32969f78 +--- + chart2/qa/extras/chart2export.cxx | 9 ++ + chart2/qa/extras/data/odt/axis-position.odt | Bin 0 -> 21224 bytes + chart2/source/inc/CommonFunctors.hxx | 8 +- + include/oox/export/chartexport.hxx | 29 +++-- + oox/source/export/chartexport.cxx | 136 +++++++++++++-------- + oox/source/export/drawingml.cxx | 2 +- + .../ooxmlexport/data/no-numlevel-but-indented.odt | Bin 0 -> 19535 bytes + sw/qa/extras/ooxmlexport/ooxmlexport7.cxx | 9 ++ + sw/source/filter/ww8/wrtw8nds.cxx | 18 +-- + 9 files changed, 140 insertions(+), 71 deletions(-) + create mode 100644 chart2/qa/extras/data/odt/axis-position.odt + create mode 100644 sw/qa/extras/ooxmlexport/data/no-numlevel-but-indented.odt + +diff --git a/chart2/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx +index 5b40560..c30ee91 100644 +--- a/chart2/qa/extras/chart2export.cxx ++++ b/chart2/qa/extras/chart2export.cxx +@@ -98,6 +98,7 @@ public: + void testPlotVisOnlyXLSX(); + void testBarChartVaryColorsXLSX(); + void testMultipleAxisXLSX(); ++ void testAxisCrossBetweenXSLX(); + + CPPUNIT_TEST_SUITE(Chart2ExportTest); + CPPUNIT_TEST(testErrorBarXLSX); +@@ -160,6 +161,7 @@ public: + CPPUNIT_TEST(testPlotVisOnlyXLSX); + CPPUNIT_TEST(testBarChartVaryColorsXLSX); + CPPUNIT_TEST(testMultipleAxisXLSX); ++ CPPUNIT_TEST(testAxisCrossBetweenXSLX); + CPPUNIT_TEST_SUITE_END(); + + protected: +@@ -1462,6 +1464,13 @@ void Chart2ExportTest::testMultipleAxisXLSX() + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx/c:axPos[@val='r']", 1); + } + ++void Chart2ExportTest::testAxisCrossBetweenXSLX() ++{ ++ load("/chart2/qa/extras/data/odt/", "axis-position.odt"); ++ xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); ++ assertXPath(pXmlDoc, "(//c:crossBetween)[1]", "val", "midCat"); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +diff --git a/chart2/qa/extras/data/odt/axis-position.odt b/chart2/qa/extras/data/odt/axis-position.odt +new file mode 100644 +index 0000000000000000000000000000000000000000..35ea152aa0d9cd16783e5b021b05a68da0cbdf96 +GIT binary patch +literal 21224 +zcmb5W1C%Apwl=!Twr$(CjjpOL+qTtZciFaWqs!{DZQFXi_j&j2^Zs$q8RO3}GBYA` +zB4TDnu9#oUxfEqUKv4kzNC4nnl0rgvh#8gw008{8|G5OPv9K|5_OLfGu(!9iFfwqq +zu(M@wwKb-oep400=-)Rz(b6 +z)R#!gTUf+IOwC(G#_YSYosO5Ip@^EZf{u-ijhB}fkXQ(~R2YnGB!XfTvT_W%YAmK& +z9G+$Zok|dqP7;G|9GQL!xj`z8aXPbEETdTli)9wKZ5F$AE|*O%pF_TwL!^*%p}2dA +zq(_O2SDCVJsZF4sUxKS@V3kf#u0~L$W=O40c%4yHqvg*Av)C4k*k-GQR>!1fhm;QI +zv`){gF0brfpWNPD5$;$q(NtB{P-~Ak3x_5(sbWjZW*gHj5xg;B@&RT3Sz+Q8MW!QR +ztS@2scWJCM4c2RUl20|tFCE4&Q|d1h?k^{%Xj-ea;bo&eJ~3a6Ha(eJ-$kE^>V>^DT|qe~qf#%}T#7 +z3VyDLe6GrTuB#o**`3cj-mTbv&D(x%8a{72e{Gw5?O1;9I(_bY1qB5~Mn)!tBqt^& +zW@Kdi$Y?7~&MmEtC@3hXsHkYGXl!U`=;-JOD*P2%Iuubl7*#P6Up1UmKapBHoYpvz +z)$%*5^><qt%SKzZL{)xdIn|7_jhO7rM?$H+qa#75WjcK7e?>70!I +zx|XjD|Lxqwui~hWip2N&tjnH;&$gnW$+m;#)cehl=gs7c&HT^7rmwZ4&zaVzotV#q +zz|X_Tuj8ouorJrc%;$r+uaktY)69$A=9`_OyZy44qr9*4g0IWUkIROy>*lYUj)8%J +z@$vEAvE}KxjoI1RxwVb8wY7n{-I1mJiPgiYwd1+9-MP(^wXMCyowK$5i=(Nr%lXOk +z<%O@Q-p{#_&-J<8ozb(S<-60Nx5Krs+y2k{@z2Mly}iA|qvPZK?TfSh^Yin))0^YV +zyNlb$kF&$a+x>^T)32M0ujjq5*Yo@P``d@-$LH72`oV2 +zef1&}#u?|kra#QM5fQ>#KkH$k+{mu~sF72ri?Y6lfHgG|`g!88hC1Z3mAOTcj##ba +zYC~&sqJEZG1B*dcto6o5F`O=E9=mA=PU!`h#~R6SHdhwjQMOsDL)#sDndRxKU2w(TcFn|#N3jpc;Pp7mD-SvjK8-z?)u;JUNAOf!yMl_Yb1$f4h%+Z^DG*pnX(9E~Wp#HJJ6K$(wB +zOAU}w|KWw#yAkg{V|L{LFtd5$^#8~Zzl6g>%$U~enQngCj0H>!e!kk^k-=aMmX*VS +z>KnjaO!H{n`6=?ZU%W)^4rtlgVge{CZZDn`UJ!EZJ8l;hRz~tBnDlAh%G1^?8dTRC +z>*3WY>11e=ls_IHiyP7g?-#eO(nhSn#z%3qN>Z+q7J04XsR*(>uN$HKzxAOU_IDPM +z=6(pReV+@4*D8tgD9uN8Jzsy-oZ6%t===1ZbQOHM;!U8xtioEc*w@|4j%Si138245 +zI%!p81?1P``d_?@EXa^}=#8da^BJ5~uFHtqsG5`#iYJTy!XdanvTExJiJeGI3Y(xRI<9QXe$r5R$vLgc@$LXD~J> +zYk`7>1s3-`CA!dsP_mB+8B|EJoq|PH>LtoM9ev7iIKq%yQ9E-l2s{XL#VO1!C70O9c#JnG51uW4J34?&J%-|x6vyVXUt+Yc8QIME_cyO6n|Iih5WKBxV(F~tyc +zlt3g!76h%P9Hd7!&RjmY~`vr0kWq6rO9#=53Dh9x@+j`;$a8!aw{qz@Y`9qfe?hVECM}@^VG1f< +z?N0r+qj#EKRY3e(X+|TRkZ)Q3O@X85E|PCwk_9bVCxxyUM0fDorE}cD*!$6bz{>KH>K5%|ZJyHxo&}!D6@AU=g6RTdO2-gjd1yGJ? +zqWYaD<{Jb*NQxutiO1^6NOQ~Jn+N1Dl%Ug@?CkJK#Fwzv&X?6+OCx(8#})NnZma=a +zCv89Ut^z*J=;zmPPJKqOfl3<+YUR%mn@0v$)3CCPf1A4DgjeKr`4`DFU8CV6>^t66L_q^T@0qIls-AIht +zp~DkiK*y6#;&L|ZkZ$kVrNjXP-qqE(PS~q+a5=kn0G-zq2Ud2xkHc#XG@Yi5iXOfL +zK<4ilYpXa{Uo~_qX#6O>%`M*{1ZPZC6X^0laJQ&Hdu1~2WO^-u8na@FGbz;tflV*6 +zc%b9_Ctt{N4OIcGbhATZobvSm|B45^H)sH2lbnfa(1bl>i6_XhfA)|t;F*E|a})zX +zp=vB26%D}orNNzB*1-tisUPTzWg=nLfdt6SFCzKRlAB5i<^fz|_Hls0r2L1fC;+qK +zY(FQ`0NB;3Zq-C|ZzSp!l(xn0Sp1OUYPPa&A7PI$mVEo(vgUwgs>iH*ejYq{3Hy$Ay` +zr@{5tX-L^FD!_9~D99GVx~l>6vH}1=VvP^K@oWwa5V^nVWGJEk-g-PuCG;5;P=KH# +zX)XYO;;Rjt%t8{dc8W@k3H;fL8J^k~+t@9wsKNqt&x#J38%*lBYcTzuPAWKqrusc9 +zf4(^znGpHp3*etadOI}G!40Dr;H^%T4S#GgKVGu9{;0SO4^TscI|7bd$8hrKp7>;Oy2&CKk-FSL#e_dv`8?mNbQ4PgNSpChHRKB`hL`+w*JJmOUpggA}P+AlLCFYJ`Q{KkxUOlt1Zhz%PvNz$24={zn`m5qCsD +z3fD1!c`V+ +z;M@6;`g>DEchp%4764->djG;V2Pf{{t4yt8`Dmh~Mnr!xK2(@$Si(z^s_h-HPW-)h +zuPoJZouz8K&W${VvEENf{k +z9u(by`u%VY8NpOSq}!L_Wh0i$fHl>M*Ki84shstr5)4p^Ju|$qpD;WNAkX)3CWKuC +z;?TYCT-qQoXIsc20_ynU*8=YJ*{6tl6AA1KkCHF;WZ55H`1M1#62W&88bF$_<8+qe +ze0E@W>U{Qa*0y$G6szsl9q^KN_DNB*SNg+yD^lI5nAhs4By;ceCw{?7cghgo$*Yv+ +z(rrA3@)w82YdzW_hl(XdX6Y7N0?c;2AJ8mOL!&>#my72QC>@1kvaB?o +z(D(2Rf!ngRRJd;MHNFJKGd)+sES}5k8I1K7ofaY=3|=8Lf~)>_% +zD*Ni&0)fA7!oQe+COiUC6t&D&YkJAzQ^KLPqj5zb0Ri_^nys&k&agXH7bVFIj6t6u +z^9rx5I(8^GHy&-JfcTt9q+vauN%4@{wGge7MDgC*nIR|tY!hY!O#j@MTKmBjZGh4} +zO8ho^k?Rj&eq(%?9c<(<%(wh~CO(v>WEt*Dj^BN!>GA#x9OdPp<^|i +z0{s!{Z-xp(b}JBmc3b{iEKbl+tX +z_%$mP1{|to{=8SB!qf!m?*Y>LM?vaE`|Iu +z*7tAxWluTb0nP|&UL?>6ASzG=yuVQld0{8y_%+Icr?(DO-Qvs|?X?Ez!8*>?ae;hT=P(q2md +zX6_vdDK4{D;)9FcI}ni{IYepV4!6^xGooxv0#$OrAoyBZ>zR4S7=Cqo2S8W|*(pex +zS0xw1u&rRf2t>H2YGDAiS=>+j697stm00Uf5N5!;APM?SX%KA^mm;FIS^*IVb{Ga3 +zO2Rljg0XbXSo;-oXN@rlEN0lq;JXqkDm_&Y2`_>k`XSc>Ga%}XZOC4>NTvtF?Dd74 +zX#7d~$k|8{hs{&mx>97%liI2rYl4EMJFgWWO1(G6iyGR_!|tr1RV^i+&R0s&k89PRW~tLRd+A%jSNc*S=Cx3kyDqr1{!$! +z3>~0fiH&{@H^JPc-KlusE*i9n5+hO`tS}PMh7cZfZ=$RMmccpKOQaUm4fD9M6>nD+ei_q&O!p&xR4K$>#4JMBZuw)#&lmKI|(%Q +zgD^h;^#mJStgllv=R6iMX(%!x_s1^)m}Ff<3K-ITE{wH7B9@z*77(8;~185ko`a%!GRw1UVeKMm(Rr$pava +zPhe$quO}VPFB}V~43mZU?{LL`gEIav?)7f0ePR&5xlIbAohSbVW=e_4i&hKk2mA{m +zg@lCs8*csU&i`yMe+ou+w$6WHsqQw`Ro`Wt_E{0T?`X7(BQnGt`h^XdS3qFERH0PJ +z@**mTN1J<-gGi^1{63mV*NhZ~!bKjL!#jF>OZ6;u{MOlA>UV~q$(Agdxn)r3%M68+ +z&+co6^=3?7Zw@o8R8a$NGpSbDwYf!;oUb{6EG+IubV{n?+KAPbwc|t9)@QUW=)KCk +zqox9@B6>l*iXT2z*eDC+ku+71BtGAts^GQoW40o>>e^U6C}RZ4k;r_to{ +zxE^&C!S8NaYEvh;dl#-9tGbnmR1U5#F2Nvf_Nnlk8|mD+n1h{%o2i2<)B}9YJ2A8m +z(?-Meqs<<>rVi#|B-8bl90$7*%ZV&`d1y?LRwVu7Xgvhwsdc#H$n +z8y9)#vJLae!}7vn(Z3^qV$B$N6wPm!V}!wBuk#7;yx|XDA$h(Lds_wVnSz!u^i!3c +zAUZ5$LSt_;!$SVz=#~xbfBI3&0(`_-4^eBtI!>aVtF;BWq1-IOECvDOVGua7z+a +z^7f8kl#gL8Jyk>CNUS@3*u5Hvo7)0UB?<)w|l#? +zgLYhF>GgdB3&6_gGKra+LJFB}#i*1DFt1j&W!)jwKlNa0vWV=a!=(tB3|!!5oxc=T_%Fn%i4$G%u(G^hAMoN^?ra+BpcdxJ-ta +zs1~IW{QxfX5lnPT0mY7b-&Y7r@-uJ$59o5Zwk~k=x)Fwxx}%nW7c`y@Z6D5YbChs2 +z43h(xOYeuh1B7gBR=<$QxSK2i&7&x2wfJl9F`5AbEUg`LZlJX|{3^|vQ$beG_#dZ}h|k5*HhUP09(Nta?9l0w9t~#%W4xu1w0`#Tq-%b3RXjK>!{Ok4h4w +zn?)tZ8iomR6#|h)4YPk+e_*~JjSI~9T;HwrbnaB3MUN8iIK;)v5|uqhjUYjqIU0oj +z6e6kz8;&0n3;9NjL9Kh8X)JHPCOiPWIDc#2hmRXdz%Pg{P>xhNoVTz}OpMtDkug`fgU~%wSGI#8`5nz)L40Dcex0!ciDs=iN +z^Qky;C3oQ;YkQk`CR%L?3w70E@y_)DTn$i#*r432%Jpwl<|+5y*nKi6}yBP%I?P=H}N0Q8z3q$zH)Fc}jv* +z2J|8oWG>}9xJAe_u)qmNFbeHTbcLB^^iMu7Hu)BkSNMtq;~t%IEYO?nc#eYxZrVGk +zxk0~VyM2skwAgs-{j5j`0uj7L7LEywBUw6!0z&#ABhrlIsn!I*{RX&F{Op`oXY_BQ +ze4$O2{drzt%`0CQS}l+*tKYA#Fx(oVE4(7-;l*MLoNu)^coy>N^XxrHmDzRGvWmVtgr>mQlnYDVXn-mT&AB8a!g +z3fZ!#DP87=s>0Uw>_+013iEy^w_}O9-zo}Q-wwJ$RHq3SR`}WH%o{l;zuPUQ@|%4>%(OyeBOa{3eM&;fZAU>Gy%ToJagjW$#Yf|*c-$&A9ZCky?}`DGt{f2spVBu)=H~$JU_l<+Sf%P +zLnjf!1{V4-iAXUxYj24JiV>BWyX9<(Yq?=?hQU?K;)ZZD$nOC^qJf_6cENy!K-K +z@EJ|;Nzs^AZAFEl6aZ*ckB{;)zxnZX?@ON~us4Dm6iPiBqlxqm_`yu9^4J}K&T$$S +zJM>zIKHauy&VMtP?YTOgcv$;zmC9JM@U~T@j;0KzzpT&7@77(LIU{>e9hqu^qj4>g +zLc2>d%hVLQvZRjre3%#eUQ;UnWH#GLBA}&T$#gm#rAyhroCPT(9BVcV1TY_A0bSrimSC>v!kdc9<*|Kb{ +z;D;=F@6lUcN=gSWs%)SXfY-GzW3}2TA6)cP09H-|6;4ccU=z+t@{g{Yhwa6e5W|>8 +zC(h!Np6!UxbS~ofBYUHGIE!($E%0j0XS(!eTn}v9_i0b)%+-F8Xi`aBCRYXYD6|_g +z-Ufa=wyBqY87#52G}(K;0aL_Tg@`Oa$`?SoBA?0ae1~mhOVP_K{2Eo?^npfwDRv9-CT$j?_fW*Sl(x>v&HYer|n&)>Lw+vS< +zCPN()esrOSjFflg*GNmxG#hy%r_8TE4G0a2ayl@SxI-Dw0Zy*8+UJ|qr8i9N2eI~e +zuIC-?7;I2=!8i98A`>&VIwd#S-@=BlKwc7u%0`eZGkGxJ=J|Oci1E6p3kPmkJ1<06 +zOIW9K$aYR8r**MrXLJyL&**SWnZBPgPU~S!aLjZ<9Hq|!uOe5++)vVoyk1^*L!6|~ +z3jclKqC%J(TfuB&ElaLsO1?YF +zNQxeM^}E_9JssLe$u!M5h;~dg_e%i>xhRSFpod06dPCU@4@*IsId4!Qx>xovQpxvN +zk{xi)r)= +zPW4(6BZIsXn5IViDvYK>K{srqkF-qZpO`GqP;7DhDF+o69Pba5K8!-*h2q!C8uVp% +zAieYycKL(FWPoKj-XCu$&$s(%KKd*$WU~B!{@9OF<8b1fxe{fEwYFb&0Ma;L|E9Oq +zu7@N$DWGd}?AoYx5u*PwSomVJE3yrTPhBo@%Lpzb9AQ#akY0s5pPpV5SoPg@%ap;j +zOU1k_$NB5}>4M;|Ss}z1Vf`l5pOp;W|28Z9J37e3+2F4^VRYiOZ6+h)(3KCgs2A9p +zpnjdYqxr(OSv5=Q2Xv1MjYYcUkyJ9DOnw=?%0s>SjumM%3R7Q}EslY(-N&-BE|OGv +z%ccjZFdqceCE;?*Ge56qOzZcxTe-X^uhAdSlW*XOaM-mIPDSMfPL^j+;!2a;D@udd +z$E61RspVEIYx8!sJ^uI>!rZ@4-s|Dt +z01-eXZ;=`5P(R8pm24)Ha~C0O?^(rKz#)}dC=~-GRRCPIJo2@6Ealh?(VwQKO6bWF +zo~(yI!Z+GYud7=$UGdDIEAl-a#uIA#{4ULPvFW&Se-pLE`nyQ4OU?PBo1WLE!9e+U +zp{_Te^=hSh(KVD?GE;REb+1-g*wwJ{=J#!L+dggb#I+CmSoHQ}hmxCgk#TD@O2#?% +ztNp3oqZ4QTUZjnn%Yco6)5qSC4xX~tlHse2dnUO~l>0h1&rCQmi)IDJA7SCBj8iB; +z4lza;^i@WiXjxV+tAa(XnOb!7BH)mPmFkny*t$dJl^!M|lSt+FI +zTSC=(5)HV}@o?+0>q%;TZI%BuLqa*Jqzh4ECm%o(OC+vMUma*Sw|Nt~ZFE*clR51H +zISDyH3uF<)hAGl=Oya41YU=yKJ(6fmJg3b;CL_opxBLrr|FQ1yt|Mbg<8xBezO579 +z&}i1QpiZ-DvvRXrsL4E2S67#Pec_^tXpBp*b5Ygz$?1F8^Zp2bEW;2N4-XfY-ToJZ +z#2|4_@FA_a&0ej~$D-;E;TPv2I5JK~!LC(DZCl@1amhS1r5`OWOFvq^Y;TkmC`?YQtKY<@4d+t2#+8-`wtn@^LREN{*(&WTsj +zp#@Cha;D=US$e@M_f#TieP(m4q&@@w*ZKncq8)e=$_9Qj;hxoZhyGb3dJ=V!duH`F +zmEeVhqd46)=99a)S;nnW$zuE5qxxOs-X +zS))9mCcldmh>+qM3PM6w#0OL#hu*O#@0U!iF?tN=rY~^I=o-7?7mPH+5Y4+B=LICB +zR4l4_DzILWsZ5`743fj5pZjMNYk27N7|<+j<1;Q?C&XkZ!8LB?GT}o-b_ky3LR%|e +zmFn1czn5;16!Xf(K7E1o@;CJQSmu2Jr^~9V|x38aElUl*=}=h;W&(IG&5aB +zbEYMeGW;LVQeH|t?XA~9FsK2Yy(Oe<8T60_dFp<>m#N`AvVnNN)&dv`H-^f#xl1Cxt{;%~&oNNU4t2B{F4N}Nh%BZc>#Nb{+ga80h(3(S)m0WfSyuv2c3Z{s21I>P*L`Xw-{`v +zBZ-L6wnVmM-_jxPm*wobBALSuA*L2|fN0!w+|ervA#)*4e?}`?ml_imFyS%yd9AS> +z#fJn5W`9!Fc#mnVhHntTMS2!GqJF3IAnO6GNwArf(^bX1Ycu?O%tuJ%o%q`X_Y}&VxLi?dd +zoP!*LXht6+A<-1m%T@L5u)L`B>ZNU2(G|>+U@hlSE^0aosJn~$SW^sL!g2APt_+rxgDi3y8QMKuNc{EJ9A +zUD)cSfFC0@BCA*^1y7QD>dweg3EM)Lu_1u=HgH*%s=TWT(2#>Nq2k^OYXy^@tm87b +zy<)-~G@F$cas0BOD@(>bb>`O5m*|O&yr2FabPa;4T<(`}U};!!ArJ1DB_^N4&g!BE +z-}*R{7inapEFB{0f9(g8p~Io#gmHvNpSId*YlQW!;uz*#&d_AxWKRDGh=5W`=#w@m +zk5rn3{|<@XkyU(sQq-i4n+XT#72i&Oig|}*##MCW&G^M(?1x#FElo(dn<3*ybKGl# +zci@wGx9RHj%g|z+?>2e25wlUg(GxS@uZcF?KyahDWp?ouizL)syaOM|biMFwP|beh +zMv2TePoCO&@R59`I85mq;1id@%5mim0o&1>+|tlldC4!W-g3O~nf>l7+H(Y{-}tDF +z4+)E#me~+uE!4Aowt+L_Q=iRr`~~_912tBdi>h)02=>Eo(HK41R*4_gwGRw`%{vP&ba#;o$$*9mY +z{i|~`wZigB5uy5A+@Gt*5XOOV(O?-0F`DL*hSEoYb;* +zjtisMQ{a<*f|Yl!!Frspo5!NSFf^x^l(O(E4Ks=cTi#B}tCyU{SFPC(hnPIt8qG07 +zk}WSVaGyRF6-$fF|_55@RpaF!Ws5iYo>l-FkOD-DZqx#?LaEFnr8E~iF5x33nu}3w4KN+rQ+*sJVqV=IyoOJj>=@&zX5cDEmwGU|wYL`hg(Xnq~ixvfpnU +ziWKbeK5rb5Uy>fVoIDf~vAi&#gL1YOyQN4W$C_f*mGc=bi@+_nTEa^=AD?2V9Zx@} +z`OKW9iQu-_n~C5yS;&C(i-y|nwzJ+`J2!Mi*wIwq9O?E$)%5nEHi- +zNvIE|co`VJWO=1zrHo>vaz%ZXcq$v&v~rfzAQ-8E7Uh;czY@87-Z^fJZLw3@s_41h +zdp4u|zDJf~i7e7G@ZijIX)?9$I1OvueB*&??x37K-!QH2S6FkUWl5{Bp_%$_a%q3q +zYY7mcKv@)N)uKitOZ{=2NxLMLp12`|#({-*Zg#v>hH<}|G&%>h<(jG{1u~u~FLbas +z4<-c*AqcIqWxPNVv(dsrj~q>|FEN|*e1Pce40h}YA2WS?Rt`SiO9KJfcd$^})@!La +zUJgd(`b)Ou1h_gZ(ZM?Lw0&diHFmupId9aFc&x*wqN7%5WH=48&Mum#*FnDnZMr6Q +zT!_7vi9@dxOutS!-De{hOnBb>qTq>T-Z*cFo;M-YI^N^V#JjZI-p)L1+%jg#s5c73 +zD{I1}0yuNvsk9Q&bqR5WFYY5*$H6s4M~C9cSftY)%1{uleqJGEU+?ubsJF5kh+Lm* +z`J%d0zJxuK#>j=-DA8RZg>ozcp-s;kE8^JfZ(0?I929w`GWb<%KBjr@mQR}Ki`Bi} +zIf^aL#8=z6?~hjdDO!29T1_Z^s8yKLg@YGMn48JakjuaeHBD-4%an5mXVyqJx8|g8 +z7#VGC@=oQKTe9Uop8r|?h^>5XFREmrkHD#`L3nKF*omH|{LZANv`~m1Fhf%F +zeKNnOFHQb8OkKjKftT*ny3}bJ5S*SQb;Q1+t4#`-^t;D|2UWkCN+je^GO@*S1Jtps +z(Vpie5zbO$_)|diwYoy}@6%r?8d5oI2bJd1k2Vyp1)(l!he~ZM%>!f3n)TX^V~*JR +zg*t*B$W&5j5?E(#OBQsKZAdhXQpZ4bLGl6OK}5yXshVV_XQ4HQI|%}+w1;BKA1_mu +zqi*Q>vs&5ezv5G7q0;xawwAy-gZAw&I +zanyD$Q=uVLiQ|I74>G#_WQjI)iE=(a-$?hA95vC#ndQLEZV@u6etr&&w?J+QItjn8 +z)IK|#da}s9W4X}Ber*AN>rRt=5-1J;QleH15U#E+a4&-Aojs-X7LxFdsi#oGGK)U_ +zZlcm7U2y7ZilvzTV>smZo=|myP;eQWLS%c5<)Un=x1)dym49vA1CJ!WF3k%C*-MEP +z=@)CvzFC#pq0JK1mj=|=3-*q{9#l_wy|p@H`xYU3+Hy#USD*i~T|qyTsCJ`fPa}klO;7lAAx#NNLsNY7ysHXC8dH39y?kV059vk$)zY5R{ +zBg0T^y9!VFanr_H=1PH9mQJbncvICf5gv9=*zc3GqV-cEtz#9fj@j8|a*3bcpTciS=onYZxl^DKKH{QrjxSa44cD#a}+8Yvo%+RpVE(x4F +zF!4{5vILls-q;BIx#|#b-Mzt!Urc2 +zKrgex3fQBc0&m^@*3Yo0oxJ{YY|VnVsCnXJC?sDfcNfE~iJ^EV^i2P?$>p$B4`R7e +z9hrF14RdwpU&^ohlItNBwvSe=mfB`c;WCeggSS4R)o)Jtx{pryn*ROSoQ-f{mNX)X +zJnmZmyE)|E56F3*0UBc5sxU!mTG5kgkNoKU@MaMkl+1Sa=>j26l4rz->#{**R)7zj +zVBvuEa8ce#fK3-!6a>+AKY$_brco69ic_wFxVCfSvF!7x1 +zGzF0b;Grpli6EN0i8zT8-b{ep_z`P46mW18gYs$$Xx>a_#113sgP2)>N8WHc3bWgG +z$_Q+7Q^E*Y&G6_XQMwRCoqTE34k12Zp1%=J@W+t(V`f+|TMnR^#m(1D4}`ndWz!Hs +zwQ&kk%y5!&kBbda87w5p<7jm^+ES?>0S749u|L2`7jekF4p(2PEM%|{BrmFAH%+h< +zI&SufHiBERVvW(=iz_^gMgHQ8Q-7idb!LH+ESwmcp@-x&#{i{tF>SW6>Z{C)f*|b_ +z2!t{&1qyezcH$x2ApEWO*_?>-W9> +zge~M=AB5dZZr_pR@F4xB&I?Xg=q)fX!+Gg25>XI-m>bRj1mYM4Eu_zdd!Gc%LbYq> +zb_^t8r(7T;;S7Bua^qVV2R8w<_7Cj$dvOs=B=O@=_a|ms*QN{dl#Z>z6OLdGOT@f} +zrn@T^lWVQ#^?fwrhkZBU-uzmkC`gif!A=}3f-|}6w`)Q76mU51X=kc+5S_yJYc;no +zn +zX08|XH~Bs}VDqrS$k6nnx3|v|!=j@aN}+k-E{PCdnL6wKw@;7i+e6ZZn=U>t`jq>l4>wngKv()5%t`Q=3J$+Z#RkcKbZ*EZK +zSS0rAb|DtZfE7?{#KNRy2hzhSOnsUaVy_7#A{5`+?N4))z;4f5j6!poq_iNFaRz>4 +zik#I)b8O!(n<|%}#d2D+JVLYR+~B;Ic$R_<9s3%)BfmggO7n({C|WW2{jEDj1OLH;%fGs2K&*8WM&_{X5A>;z@PL^+y4a1UY +ztlS2`tIEy6!|<0ii&iY(JCF26R*`uU3{GKvJ4+~ky6tt$32<~sWGI+JXfwwmwk4r8 +zNBhBgz431NMSIDNI*;F2Art4%@OE-D5>Tnl;iF=LBc(9DTq-}ok((clDz-6fFVjL! +zPS8*)%>Bf-*bES}>H1khP)L2z2*!im&ub_W;~OP#0p3Z(K4i^4goI>b5S6ZBH?V2# +zY#-Ct&%aA$5yD3nZADb!h*}gK&%jDm2VdwD$VOLH>+@MFVAM3t;nmTZv#>Hypa6Ks +z-3Zl0BQqtHDqtB&?~&z1YvKwhR!vt>uA)MSdqLaR%Kcy$4cT6C&94yZkb{fy5~;9V@lGt5vNUzC&@A?VqjL&K1HYf`Uu4Y)I2u?T3X}O$6l)eTfx;pDqBY{?|n=nFUsF&&ig-hl! +zitO@ixMl@HupfH*v~MuDDd%$VZ28{afvekcLlo1A=4oE(0kLC`NHH9y2-zC-BbGHD +zv6vKhEHRX|ND3KL3YK}G$C2fI09x;jWsu@8({BdM6Z8H-gB|{u|391lFErT3z}CXl +z#L1c7(b#k{VbV5`5i#hBH`ruqS&#t?%#m`e%`&H#EkqrR;Wiz4vpXh1O{uW_G-rOV +zTAXDorZMBf0Cyy^zO+w;)rg90OwzpRgoe9=zO87Ddv&>)h9Dj9#xk%dhq~R(mYPd1 +zIhc+E)_S@jpVB@3j#r_RxNm{eK@xVTF$NL}KU&!0Vc#2@YibwD^t+PtS#GSy6Cq#Z +z26tI*J+wiya#v_GVcZYFXeimSAm>2bc6pgWmgGAnuD-mB-C_N%xxjp0{cD<->E+EZ +z*y01-?XKEO?Z7SXBy-P8BTtvP!J93TMEy+WONG-89*?i1Px|REtlgSMS5a%hsRFat +z*rUc<0#%8czs%S8WIhY_$9#c*@}K{+`Tk1L7O}H6wJ>vW{5vt*iJ8H`$jHRnhYoa{b9BcQG{hZ(Icbi!KWr12YpR24M?l8v}c%|Dy7L +z>!7`zy^H-{djAU_?*F3H-qFs?(ZtE=zc=@PGtFNn{qJ1=TRWYc4V+#6P22w#M~e2R +zopNF-LUdB{;tc=a`1-R-*Ob_2+s_Caa>Xl_bT)5npH2-OD%ByMz6=sHPbUiQ`DJzP+`X=qa6u?~QEU9|bAnm$fI3=kl>fWk3yc;$xf6}j5@H!A +zUHv2O5I?O3v^po23$3DN7+6`qNAFmfF;LmFh8}L#>oKtY5PHJ-`FAT24=;Y)sRb8i +z@~3!qG87TwqsCzA@l1GpY4R=(O)1OqU+^@(pob}$nfeN{Q3mQZ@j3v55`UWvAafj`{cG+;=trlCbI^fz-JeY(KJ2)3hDen$(T +zZk1VcZ#zZ$vZMVxHMG0Vb$xtAII*hneQQv~!4mIY`xX;g-re6?<%#`aQUh8IZf*k8k`4uU{d=Fcc)`2$)0 +z=TVCD=V|;4u2eR$w>B^``SX@JJ2CtZf_af;WsUnCZTPCX>#^ExX=+>wcj?B-s)JqX +z@x-OqHZxkJvbDJ^g`6%7(Hy$iBER?`uhHAyey-ethI${G=mAOWUS=Tx67>f_D3^D= +zR0tYb1*{3ViWpP{bS4=A$Z0xrW#ZxCoD^kR&MviK_Izc-BlC{u>ucF)dMZl`x_|?% +z1wuW3hol!f?U`~P6KAt;c@Apm6AGpe$DIko@ElW*cSIl~C+Dyx8LGl&PbN!2Q>L+& +za1zO(C^HVj1LJbwrYF8kpq}XU`#)p{}o#w~??* +zU7RZJ!G2SBYFQV}>WZ-}4J~aYNI7V_>OeY!+vApW9$)|G4abA^(=SDbVdI;_o2&sZ +z@=$?#v$N|^i6KUuKY!VfJ@?)g@sSsO=gP9EXfvpH3(v=7F818nn7KksL+=ZU-l?Uy +z3qt&=QyK6lDhVmcdLy5=2qI!sYv$L$m{=7i{+g*4R;5F4o5!B`6w;mt**@bbbjCwS +zm!147d$|1dQ;UHPVp3nElyiWfDw9V%4#~1LoKnfyvxa}74I{L7& +z?E_NK8lZO$BXtZ>lk2}(__ZVdp}MLZXeXo&Oi4iO1i!AK{kKXP+CMD5u4Mmc`Ff)M +zyRBSMeO7?4x`ltpJ}Inf|397HRv`cIm+@-m_o-+-Pz8+v@*Psps;yRsU7N@%)G7 +zy`bwK{htH`|0X#B=ijUuneh*gx5!xM5J%Ciup!mo_Bdeur`3KWf&Wh(ttX7PRj|Up&n|}N2wQE&QtU8oIgDhR+4?YyX+UV{Yo-}oh&iO +zcI#)0PcptH-cyQhMnm%na;&LQi_Bu@_5JfPTO0$rLVMoi)h0(5liOoS_mn<0C?!Rb +zb_D93lW)8)oqL_t(yA+%*xvK+zv{KfNDDW)K>P6v%JIcZ_FE-%dmWOg&T5i_|7h$b +zzEBVJ=pT6jBaX#les1~AKsu#b@8)r~K`f@P!T_UedD$>AMl1OxCLve0=;yvBy@;Fr +zh=7xQo>E9jvOY!QhJv3*G}65)Ta6lVjt^qFlM_4-0$`yyaar~rL6kZ9wm3{5C77onLZ$fgQF8owHz|IEUK~zLfh){9IDFJ0 +z35Qa%LXIUp#^+*~Q&m3?OYWYI*q?%Hz#c<$_j8Y)j>owZEs*NwG|sRsIw7AkGi*zb +z^CoIOxF?2GhjWFlJBK9~VaOX2(_|V`_D8NHN}hj^>8(1tID50r8%rPY>6Zlk`7-GM{kUW5_P$H2bo5A(K%x`iL?Cn=)oZ2GD=cR@% +zdRhtZpS=2}RwzdH`qUU?!bnnOT__ZL9_2~yx^Pz7YGQZ!WdFp??Ug}omxNBT1KPjV +z`eFWAd^fIgJcBgtNi91=En}9%?i`eOT&Q{GT}LuqXpJ_v-O1NRA-b;=d8X3Dx{NfyPC~NFGAb>WtW9SI$aj(Um0QO3z^<% +z2Y7izP8HubCt|pa5TE6OqIJyb9|t9-MI{kArF`Ew@Q91O6N=U~t8Wb+k>zKi%d1ed +zduTU7gzLZ^kUQ`G9q`3g{nRl9R3=VeE?*sfpXpW5Ky)N$eNyT1%;r$4j1q@{HX@X0SBTo +zTR#dXSdci%A3w8s7QLiMU{9#-S}&OBS$B)SKzkr +zh&2UX`Yd6LwMeBsV$G=lCY`puq&nX5m7b&>V2S(l_wc5ESHHx!PjO*adQ~Dm2P531 +zc+b4XD!i!o&QR|$kIcnIem3%VJn83{xbI?bN&85tmv4cWuiqb$)WndEk~_>2DT9`J +zFN!2Xyt{axq0GxT_LDd^(JM(w(5l2M87NcA)Ke1J8%vkoh_8NEb#kyS6gF=!gQ}~( +zHB0R?7e7R`Yw&^u+YMb9Pbo74wCTLZ^vISGJFvo$&{$u9w{@!8=k}!hLYWk!>gCJGRap +zd>(8{`r;md`67pkSK-K^=dRS#!cfUmAq^47O$QnMGTN1wXfq*=9U&HTEg7SGr9Uq% +zA!MXp=5@TyYtz{lK2$W%8H}QC_0VrQ@+zyN(Nnc0S0~N1iC{YEYnb3mpDaiY6v*V^ +zLW>c{ODwam@MdLaau!R6bM4f;I;PJ5=Z15~?!{;F_CCq4uNF*j(w?4LE!;760 +zml-Q1)j#YFz*rSOf-8b8VsbE`SOHjeZ?v%*uq+UX)os?+tJd$J21#sy=GoOv)Yk2% +zw(7FFIu!lP2mHzqia=noC{jbQUMN}#3VsCy#dctI3i09fI?-ytuh`*lq3QvE`K(a3 +z^(xW&50DK(aYkcp-QaqqDBK3?L!ijiUR{2ztrl7DAPNgX2oA**Ld0S7DT^X6kSRjJ +zHWD$|Z0@4SXYJfQfhyd;SMdNPTR(E}LaS51O9w?I{*Lx + +literal 0 +HcmV?d00001 + +diff --git a/chart2/source/inc/CommonFunctors.hxx b/chart2/source/inc/CommonFunctors.hxx +index c7bcff1..390f13f 100644 +--- a/chart2/source/inc/CommonFunctors.hxx ++++ b/chart2/source/inc/CommonFunctors.hxx +@@ -85,9 +85,9 @@ struct OOO_DLLPUBLIC_CHARTTOOLS AnyToString : public ::std::unary_function< ::co + return ::rtl::math::doubleToUString( + * pDouble, + rtl_math_StringFormat_Automatic, +- -1, // use maximum decimal places available ++ rtl_math_DecimalPlaces_Max, // use maximum decimal places available + sal_Char( '.' ), // decimal separator +- false // do not erase trailing zeros ++ true // remove trailing zeros + ); + } + else if( eClass == ::com::sun::star::uno::TypeClass_STRING ) +@@ -128,9 +128,9 @@ struct OOO_DLLPUBLIC_CHARTTOOLS DoubleToOUString : public ::std::unary_function< + return ::rtl::math::doubleToUString( + fNumber, + rtl_math_StringFormat_Automatic, +- -1, // use maximum number of decimal places ++ rtl_math_DecimalPlaces_Max, // use maximum decimal places available + static_cast< sal_Char >( '.' ), +- false // do not erase trailing zeros ++ true + ); + } + }; +diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx +index c043fd7..7a4f2f7 100644 +--- a/include/oox/export/chartexport.hxx ++++ b/include/oox/export/chartexport.hxx +@@ -64,18 +64,25 @@ namespace com { namespace sun { namespace star { + + namespace oox { namespace drawingml { + +-const sal_Int32 AXIS_PRIMARY_X = 1; +-const sal_Int32 AXIS_PRIMARY_Y = 2; +-const sal_Int32 AXIS_PRIMARY_Z = 3; +-const sal_Int32 AXIS_SECONDARY_X = 4; +-const sal_Int32 AXIS_SECONDARY_Y = 5; ++enum AxesType ++{ ++ AXIS_PRIMARY_X = 1, ++ AXIS_PRIMARY_Y = 2, ++ AXIS_PRIMARY_Z = 3, ++ AXIS_SECONDARY_X = 4, ++ AXIS_SECONDARY_Y = 5 ++}; + + struct AxisIdPair{ +- sal_Int32 nAxisType; ++ AxesType nAxisType; + sal_Int32 nAxisId; + sal_Int32 nCrossAx; + +- AxisIdPair( sal_Int32 nType, sal_Int32 nId, sal_Int32 nAx ): nAxisType( nType ),nAxisId( nId ),nCrossAx( nAx ) {} ++ AxisIdPair(AxesType nType, sal_Int32 nId, sal_Int32 nAx) ++ : nAxisType(nType) ++ , nAxisId(nId) ++ , nCrossAx(nAx) ++ {} + }; + + class OOX_DLLPUBLIC ChartExport : public DrawingML { +@@ -145,14 +152,14 @@ private: + void exportHiLowLines(); + void exportUpDownBars(css::uno::Reference< css::chart2::XChartType > xChartType ); + +- void exportAllSeries(css::uno::Reference xChartType, sal_Int32& nAttachedAxis); ++ void exportAllSeries(css::uno::Reference xChartType, bool& rPrimaryAxes); + void exportSeries(css::uno::Reference< css::chart2::XChartType > xChartType, +- css::uno::Sequence >& rSeriesSeq, sal_Int32& nAttachedAxis ); ++ css::uno::Sequence >& rSeriesSeq, bool& rPrimaryAxes); + void exportCandleStickSeries( + const css::uno::Sequence< + css::uno::Reference< + css::chart2::XDataSeries > > & aSeriesSeq, +- bool bJapaneseCandleSticks, sal_Int32& nAttachedAxis ); ++ bool bJapaneseCandleSticks, bool& rPrimaryAxes ); + void exportSeriesText( + const css::uno::Reference< css::chart2::data::XDataSequence >& xValueSeq ); + void exportSeriesCategory( +@@ -186,7 +193,7 @@ private: + sal_Int32 nAxisType, + const char* sAxisPos, + const AxisIdPair& rAxisIdPair ); +- void exportAxesId( sal_Int32 nAttachedAxis ); ++ void exportAxesId(bool bPrimaryAxes); + void exportView3D(); + bool isDeep3dChart(); + +diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx +index 2f0853b..d0fa7dc 100644 +--- a/oox/source/export/chartexport.cxx ++++ b/oox/source/export/chartexport.cxx +@@ -119,12 +119,12 @@ namespace oox { namespace drawingml { + + namespace { + +-sal_Int32 translateFromChart2AxisIndexToOox(sal_Int32 nIndex) ++bool isPrimaryAxes(sal_Int32 nIndex) + { + assert(nIndex == 0 || nIndex == 1); + if (nIndex == 1) +- return AXIS_SECONDARY_Y; +- return AXIS_PRIMARY_Y; ++ return false; ++ return true; + } + + } +@@ -1533,9 +1533,9 @@ void ChartExport::exportAreaChart( Reference< chart2::XChartType > xChartType ) + FSEND ); + + exportGrouping( ); +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportAllSeries( xChartType, nAttachedAxis ); +- exportAxesId( nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportAllSeries(xChartType, bPrimaryAxes); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); + } +@@ -1566,8 +1566,8 @@ void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType ) + XML_val, varyColors, + FSEND ); + +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportAllSeries( xChartType, nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportAllSeries(xChartType, bPrimaryAxes); + + Reference< XPropertySet > xTypeProp( xChartType, uno::UNO_QUERY ); + +@@ -1626,7 +1626,7 @@ void ChartExport::exportBarChart( Reference< chart2::XChartType > xChartType ) + } + } + +- exportAxesId( nAttachedAxis ); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); + } +@@ -1642,14 +1642,14 @@ void ChartExport::exportBubbleChart( Reference< chart2::XChartType > xChartType + XML_val, varyColors, + FSEND ); + +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportAllSeries( xChartType, nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportAllSeries(xChartType, bPrimaryAxes); + + pFS->singleElement(FSNS(XML_c, XML_bubble3D), + XML_val, "0", + FSEND); + +- exportAxesId( nAttachedAxis ); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, XML_bubbleChart ) ); + } +@@ -1660,8 +1660,8 @@ void ChartExport::exportDoughnutChart( Reference< chart2::XChartType > xChartTyp + pFS->startElement( FSNS( XML_c, XML_doughnutChart ), + FSEND ); + +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportAllSeries( xChartType, nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportAllSeries(xChartType, bPrimaryAxes); + // firstSliceAng + exportFirstSliceAng( ); + //FIXME: holeSize +@@ -1734,8 +1734,8 @@ void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType ) + + exportGrouping( ); + // TODO: show marker symbol in series? +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportSeries( xChartType, *itr, nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportSeries(xChartType, *itr, bPrimaryAxes); + + // show marker? + sal_Int32 nSymbolType = css::chart::ChartSymbolType::NONE; +@@ -1753,7 +1753,7 @@ void ChartExport::exportLineChart( Reference< chart2::XChartType > xChartType ) + FSEND ); + } + +- exportAxesId( nAttachedAxis ); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); + } +@@ -1779,8 +1779,8 @@ void ChartExport::exportPieChart( Reference< chart2::XChartType > xChartType ) + XML_val, varyColors, + FSEND ); + +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportAllSeries( xChartType, nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportAllSeries(xChartType, bPrimaryAxes); + + if( !mbIs3DChart ) + { +@@ -1807,9 +1807,9 @@ void ChartExport::exportRadarChart( Reference< chart2::XChartType > xChartType) + pFS->singleElement( FSNS( XML_c, XML_radarStyle ), + XML_val, radarStyle, + FSEND ); +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportAllSeries( xChartType, nAttachedAxis ); +- exportAxesId( nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportAllSeries(xChartType, bPrimaryAxes); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, XML_radarChart ) ); + } +@@ -1848,9 +1848,9 @@ void ChartExport::exportScatterChart( Reference< chart2::XChartType > xChartType + FSEND ); + + // FIXME: should export xVal and yVal +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportSeries( xChartType, *itr, nAttachedAxis ); +- exportAxesId( nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportSeries(xChartType, *itr, bPrimaryAxes); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, XML_scatterChart ) ); + } +@@ -1862,8 +1862,7 @@ void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType ) + pFS->startElement( FSNS( XML_c, XML_stockChart ), + FSEND ); + +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- ++ bool bPrimaryAxes = true; + bool bJapaneseCandleSticks = false; + Reference< beans::XPropertySet > xCTProp( xChartType, uno::UNO_QUERY ); + if( xCTProp.is()) +@@ -1872,7 +1871,7 @@ void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType ) + Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY ); + if(xDSCnt.is()) + exportCandleStickSeries( +- xDSCnt->getDataSeries(), bJapaneseCandleSticks, nAttachedAxis ); ++ xDSCnt->getDataSeries(), bJapaneseCandleSticks, bPrimaryAxes ); + + // export stock properties + Reference< css::chart::XStatisticDisplay > xStockPropProvider( mxDiagram, uno::UNO_QUERY ); +@@ -1882,7 +1881,7 @@ void ChartExport::exportStockChart( Reference< chart2::XChartType > xChartType ) + exportUpDownBars(xChartType); + } + +- exportAxesId( nAttachedAxis ); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, XML_stockChart ) ); + } +@@ -1961,14 +1960,14 @@ void ChartExport::exportSurfaceChart( Reference< chart2::XChartType > xChartType + nTypeId = XML_surface3DChart; + pFS->startElement( FSNS( XML_c, nTypeId ), + FSEND ); +- sal_Int32 nAttachedAxis = AXIS_PRIMARY_Y; +- exportAllSeries( xChartType, nAttachedAxis ); +- exportAxesId( nAttachedAxis ); ++ bool bPrimaryAxes = true; ++ exportAllSeries(xChartType, bPrimaryAxes); ++ exportAxesId(bPrimaryAxes); + + pFS->endElement( FSNS( XML_c, nTypeId ) ); + } + +-void ChartExport::exportAllSeries(Reference xChartType, sal_Int32& rAttachedAxis) ++void ChartExport::exportAllSeries(Reference xChartType, bool& rPrimaryAxes) + { + Reference< chart2::XDataSeriesContainer > xDSCnt( xChartType, uno::UNO_QUERY ); + if( ! xDSCnt.is()) +@@ -1976,11 +1975,11 @@ void ChartExport::exportAllSeries(Reference xChartType, sal_ + + // export dataseries for current chart-type + Sequence< Reference< chart2::XDataSeries > > aSeriesSeq( xDSCnt->getDataSeries()); +- exportSeries(xChartType, aSeriesSeq, rAttachedAxis); ++ exportSeries(xChartType, aSeriesSeq, rPrimaryAxes); + } + + void ChartExport::exportSeries( Reference xChartType, +- Sequence >& rSeriesSeq, sal_Int32& rAttachedAxis ) ++ Sequence >& rSeriesSeq, bool& rPrimaryAxes ) + { + OUString aLabelRole = xChartType->getRoleOfSequenceForSeriesLabel(); + OUString aChartType( xChartType->getChartType()); +@@ -2048,7 +2047,7 @@ void ChartExport::exportSeries( Reference xChartType, + { + sal_Int32 nLocalAttachedAxis = 0; + mAny >>= nLocalAttachedAxis; +- rAttachedAxis = translateFromChart2AxisIndexToOox(nLocalAttachedAxis); ++ rPrimaryAxes = isPrimaryAxes(nLocalAttachedAxis); + } + + // export shape properties +@@ -2181,12 +2180,12 @@ void ChartExport::exportSeries( Reference xChartType, + void ChartExport::exportCandleStickSeries( + const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq, + bool /*bJapaneseCandleSticks*/, +- sal_Int32& rAttachedAxis ) ++ bool& rPrimaryAxes) + { + for( sal_Int32 nSeriesIdx=0; nSeriesIdx xSeries( aSeriesSeq[nSeriesIdx] ); +- rAttachedAxis = lcl_isSeriesAttachedToFirstAxis( xSeries ) ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y; ++ rPrimaryAxes = lcl_isSeriesAttachedToFirstAxis(xSeries) ? true : false; + + Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY ); + if( xSource.is()) +@@ -2456,6 +2455,21 @@ void ChartExport::exportAxes( ) + } + } + ++namespace { ++ ++sal_Int32 getXAxisType(sal_Int32 eChartType) ++{ ++ if( (eChartType == chart::TYPEID_SCATTER) ++ || (eChartType == chart::TYPEID_BUBBLE) ) ++ return XML_valAx; ++ else if( eChartType == chart::TYPEID_STOCK ) ++ return XML_dateAx; ++ ++ return XML_catAx; ++} ++ ++} ++ + void ChartExport::exportAxis(const AxisIdPair& rAxisIdPair) + { + // get some properties from document first +@@ -2519,12 +2533,8 @@ void ChartExport::exportAxis(const AxisIdPair& rAxisIdPair) + if( bHasXAxisMinorGrid ) + xMinorGrid.set( xAxisXSupp->getXHelpGrid(), uno::UNO_QUERY ); + +- sal_Int32 eChartType = getChartType( ); +- if( (eChartType == chart::TYPEID_SCATTER) +- || (eChartType == chart::TYPEID_BUBBLE) ) +- nAxisType = XML_valAx; +- else if( eChartType == chart::TYPEID_STOCK ) +- nAxisType = XML_dateAx; ++ sal_Int32 eChartType = getChartType(); ++ nAxisType = getXAxisType(eChartType); + // FIXME: axPos, need to check axis direction + sAxPos = "b"; + break; +@@ -2568,6 +2578,23 @@ void ChartExport::exportAxis(const AxisIdPair& rAxisIdPair) + sAxPos = "b"; + break; + } ++ case AXIS_SECONDARY_X: ++ { ++ Reference< css::chart::XTwoAxisXSupplier > xAxisTwoXSupp( mxDiagram, uno::UNO_QUERY ); ++ if( xAxisTwoXSupp.is()) ++ xAxisProp = xAxisTwoXSupp->getSecondaryXAxis(); ++ if( bHasSecondaryXAxisTitle ) ++ { ++ Reference< css::chart::XSecondAxisTitleSupplier > xAxisSupp( mxDiagram, uno::UNO_QUERY ); ++ xAxisTitle.set( xAxisSupp->getSecondXAxisTitle(), uno::UNO_QUERY ); ++ } ++ ++ sal_Int32 eChartType = getChartType(); ++ nAxisType = getXAxisType(eChartType); ++ // FIXME: axPos, need to check axis direction ++ sAxPos = "t"; ++ break; ++ } + case AXIS_SECONDARY_Y: + { + Reference< css::chart::XTwoAxisYSupplier > xAxisTwoYSupp( mxDiagram, uno::UNO_QUERY ); +@@ -2869,6 +2896,17 @@ void ChartExport::_exportAxis( + FSEND ); + } + ++ // TODO: MSO does not support random axis cross position for ++ // category axis, so we ideally need an algorithm that decides ++ // when to map the crossing to the tick mark and when to the ++ // middle of the category ++ if (nAxisType == XML_valAx) ++ { ++ pFS->singleElement( FSNS( XML_c, XML_crossBetween ), ++ XML_val, "midCat", ++ FSEND ); ++ } ++ + // majorUnit + bool bAutoStepMain = false; + if(GetProperty( xAxisProp, "AutoStepMain" ) ) +@@ -3179,12 +3217,14 @@ void ChartExport::exportDataPoints( + } + } + +-void ChartExport::exportAxesId( sal_Int32 nAttachedAxis ) ++void ChartExport::exportAxesId(bool bPrimaryAxes) + { + sal_Int32 nAxisIdx = lcl_generateRandomValue(); + sal_Int32 nAxisIdy = lcl_generateRandomValue(); +- maAxes.push_back( AxisIdPair( AXIS_PRIMARY_X, nAxisIdx, nAxisIdy ) ); +- maAxes.push_back( AxisIdPair( nAttachedAxis, nAxisIdy, nAxisIdx ) ); ++ AxesType eXAxis = bPrimaryAxes ? AXIS_PRIMARY_X : AXIS_SECONDARY_X; ++ AxesType eYAxis = bPrimaryAxes ? AXIS_PRIMARY_Y : AXIS_SECONDARY_Y; ++ maAxes.push_back( AxisIdPair( eXAxis, nAxisIdx, nAxisIdy ) ); ++ maAxes.push_back( AxisIdPair( eYAxis, nAxisIdy, nAxisIdx ) ); + FSHelperPtr pFS = GetFS(); + pFS->singleElement( FSNS( XML_c, XML_axId ), + XML_val, I32S( nAxisIdx ), +@@ -3192,7 +3232,7 @@ void ChartExport::exportAxesId( sal_Int32 nAttachedAxis ) + pFS->singleElement( FSNS( XML_c, XML_axId ), + XML_val, I32S( nAxisIdy ), + FSEND ); +- if( mbHasZAxis ) ++ if (mbHasZAxis) + { + sal_Int32 nAxisIdz = 0; + if( isDeep3dChart() ) +diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx +index 878276a..ba32712 100644 +--- a/oox/source/export/drawingml.cxx ++++ b/oox/source/export/drawingml.cxx +@@ -1206,7 +1206,7 @@ void DrawingML::WriteRunProperties( Reference< XPropertySet > rRun, bool bIsFiel + PropertyState eState; + SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ); + bool bComplex = ( nScriptType == SvtScriptType::COMPLEX ); +- const char* bold = NULL; ++ const char* bold = "0"; + const char* italic = NULL; + const char* underline = NULL; + const char* strikeout = NULL; +diff --git a/sw/qa/extras/ooxmlexport/data/no-numlevel-but-indented.odt b/sw/qa/extras/ooxmlexport/data/no-numlevel-but-indented.odt +new file mode 100644 +index 0000000000000000000000000000000000000000..e435acdad35e581e1eb627d054951a4c81697712 +GIT binary patch +literal 19535 +zcmeFXbC9O7wlCb%wx?~|wvA~|+qP{?+qP}nwr$(y*R#L9Z=G{$pHp@JySM5-RjGw! +ztxA4x-ehGZza)WxkpTd}0RR^CNJX^<8K6l40091$Zxw*0simQVtBs+qjg5t=zOI9* +zwH2+Cl>v>luDz)}jkS%Tm4UUsqotvh1C4{Bi^H$~0N`&y`*x;i;%KR7 +zrE6+oPwVh6md3`)IOLa%C=4V9*M}hCx@al8@$`gseU^bgCmis4@CDXC_`ocf5e)eeIq2kSHvvJO|xc0Hy +zndW#2w|UQLR)WH?&cqCFoGOPkl^@12xyCkh3x^DRec3HcKa>c4p_%mo#Q?|KrwStw|R3T5? +zMN^cNBB$Y@)Y3FL_2mW6i=wni*D-lObyA^SV{&y#VRtsjyg}{BbhU76TusINAw1)2 +zo5^jxgH1YZ+JxO23w-AjIor6DY{5(3a^n1Q +zicG2$r#@%KvbftAA23-C@edRL>K3>ed$$Gbb)%p0;?d~|&rBM9A52zG_* +zB|uY>A&`ghNnlKSq7p2|czAZ@o#dhbC3*cg_w+Ri<^0w#_pqb!!g>Oz1(n}-mBYE> +z-ec@_znMYp+#lSPvmK7y7{wMfPZdN7iGPW +z>!{sH2?`k`wGGo{Q=!R)rTGYR<;ahM0Q%8}&^>s!S|pv+GW$o?72qF1E63EukSgD3 +zY(QW2Xmg_wPNgpwS6l2!F~7v|doQCu3?=aD1cdh_4kB*nkg;|-W;(f_Fi1|6#hz&; +zM3*$q(iOjp0QZ!YZH%`CP6T(@o8rf_mMJql>;=LxAYz&Z-h}K(>a4Ahuenw3<_)3A +zYb|c|)UpH-rqF5s`ML~GG@`6=LDtq +zkN2CZDcr9{o{!J9BHqvSG)`1iG5Xp{gt$d@5#3S}uOegWac-;_dx`^;wHeDV{i>qyNRgV>SvWXGA4MaZR{3^!jr4utvE?75WHYJU=S +zxT;HQ=BL*LAMW`@Nwd)(6PP2mFcf(_s_~3Gpe(F5EKQCpW*^gqj@atf5=s}R=6Z!XetXXO@9AX+~J7&*n{`za9oe~T&Y +zGpk+*e-_e^ggqoKSIgZUC^Kz>dSF&Ve=`1l6uywtK|cpcR2%LG)tlM@94dmx)qSY^ +ziWe8oW0p5~ +z4hXnrebfvH;wA{G)-_Ht^Rp5TclVWYGGWI}MYjn2>}eokv{Jcj){087=h*EDbO@$5 +zfU=-#zZ96{*RD|fD7taK26X~!lH@^;cq!G0erN@$*5{N#DfB__M+_D>69ir}obOW( +z4kIEkW4(<$(?(^2G7+`1S6KO)`cwOKqTXv+wYxkO#xDOfZgN@!g63O|@FrX?9^WPk +z=+fabHB8VC^bCud2Uc^W-9%7XTRInx)!yw@@cNnUMkFV1-bGM+Z8^6e6qP1S+5X{R_HX($~^Z4@t!&z6&uZdx;@ +zB%!fqpuB|)UmNqkNu#{jxM5{P{pa>_Sg-x#;$p6{;?*W_-abFBDJ0+Z*M9B&5=Pu} +zb)Kc-og7P8X+?eY7)HfpgFe42YgY#f7p7O`U?%U;R*j>I45_8_mGz4%N8CfMas2od +zcBE3ptI^TX?(%YZ5Qw6zOh1pPkpmg~v$yV)mvXaB#KMa4k{dy#bWxN1__XB3yyeat +z;FlyAxLTpE(<>+dfYtZ8=D*)E|8d|kbkO~~Uq-}@S*6pV1wMH~3blb~H^ZO^qC}L^ +z#5T$o$vemBf9aZ_W1>&dd8YG7YEvDqigSeZhT3=bdG{c*9trMcbUQRCt7io)Kk-3O +zn=4s3;~g0Vs+b12`deen4jTB=%qS44k7dM4VCM(f;0#% +z6Hg2Z#MxPyJ=mXJRal}6cy9giL^e~vk3C|?*Z@h;J6O##6_J1hhJpUcAtd03;&goN +zorbYImRP@Np7SFs6=zH?T%U=X*1<5}q7r6%8N3Cy<)Eh|=(FN#Vo#eY{q>-BBPXI3 +zEe!#**->b__m{lXE`aC{8K-y##5yv_IJTZWrEJQO6KXv3GadsxuMp7I*!&gfE(WdH +zTa!W71nuDqnz!U__tuwJie?6ddO#4F>B9ChTo@0Wqn1D<34tbM=exoU``gP(<)OR2 +zC+XMd!A+3YX^an`0AZ$yOg$+dyA;4dS1SBb+kJyx!q_;fJSIv0$&2?2b+MjAP2wMu +zK0{k8&-^*TVjmE(q6_8adn747afA-K&ugbm4aK4(2wmnQ75u`p4$r)yQ=e1eLhtSkA6gDMlOafZQ9`$EN+(jxibzZ1DiX&eyZ3K +z#*!^_(^uwDnqz^KcW@y!QKNtzY+lE!Ra!hif9DRV=J-4)AOHXv@c%S-pufW{dqW2Y +zQ!8Wpzw>87ZNmz4=x67ZLa`8JJ)faOJ(YU7uz$XkC<`$H(a$_nclvd1BG%Ll)$#FE +zf=~cV_8+lK6L8ajme{1y@>{4EhGLl4c_z3z+BwEf;;K1fk}C%QCke$HEA~c{Q_i1< +zj~V(&m0W=M*prR+XG@EAl-*QToaId!oEA&U)(4mIUQTJwZIK|tY3iL&QWX-vAd`lF +zzNe4q-MVoeK`HMGanue6L)8|S6Fm7y^HOGNYlf!~%SM*;MK;=d7PRZ}@S;Ii!c=PS +z9;=RH?*FF#X_N2_)-F3e0uv+iD)&k5PYFWLCz;JsAvY#DD +zoSm^+Z%%6G+c}Op9+$S{FV)U?9xs>jCfV!^u1-`~^lt$dEoF6G^t$bcNW|2?dQ1aj +zPC%D>_PXI2vpKL8@%^sM4}d#yIj;@f27+*34-%el3mB!0({>DLI;F#m?CB&ce_=uK +z_TR)0QbBsDKiwyrQC4McTwh +zvZ8T9a_F_Fr_><7oFvs+Ztl#Cd|pd$vm|0RxACM=B#|nO!+%mrP}nl8^Wx6Qv>U4` +zR$=2+OV!tomyGxw8usG8B|)C5xdI582-rq)%^#XE~Y3 +zp}d84HFEe$|KaZE;yJ|7@PTG1ecCJ%`9#ZcLoiKs74AJyAq-m)+bOa(bp@@0XCWq +zr|78qAZ5dxa-;1vWn@{UYs`l+vjS +z&N9r9d?($`GV^GNJTOv;=jEUpt8KX8VvpSknGxdyEYP2ji8AK+=ic}jX{>z7mu~pc +z#)fz)eitYZ*&UuMG+Vw48>QV5P;jU_8ff9PG?H{bg;0&{%Ci#PpJWS>%^toN2n$v4 +z5UudE3PnQ>q{c56qfW7RI1X*eOsT~Wh8Ye%mr`zWg}I2qQX@USRrT3tXluvT*x8Lt +z=%UW<;ZViw0;L>w8v_(RC7MRD2RX(_ARKq5{%3OUmcv7o$xm45{k-KzFWW!5d-tgc +zeb#iY;GxBj-BPG1X6UVcC#FOQ=!zmLFjZVqk0L(BUo@n}gEkm~CC^$&36L|9#zEZvxv`s`*G +zya4`Yq`mGGO9NcE1&Fg3@Ng&t5b^R +z=CSi7FK=McI+eFYj;Qmp)+p@aXM|96r(4FA^T|uO>y>YaCaYZ{LDm!~ueM5WKH+LrY +zT1>Ba7@o)xJRu@kB6;3Id89MPXC_RMgR*%ytTWGTCht`y?^JG|O84()#{;|yg{M`F +zIkT8u?;BTN&$n$!Q!@Tt8KBxhJ%4nsZP7dsL9>E-j&!e+OzypyUg`djt9$erBk`FJv;MbOzLv>mQw<(7z0}m +z!c;dD(24zXN(@!ZSU*mvd}6O&>Zx)3y45{gHwi%vOb@dJtE>~g_}&!1>Z`Gtw*0=j2nEl}N**0O#++Hd`cbDEfkImdLvQew1X +z0O=)u$#6H4C)HZg)*3@3k@gL{b85j;o1%zwK8OgHqqIvjS=K~YwjX+!%4h``LZVGi +zl{{xH^UaG3kx_S;SIDjWPP6x%o!QI6hFrR0GGs#tc`sbc=D~2JT!M?+VBt8bk__(m +zo}QM8jLwRcl25XG#;#~?b|y>GfvPIcgewlD1_j+!$dRJRVc%S{3#@+xliXf#jw27$D&*EolF9a{E8p{Y`HFS34sMYh4FJyZ=qA?@YR*p6>sy)!#n;&sJFf +zriV6m*2Z>*_V)j?<-fzk-a*&F@jux8yZqDN8-)LgiLSoBp@rc$wAOaC`i^#X|IAH& +zC-=YOtiOPMhgtvl{(GqZU3YA(Z5(a>BKJRljr;BQzjnveQrFnfo>sur!BW@8{-4JG +zZY+O;J4;^Lv#dj9ZcQX&1U!!(p|>J&H{F$N(XLN;++iCWCE2x*x{dN3e;V;(eEA|Eq(%cA{IObPBnKE1@8sBfaxQj%O|+%EOq9OnjZwg}^O(itvgPunroPa3 +ztLmMEEchn#j9;UV>ThwCM63S(X7x`dvmieJ0Q|piYX19k)z5GEq=gmvsl{bPX#W?E +z-$8Oke2-Nh9(2%^XK3&l^0Hg%uQ(iv3y4-Qoqq9{ZXuo0#|zQi#uFw-v-))l{m-ws +znq>>wNfc4=8JF^9Om9Pw?8k_nO1-SNsM`$7vxPx&CTgMBrR?D+y3N_p0-xD3lU$(# +zJc-%aC!dI=ksq<|E3~3T>P}$QMh~UQ?`rxv<4=9Ar&e(dhE>PE=x@XfC^${RDNfb} +z2Nbu|^L`$%*!BlSb-!oEA*Bb0utUEI+G!VuNBC9ZU)8vG>!hFZK_As=)Qe&~-(ul{ +z!|m&_WfowbSm4vpocYY(mh;7<+Pki13@tj4ho>Pd37Ep5*q!=MlLvHxeeqV2sxXsa +z!MiYMY*CJTBuYm7DfH}RbMDXxYC-7w^m)bn3-1FM;UBDTczOQEqsQNSGkXVD3&VdL +zJT5#XqxOcK4mZ2}hD9)+dId?gq8yCTH5W9S)`m+jOUlo*pu+(ba^>5lV*tesl^0KY +z(Z=n3dH@);T%cW8>TXBFR-Tu}dnLEJ=t%wGZV>oEaAU>9H8qJtYPx&pZMs7$@^0-%ion0(2L@u!| +zElo{L_0|yp@9Z@gs4g2LP}3wh3Rc2-vf +zS1EVIUqvi4%4sw5nh0o3<^}g_FCi1m&2Da~B`aMTxdME!Cw#F#9+dfwm&F`AWnrCY +z&-FVd8Ps8x`PcO%65?DqhY+nawQ3t|h9mr-t02lbC}cC?(P=}t3XW#SFEf!>w8$Z`z$G>68Rn7oPg==r;=2sR)1>HHt0 +z@tsH1gklimw%?w2FbZypp8(#H7Zr|~4$4$i;ab46oi&yj|73A8(z-oJ>#f`lY20Em +z-#(s_nml}ro#F!^08%E(RcKrl#5Pj{r<4r)I(Z%D5k0iF#A;`+@o%^a73U>4QtMp| +zGFEHJIvtbf%@?_yz9DQ@-{8;-zR~j?)LyZbhaIBwtQNk|1zH-kInk>mE`%luljl~^8P@*-1_|N +z`ds6Euj)y)Z%S#gPit%X2!89h>V=<+DW)cbXJjIBbIL0Q!McCt+~JR&3w&Eix!Mnh +z@+YYcZ_ocRXdx}NdY9F7T36-!@l)>N{x +zQu%Y!)#)pq{(gnxh#~)py_x4wk@U8R&HW~~~RfqreN +z&3&an#vM$sF2e|arZ6Ce;r<*c*;qhg8=DMZtlnLB=?=Ie#Qo4XV^vl$r$enh7M+bJZkrKF?=jMYXvF +z<6ZCLI*3mz6N{OSspU3Vgyxj`A?|-nB?bF*z`Rzn90#zFl%P(vx-@GQ*U!pNA?A-omXW6(i6e?O +zgkm$j4hF76_Vm@Dur|X3;iyXEg95CwkEOYZ_2pqx^eMC{-JE}AwPL%&GE3XevP@Id +z3?hvU0mf2X?!`^*SBJD7KK6bF*84tmm?AmEq +zqPq)E{+M%^(KrPwUmbE^;7d?MdN-DV9>PsU1J}a`q$U=T9)bebtjE<=F)~2i7t=p^ +zzCQ!k!rJ$jbaOzb<$K_nE1e`kPxx?4K;jzWqG}nw95YOV3Axf(G@C66A(C0nlDr{^ +z=P^Le@JZq@Cd#Z!wGBn}u)J?k>);6u_23PbDN*sQzKaXenJqX?8#Y$p8xuIK$)goG?bMKS6piv2x~$WW)7}&$&GOkjG%N +z7|);qLH%WXM!r%M$&d|kOT=W-q7VeZMfp3qIT-|{(y`gT3|2qPvbpx;`lhv!pj!$k +zn^(B3SlSV)R7s-JNb#+*m2;dyX!w{hDrI7siC+NUcZ7bKAUpw4_+hf0jNkz<0OI~G +zpUMU}&LG0cB>P3=ag2x9Z7D1$4@wII2%19N2b=&nXv*;`6+)IB=uX663oLYokINBg +zq%ypJMF_G44Xd5u9Ym%NNU&*I5Q!L*&EJnnsUCpxXXdF74h52uA4MDy%qon>pHu34 +zVgWK8M_({5kE|c$)nMiY{d+{z#i6KS?UXQ-wdLhg#ScEpDAx=!8T +z&bURB@vRw`S-#X<k?hln-HyN!`ZB;Ghycs}d$^rv$|x$hO2 +zcdt~_VaxIaJ-VGtRx+&Kvv$GyHy{ntjMv1Bh-=%RxbVBUKP2Ryre@qAuT*diL{|)0 +z*bY$pr5Tfj!Y$H2w!Hm_@-n_^4k%e>gcFx1m|L;su&cBCL7>O` +zuT+HQ&vkxEQxj{x8^c-=Bg^m$u;?@$>>P5Sjum!xGv^CSmKY$5YlPB}Jzj)Fw)J>a +zV3SOGc#?FS7VT)8u`@K@JBu${ecoQep&>YjpS8@5+voNwKt@yCmLj#mD3a^~HT1{M91|tTtrQpRh +z6IJ|^9MTa2uO0_C89Be$4>36Y;Ca9ita~&(-pr23XuhY4jJ=2H{poz!JV>=cxhY7KUKy+;s#o&)q0Gf`Pr +zPa8x`n39uOKpevuF=?vP7pGLdSwpop3J!VMoV(_v<&~mw*-*^>R+7af7e(U7WY%24 +zcj(d)$fiV*Q)%^lgzu+cg%83dP4hPD=6+sZ-gNRwDaMU8pLe9i-hb}usO_&hISn`D +zNzo}LcoqD$HHx96^yjHTNJ&m@Wjvncq~fmWP?$e{JYLt|`AK2sF@Rgq(%2;;y>TyW +z|HZUwb`WuUNmuzK3U6T;`x<^+yH;Rq6F{ivXWUycw|Lpehk<6;=_}(nhrQOhed!~d +zFDvbV7$Spf39)RpGklsG*ig|Utoi~i1A**dxlUpOXY!o`0zqteq2GQE0XlGr@RiJp +zexu|`TluImztQ17CT3eT>TCCOUEGSu%gcXj~U08K*-e%@z>&Y1HTX3s-iF +zy{&6R9-2on5&Nx=r?wnVU_ZIb@7RoBc;^Xv8M*zr8spYl+0$ZqNEwb`HG{cX9VC4l +zt|N$vjJweoLyDi*W3-2F6B4s-a5f-H%4Gf;{D=>SzL$%%z8?zj{&nC2U^mC~uHmG6 +z%e?3MU)2}fYqSV!bjy6+W_hxXN%YI?rBo4%^G-pzR44P6wr%8(bM$Ba7?pmp!xIt& +zxC-L?o)jTRRJ*H8bW-`1w@eG9sSQ%?bs;4oXR}jKD95Gz9cOVxj?ApQX7QW3lqsQ +z>WMt-YY7b$VpL@r8_o@a%}0ZQhuu;N-YZ%{$%* +z`)Fy|V2S=PA(>EtZs{yhZ4t;hzDl_;j%)o9&KS<_IV292*UKq^7U{pFNJSak{ +zkBh*LSPd{l=z7Lu)oZ!mIhq3`GzJ1yDbRo$W6sn`iJWfP^}u*eCWox4O=SjX6OB#W +zv81mK6B^a54rtvV1A>qN`=l=R1ZKSB13n%UqqGVNT9-jSUT7R%7(I28cCmxsL|*-< +z{aZRl^X2z4h{{C|9fC^!F|d4^0=zJ{3CGp6aYonm<5SunUbZ@H=wkSWogaZS%xlU8 +zYXh~F##OJ>{q2q1wBYYXHR2(Uq%6#7nZmo}srUQ@4$ArUZqGGj`JAvK^6GtjwWwdh +zWpPnkuXyz^b^Pg@mK0(fWwrL*l8i5)XY0|m1Ejc3xDHXWe{9=`ju*G>1)Z|OaQi3W +zvGg8W9i9$rr$o)%?M6hWpAec`Rjk=A2$wJ1uAcatYq|4#c=b+*%WMS(62#pc1;ZuC +z8OICOuCBMvs62$^wbk)V)VPzI=bO~HUBdR+y&whPj1v8u<4v%OSLb~{&sQ!ZZ*WOY +zcwZ&OS8>KiV%4w$byec?{-B!a65X7WsKOP5FK>crBv}qJ&(IAYKz-%l=a8K-r)!8%*lhG=BtIRPp +zHF4HGx9C=$;PIZx)re}#Q+ib`Yu#2`>u)D(yg?0BA&p37;gzSb&M7WR5BLu2LQ77mJ{=Bp-LQ(3Z +zQy{m*Z6zKp(h1^YWT3=3Kas)_Ls%(06uFIsgiiUlioumb)Xw(v5hKP&Gu9NX4o +ztk#VW&jaqi-6{Mzue`+J;OL)qKp_)6)-(PLM5xC{o4pKH$j~oH(3ihijLK8nPfM#} +zv%sDCnaD+k9XR1+2#-HzPvu-W9VXQ8w{q^_fsK=Ou42u|R4)6%C;X86SPnMxDdr#+ +zBDYnu6XFChLx+|dn~jVprZAZkh)0AV60KJti}r|1oq#`2XcIh5Kg=eM64eQKkFTUlS32fout0@NP=$;5(Q;y6K_V%*^`O=h-0t> +zm_%#MR4Wpbo@~{2^i`a_40~1VrCjaQ(8nofs?j;tG*`}wT9ZpgWo2=I=b-F +znk1=ZKP9M0z3))*GLICiI2I +z1#A)qJA~RLkWsrMfqo;hSE_a)riOV%Kvsf&NZhm@FM$KR&D`nK{#@0(3cgsj+~oYs +z0TPfggr0l2HxVTYO|vDVsekY1BZX5#l?A*QRIIsm!WK9yJbnbooB`1_(Qdlu+r|p4 +zSB3?bIILWP1VVJyBkJ!&))kT2GB8+bvBqbij%d>dy>vPLWs?kiG--663TT-}wv +z4$`1QC^$E=el5;(@OX|8qfGJ~`Q^CIcn#>L>QW~A1k012(bUZNCMS3t8+clNu80GV +z5vw|pWhmEN32Q4Q6?vgXPgyv1MQA0{6^H>R?b5A4ss}cGmA8qN@!6~Z(pn4RKnuP1 +zba1j&G98Yp;Qa|pKS_T-R_^|&K}96;G&i6nm%xRkAd47!us!ecr~awC`L3!23rbMK +z3T5|j4Qvh7BN{#z4Cr&g;bnij*>wR4`avanLM8e_B|5Xj;NdZ7;GOpqEhQS~Jlv<@ +z6cqZarY^nus_wo|x5r_g+sc8U`TZ!m7$`?#VxzNULQ~ob2NC=UYVaUzjIFQ9Ief}L +z*o6k9xPGW+eK3{Wh(a`O5>Gw(Mo8}%)+QEOV`PyN$%%;3^twZRgGp7+r?K=prv)JU +z$<-0X!}JEE=y7&)(hD?uC!9FJ$;wzf=S1L^I-=nWV*X1i2s>l(XiiDLbyY-@xN=Ej +z`pijzoMS9T5osK>-+vI$~XLalv3-70_%&eIUpS%B@3b%$dwI1J3^O32lup +zgo;Ucy)V?*N4$mo*)l3ilfE9J#6#bf-w8Lre?H`bfo;>fzT4KUYf`aJaJRX~=Q-ju +zm}Q7os2$0bExOK^{%6tc1~972dxkb|@rPxW*Ga__O^qcg4Fx^QJZKRXyDcUS|HXDZ +zBZsq@$dSy%@p=h*1}Af#eUXvF<$U;LM(Rw9LLT*K_5L{pgpsj0-S^N|R1wD~V|APo +zf$Qpsk~4^N-d3X)R1wR+b&iR^WpzZqGl+XmsUVb%#j95(d!0vOx@IFhkB8QL8mTEJ +zYC77YC}(RI-v~L<&p1~=8?{Fq4HY$F0ve{qb4|joxAf$|wIUc4{pt4JF&#KitZ8IS +zbGz-2kP$rqsKY7*^2IQt!*QmcG;6AxCd`A8rJ;!@){DL@cy}lKu5K<(8I}-WR7l8f +zxI9IcuNTRrVP>yMeph5u3BC5Hvi-UYx4We;*f%r47Li|AmK*Rzrl-agZD<|*v|b;M +z$Z)lbH=}%TRxFWav}w8DdWiNy%HKkUqdYu!|2?O^aZ~v?3($pw0X$=y;7a}mP3)R_ +zr60}`J#KoqWVy?K#E^P%=22HqP7xnMp1U7vfL&DV-U(SFzk@~tY|vyf;G#KEY;hHW +z0~ps0)=>j-w{9r`M3EAg-MS|*EykLWuUxVN8@GX+zzJ*OoKCl8%V&BTKto@w6&R!) +zta_~lc8AK+A{gJ7;^)7~MbyO0sMMk7FqBeK+LN;U&>O&d;nI1=1M9!9*!xuWfVeCi +za+y4BtCXt@l)a}>61`bHUdTj#QvkK$jjGmNV2YfGZ`aSi%>BCgmbq!v)8|;dv9zW| +zgR0Px*f3&O-_=*53v6E>rlJ0z0Q0MQ8roq`gV$c8b)rF)w6UpG#u{9(o#WcB%1roo +zlueaco6YG2V5qoTioTMNH~66oR?@{m&O({9&uuQAglaNmq9mWQ+S%asdH;^vU|I%a +zyORZm^5MR+R@=G!CboWHd}-2t#y)kOv7@^=POAUqymYSJFYXqY$(w$pET@@~ObaSOD*32ZABFr=KVGK%L9O(CYCy!N{5JcLvX2oE`Reg50C +z=k*@Cc{TV2NyACBqe6c)JH>YAcgLjpX3x=+T|(W8@-;Fl2TE(t+VZytIqiGX_Gp&0 +z6x9BZHR~~$&valJu{}JFM&#h8CV+s48By@h-)od9gwk}TkRXhCFp9=kU-7OTW4}3q +zInx|FAqw4UZiChDI0crk6^=V_)!XoL29$V(9=kg~REOA5uWwAM>V>pUIaKeDW!KXs +zm0-*{MfR=TRy9`D>pCRVC#qU(7K}Mtu>{#oyTno*1fvY?y^JRmlWe~YI*TZ+g|UkH +zFb~%jbeY%OAypj4xzr2{3(7{ZX4O^8Uw;%J>z$$pBif-=9(-Tum*YriaN6_GQVXPs +zyG&`e*wz5x1U5mk=n^B}A(?HCKSqxLbb_6!2?PuLvEKVp&}3+6FvjKQC@=6rQY%1F +zfM(SBMWbsvaf<8raEEHr*T~5Rd*p7Ho-xO};pwe=`%7xjVr2Ik$t5FSLkZlr`!gPk +z)Bxdqt~+Hw*WsfYsX8)>1*&?BtleQ}2hfs15P#SXPj0`XzL6qvAm4$lXYCWK4G9a! +z5w}St^8;Yy8Bw5KI!MtXkcb+SR|7Z`l?$jDj#eDHd)bT3CVH7gtiU!j=8qi`TmcG~ +zROko?i-uc3D6jq|g>-v@`<*g6y){&V@yuRH2DyRc8A!I3svhZ9Q-`sblEDDn}yflGPsm>?|L>-mxRWiDC +z@<|6hBS}~a4VeLV9I)iPShA@fzUiOtaf{yZg@$J(Y(G6H +zumm7N3k2I3s=|Vzj@->aRg%APK#%$e=c4ygjrD93yl}boFl*BOf$eilbxJW38u^sPK<`g3|0`)rrtkImsT +zLo+x@f@e~wTf*)ZgU8b*5fKbdq{8kRgU2lqFOYsZUL(tW|wIm8@78(quT~fqD5@`a6-N3ig<3qvI2Vs;(W6eI- +zidO)d&$gr}*fphlX^Mm-ZM!?D-&O=3nP1yUF+~4v!IP!{q?m_wWdXo6!eGU>g3Vn7 +zT5MRqI88Lx{KIkwmxEeJiJxAr)FknMEV%KGe4|Gn>nR;&gEo{sDnVh%B<~^VT{g-ZE9g8fXk=ib&RU7d523IRe_Q*EjkKw^v;o{0ppbn +z3GFq#MqS)u$&}%00W(S=1Q8XKGvOFt7u1>J<7oskBpLU%!WC!43%rne8p(-58eQVF +z765(pX6@1owt!qvTvMT_{{x*n{v%y{F0gilRSei3qqFC4U7t8yu842k4ck%xwxmK( +z++|31H#>-|5bw~e!%jTrqYlzeysEQ~>~am0A=`wM +zPAW}i1s9m;9j1dl6*){K@qtccLD!dc+)vn=4-s!$M9dHOmZZ-iUTL)HM$C@^a*O+` +z1HIPcqi2AN1CwvMynX%;`d2plr~H@xl`Z}$|E1sZkyR_%aq)&sJm2KH_9RKv#`?$_PDZt7rSJWpg6lCSAI=j&^;y$oRfO_t~J +zUN$>SFiA~VcGTX1kWOl^ayidse4Nj>p?e0n*d8v&y`4uoumloUwlD-i1UAO~^Nb)T +z)8~$NB)o@m)e`aP)Ciwz$g918jaKewI$C;CG4J=o!*8`|x68L$?H_9Rf2e`~s!McS +zN9DY|UIu`{3pO!zYwbFN<0Z>a32utI-n!y`LWoDhgbE!)9;gwf>yyQ>g+rZ;|4IOf +zI7H9SPCZ1UEhUnbk1SmWT=-&CRs8AerVa+Oz%=x$_!Dqr59?Fp?U6hqrPa*Oq!EZ^ +zf?ms!xFyL>QOQWre?+eo3eqx+9c1pib#f;JOU_xqy8DspYSYlkICKsEas3N5$Qsj7 +zF%134lY>#vGO|=EYAB#Zs(yP=^1dGjr65&^pOC%obRnB*VojP}tnBHyR1FaX1@$5{ +z%m&k#OE~?BghOi222c8@;ZdtjN(Gp>cw)x(MYB>%oPEht!J{hs{N;W8^!HeHEvX6> +zJK+Cx+_(3r(dW_jk17efO;QJvDAAar=0%#*kspc +z54wI!gg4`7(A}~`p27wpk~$aLDo%=L1tin6`u&{hPqs8^I%8AxqV}!>XzIQDrpojJ +z!}RCM_`3RVg-si~pu`*C#@O@%({>BQmS?Hf7pZVxmJl>*mJknh4{!!#PJG;s=el)a +zM(N`Sa_E +zm`|9zcISQI>g7sqm7eT!31bNTWf;A9XMc@tHUKOb8Hl|09{pRJUr~s2D3Piv;;_}a +zePq_l%{n#KR2c2xBCcNp`!(6to79DhD7mo#W0|4$k8lQ$rQeJb4shK$|L;GrgI~Nc +z0lU_+l4PONQI0aJ+Z=T2>D)E4b5C_$@FZZ@)Hk}KrWQyD8?!>V+<_7Fgd>m1+9Cm +zuFaAwA}gen>K;))_W&kg>jqBZks89^pdV}jP(xOBgGWtQ1`Ek>koSh$`S*6E*oBQp +z;hec7PR__(WrJVCI=x~iWUGLzKgAn)Vm!!r*E7(r-@<^}WSvJqIy1tIV4ksEX2Kt6 +zvg?3t-Y;nu+q@?cd0x$a_0{A9Re{!QKHC=pTv9gP@?=n;K0ApxC(WahFSJxl-dL2 +z*lMPU2jiT&-rC}vLehfqjKGc?J)9b3#U0}1epUG$Ic}m^dvNCNwL&wL+Z(~fYNj#$ +zV?Ua~>=-9D*^}$a`HFNT%C4X%M`M{@rs&uEqK*(C7ZvA0V+e6{$EkhMw;uc3IS?rK +z1Gnr>dbiXw-cMl{N@pBe-;7qgQ5Up;6RTP3cnHRmt1izP#jjL#G7m`$Lh$G&)t7`q +z61X#JnXDq1CEyhbYi48fk+U9kf)KwPH0)G@m^4JtsRXC)I5$FN9VNNmSzFws-^TkE +zY;R?IIM0f#%R%sfC~D!y|W&Hsjiu(}BQ|FJ@EY5m_l(7PfAD +zxdlpkLBI;sLR>bySTUCexZbbii@QH~>4a~w$~q=z$zgy~8TQ&C&s_vcYALwSGB>vJ +zGm-7C146Ak^+yl$HOstV`;o0o(T!xHrJoy9%rn2&az4;j&kPd*;Ib*HV3aTCI?dMD +zj8))8qtpLPA6!Or=@{7R?R(iqgJ_^;en&D8BGPwddg8&!O@vF2byR`W|zqG_@=XriK;+>|+NmDpyYS+?QQ$ed8=9)Tl# +zNx1yI4)lvp`83vHbE1FW6!a6x@^jog^OW)oZ?;ui;DsJUHbpk*U$+hlei1iTRo3m!c)8Tsa0Y`5LKA}fyRiZZPvHM?^xM^qM6l}Z6*q@2>CRu +zIU3D%v3UVKV%GsR=51qvrsmiP9Ui*5OC8SLK7euttviG;0am06DW8gB$=X(r{o(;> +zS+tTpN|wgZOA=WLLhqbUKjBn5mwdPqQC>H0Wn<)|>{TwS3^0cRKnbPVIKaZZ2=;Yh +zmOc_$(BwAs>e8hdF{q)eSSB6eNGq!lVcF&>AqcryYG=Plc@oN}h~yzA-a%9gyf=7( +zjEKlE6lehfy0Da_jLg8w0#E@@?D?=FW8TQa=%feGorA!htlW2_1> +z329AS(XS@!3gArQpyb;)5OO0`N%^$|uWb5gKEl_d6Oi{Pv;JM9UQA-vC~ywx~AKUPy( +zrVZ9}yxdk*aguxVLL$=JDgibH0QZ5!eg3}{eSP&+&FOBzk-d$M6JO`w`O&&r`P{R2 +zb3br)+3YG<5t$`?Cdqo^2CpZZG)$i}m}Ry%#AdQuCuL?mnN<4V2$$=Lj^F!?k5_-+ +z{V`^D)z`axdf%?O>YXk4+x5IG?CZB=!_Q~U-k*zl-|YH_=W-Zd)ny9@nFs&w#I5~5 +zsXHx0rFY7FZdsE_X>JykM%?q}T$uU!_LOX)A4k=Fb*^V0Zhf`j0Po@*D_IuXJ@EJ} +z^83Rwp);|o*mmvUXl`%eh|_#r|7q)q{cTBgZTn<$J3Y(<4MS#bli+3SlAfY;yg2P- +zUeoQ>H`RDP_RT*dByu8NaDwc#}}=HS?CLVN<4ip5amohGPut( aLRSpace ); +- } ++ // put back the new item ++ pTmpSet->Put( aLRSpace ); + + // assure that numbering rule is in + if (SfxItemState::SET != pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) ) +-- +2.4.0 + diff --git a/SOURCES/0001-Move-SolarMutex-down-from-tools-to-comphelper-to-mak.patch b/SOURCES/0001-Move-SolarMutex-down-from-tools-to-comphelper-to-mak.patch new file mode 100644 index 0000000..aab31ae --- /dev/null +++ b/SOURCES/0001-Move-SolarMutex-down-from-tools-to-comphelper-to-mak.patch @@ -0,0 +1,266 @@ +From f76b3dd039818cc2b297fa2a11b60d9e055e6d8c Mon Sep 17 00:00:00 2001 +From: Michael Meeks +Date: Fri, 9 Oct 2015 11:27:26 +0100 +Subject: [PATCH] Move SolarMutex down from tools to comphelper/ to make life + easier. + +Change-Id: I7dd21f30daa27e5de2848eb16aee9a610dd629d5 +Reviewed-on: https://gerrit.libreoffice.org/19271 +Tested-by: Jenkins +Reviewed-by: Michael Meeks +--- + comphelper/source/misc/solarmutex.cxx | 25 ++++++++++++++++++++++--- + include/comphelper/solarmutex.hxx | 17 +++++++++++++++-- + include/tools/solarmutex.hxx | 2 +- + tools/source/misc/solarmutex.cxx | 9 ++------- + unotools/source/config/configitem.cxx | 8 +++++--- + vcl/generic/app/geninst.cxx | 7 +++---- + vcl/osx/salinst.cxx | 6 +++--- + vcl/win/source/app/salinst.cxx | 6 ++---- + 8 files changed, 53 insertions(+), 27 deletions(-) + +diff --git a/comphelper/source/misc/solarmutex.cxx b/comphelper/source/misc/solarmutex.cxx +index 0eecac8..1d23754 100644 +--- a/comphelper/source/misc/solarmutex.cxx ++++ b/comphelper/source/misc/solarmutex.cxx +@@ -18,11 +18,30 @@ + */ + + #include +- ++#include + #include + +-comphelper::SolarMutex::SolarMutex() {} ++namespace comphelper { ++ ++SolarMutex::SolarMutex() {} ++ ++SolarMutex::~SolarMutex() {} ++ ++namespace { ++ static SolarMutex* pSolarMutex = 0; ++} ++ ++void SolarMutex::setSolarMutex( SolarMutex *pMutex ) ++{ ++ assert((pMutex && !pSolarMutex) || !pMutex); ++ pSolarMutex = pMutex; ++} ++ ++SolarMutex *SolarMutex::get() ++{ ++ return pSolarMutex; ++} + +-comphelper::SolarMutex::~SolarMutex() {} ++} // namespace comphelper + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/include/comphelper/solarmutex.hxx b/include/comphelper/solarmutex.hxx +index 3b66a00..c50eba2 100644 +--- a/include/comphelper/solarmutex.hxx ++++ b/include/comphelper/solarmutex.hxx +@@ -26,8 +26,15 @@ + + namespace comphelper { + +-/** SolarMutex interface, needed for Application::GetSolarMutex(). +-*/ ++/** ++ * Abstract SolarMutex interface, needed for VCL's ++ * Application::GetSolarMutex(). ++ * ++ * The SolarMutex is the one big recursive code lock used ++ * to protect the vast majority of the LibreOffice code-base, ++ * in particular anything that is graphical and the cores of ++ * the applications. ++ */ + class COMPHELPER_DLLPUBLIC SolarMutex { + public: + virtual void acquire() = 0; +@@ -36,6 +43,12 @@ public: + + virtual bool tryToAcquire() = 0; + ++ /// Help components to get the SolarMutex easily. ++ static SolarMutex *get(); ++ ++ /// semi-private: allow VCL to push its one-big-lock down here. ++ static void setSolarMutex( SolarMutex *pMutex ); ++ + protected: + SolarMutex(); + +diff --git a/include/tools/solarmutex.hxx b/include/tools/solarmutex.hxx +index 85e465d..60af81c 100644 +--- a/include/tools/solarmutex.hxx ++++ b/include/tools/solarmutex.hxx +@@ -24,10 +24,10 @@ + + namespace tools + { ++ /// Deprecated in favour of comphelper::SolarMutex + class TOOLS_DLLPUBLIC SolarMutex + { + public: +- static void SetSolarMutex( comphelper::SolarMutex* pMutex ); + static bool Acquire(); + static void Release(); + }; +diff --git a/tools/source/misc/solarmutex.cxx b/tools/source/misc/solarmutex.cxx +index f718999..6602939 100644 +--- a/tools/source/misc/solarmutex.cxx ++++ b/tools/source/misc/solarmutex.cxx +@@ -21,15 +21,9 @@ + + namespace tools + { +- static comphelper::SolarMutex* pSolarMutex = 0; +- +- void SolarMutex::SetSolarMutex( comphelper::SolarMutex* pMutex ) +- { +- pSolarMutex = pMutex; +- } +- + bool SolarMutex::Acquire() + { ++ comphelper::SolarMutex *pSolarMutex = comphelper::SolarMutex::get(); + if ( pSolarMutex ) + pSolarMutex->acquire(); + else +@@ -39,6 +33,7 @@ namespace tools + + void SolarMutex::Release() + { ++ comphelper::SolarMutex *pSolarMutex = comphelper::SolarMutex::get(); + if ( pSolarMutex ) + pSolarMutex->release(); + } +diff --git a/unotools/source/config/configitem.cxx b/unotools/source/config/configitem.cxx +index fd1c423..7d03ab8 100644 +--- a/unotools/source/config/configitem.cxx ++++ b/unotools/source/config/configitem.cxx +@@ -40,7 +40,8 @@ + #include + #include + #include +-#include ++#include ++#include + #include + + using namespace utl; +@@ -155,11 +156,12 @@ void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) th + } + if( nNotify ) + { +- if ( ::tools::SolarMutex::Acquire() ) ++ ::comphelper::SolarMutex *pMutex = ::comphelper::SolarMutex::get(); ++ if ( pMutex ) + { ++ rtl::Reference< comphelper::SolarMutex > aGuard( pMutex ); + aChangedNames.realloc(nNotify); + pParent->CallNotify(aChangedNames); +- ::tools::SolarMutex::Release(); + } + } + } +diff --git a/vcl/generic/app/geninst.cxx b/vcl/generic/app/geninst.cxx +index ef7bec0..d53ed30 100644 +--- a/vcl/generic/app/geninst.cxx ++++ b/vcl/generic/app/geninst.cxx +@@ -21,7 +21,7 @@ + #include + + #include +-#include ++#include + #include + + #include "generic/geninst.h" +@@ -32,12 +32,12 @@ SalYieldMutex::SalYieldMutex() + { + mnCount = 0; + mnThreadId = 0; +- ::tools::SolarMutex::SetSolarMutex( this ); ++ ::comphelper::SolarMutex::setSolarMutex( this ); + } + + SalYieldMutex::~SalYieldMutex() + { +- ::tools::SolarMutex::SetSolarMutex( NULL ); ++ ::comphelper::SolarMutex::setSolarMutex( NULL ); + } + + void SalYieldMutex::acquire() +@@ -125,7 +125,6 @@ bool SalGenericInstance::CheckYieldMutex() + + SalGenericInstance::~SalGenericInstance() + { +- ::tools::SolarMutex::SetSolarMutex( 0 ); + delete mpSalYieldMutex; + } + +diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx +index bc9b205..137c72f 100644 +--- a/vcl/osx/salinst.cxx ++++ b/vcl/osx/salinst.cxx +@@ -21,7 +21,7 @@ + + #include + +-#include ++#include + + #include "comphelper/lok.hxx" + +@@ -350,7 +350,7 @@ AquaSalInstance::AquaSalInstance() + { + mpSalYieldMutex = new SalYieldMutex; + mpSalYieldMutex->acquire(); +- ::tools::SolarMutex::SetSolarMutex( mpSalYieldMutex ); ++ ::comphelper::SolarMutex::setSolarMutex( mpSalYieldMutex ); + maMainThread = osl::Thread::getCurrentIdentifier(); + mbWaitingYield = false; + maUserEventListMutex = osl_createMutex(); +@@ -360,7 +360,7 @@ AquaSalInstance::AquaSalInstance() + + AquaSalInstance::~AquaSalInstance() + { +- ::tools::SolarMutex::SetSolarMutex( 0 ); ++ ::comphelper::SolarMutex::setSolarMutex( 0 ); + mpSalYieldMutex->release(); + delete mpSalYieldMutex; + osl_destroyMutex( maUserEventListMutex ); +diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx +index 27af73f..4f3a289 100644 +--- a/vcl/win/source/app/salinst.cxx ++++ b/vcl/win/source/app/salinst.cxx +@@ -24,8 +24,6 @@ + #include + #include + +-#include +- + #include + #include + #include +@@ -580,12 +578,12 @@ WinSalInstance::WinSalInstance() + mpSalWaitMutex = new osl::Mutex; + mnYieldWaitCount = 0; + mpSalYieldMutex->acquire(); +- ::tools::SolarMutex::SetSolarMutex( mpSalYieldMutex ); ++ ::comphelper::SolarMutex::setSolarMutex( mpSalYieldMutex ); + } + + WinSalInstance::~WinSalInstance() + { +- ::tools::SolarMutex::SetSolarMutex( 0 ); ++ ::comphelper::SolarMutex::setSolarMutex( 0 ); + mpSalYieldMutex->release(); + delete mpSalYieldMutex; + delete mpSalWaitMutex; +-- +2.9.3 + diff --git a/SOURCES/0001-Pasting-from-a-pdf-from-a-fallback-font-doesn-t-give.patch b/SOURCES/0001-Pasting-from-a-pdf-from-a-fallback-font-doesn-t-give.patch new file mode 100644 index 0000000..e639609 --- /dev/null +++ b/SOURCES/0001-Pasting-from-a-pdf-from-a-fallback-font-doesn-t-give.patch @@ -0,0 +1,39 @@ +From 924126df792915092ee6201d1f068e43ffb80b67 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 24 Apr 2016 21:24:41 +0100 +Subject: [PATCH] Pasting -- from a pdf from a fallback font doesn't give -- as + output + +Type -- into a writer document, on a machine without Courier installed +set that text to Courier. Export to pdf, select inside e.g. evince and +paste to a terminal. You don't get -- + +0x2D is mapped from unicode 0x2D and unicode 0xAD in the adobe +encoding. So the latter trumps the earlier one and is pasted +instead of <2D2D>. + +Reverse the order that the encoding is mapped from unicode so lower +more "ascii" options are preferred over the higher more "unlikely" +unicode options + +Change-Id: I8f251253fca468d269493801e668617a935ee15d +--- + vcl/source/gdi/pdfwriter_impl.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx +index ee9b0df..4ee0366 100644 +--- a/vcl/source/gdi/pdfwriter_impl.cxx ++++ b/vcl/source/gdi/pdfwriter_impl.cxx +@@ -3096,7 +3096,7 @@ std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitEmbeddedFont( const Physical + memset( nEncodedCodes, 0, sizeof(nEncodedCodes) ); + memset( pUnicodesPerGlyph, 0, sizeof(pUnicodesPerGlyph) ); + memset( pEncToUnicodeIndex, 0, sizeof(pEncToUnicodeIndex) ); +- for( Ucs2SIntMap::const_iterator it = pEncoding->begin(); it != pEncoding->end(); ++it ) ++ for( Ucs2SIntMap::const_reverse_iterator it = pEncoding->rbegin(); it != pEncoding->rend(); ++it ) + { + if(it->second == -1) + continue; +-- +2.7.3 + diff --git a/SOURCES/0001-Related-rhbz-1281906-set-a-min-size-on-un-resizeable.patch b/SOURCES/0001-Related-rhbz-1281906-set-a-min-size-on-un-resizeable.patch new file mode 100644 index 0000000..d216231 --- /dev/null +++ b/SOURCES/0001-Related-rhbz-1281906-set-a-min-size-on-un-resizeable.patch @@ -0,0 +1,35 @@ +From afeddaf7e0d11ad9b1df0c80bcc3f50caa87e21a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 16 Dec 2015 10:46:10 +0000 +Subject: [PATCH] Related: rhbz#1281906 set a min size on un-resizeable + non-layout dialogs + +a min size equates to a size-request which is reliable under gtk3+wayland +as the dialog contents size. + +a default size equates to the size of the dialog, which includes decorations +under wayland + +Change-Id: I20baf00fb5952ab93628f4dd6891779ce682783c +--- + vcl/source/window/syswin.cxx | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx +index 8589db6..3f2cde1 100644 +--- a/vcl/source/window/syswin.cxx ++++ b/vcl/source/window/syswin.cxx +@@ -1135,6 +1135,10 @@ void SystemWindow::DoInitialLayout() + mbIsCalculatingInitialLayoutSize = false; + mbInitialLayoutDone = true; + } ++ else if (!(GetStyle() & WB_SIZEABLE)) ++ { ++ SetMinOutputSizePixel(GetSizePixel()); ++ } + } + + void SystemWindow::doDeferredInit(WinBits /*nBits*/) +-- +2.5.0 + diff --git a/SOURCES/0001-Related-rhbz-1281906-wayland-toolbar-drawn-over-menu.patch b/SOURCES/0001-Related-rhbz-1281906-wayland-toolbar-drawn-over-menu.patch new file mode 100644 index 0000000..28bae4b --- /dev/null +++ b/SOURCES/0001-Related-rhbz-1281906-wayland-toolbar-drawn-over-menu.patch @@ -0,0 +1,319 @@ +From 2e071f6dd64561ae173b903a76065e2fab48a266 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 24 Jul 2015 12:22:14 +0100 +Subject: [PATCH] Related: rhbz#1281906 wayland toolbar drawn over menus etc + +gtk3: draw/paint to the fixed container + +which fills the toplevel window, rather than directly to the toplevel window. + +It makes no difference for X, but for wayland the window decorations are part +of the toplevel window, dropping down a level means we don't draw out menu bar +under the window decoration space + +(cherry picked from commit 298c089df77d9afe2cf86bb7a6a8544a0151e8c5) + +Change-Id: Icec400efacd16b5d901107c13b6fa90c59cad0e6 + +gtk3: insert an event box between toplevel and contents + +Change-Id: Ic78aa62baaa4260645a80ffb6704103440339595 +(cherry picked from commit 2796d7f1723d5b45177fe6da7a6e66cb914ae6d2) + +gtk3: connect to the eventbox and not toplevel for mouse events + +this leaves whatever magic gtk3 under wayland is doing on the toplevel +alone so the window can be resized and the title bar responds to +clicks as expected + +Change-Id: I9952cb719f3148660e17951b4f66a2525e11a6df +(cherry picked from commit 10d2467c2532178efe3d672405839bc1d0aab1e5) + +attach gestures to event widget instead of toplevel + +Change-Id: Id0658cf561570a2ae15fb7fd603e6437da9cfaf2 +(cherry picked from commit 848f685ae8f614ad62d205ef628f259cafb738b3) +--- + vcl/inc/unx/gtk/gtkframe.hxx | 5 +- + vcl/unx/gtk/a11y/atkfactory.cxx | 21 +++++++-- + vcl/unx/gtk/window/gtksalframe.cxx | 93 +++++++++++++++++++++++++++----------- + 3 files changed, 88 insertions(+), 31 deletions(-) + +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index 604f2a6..3531c41 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -173,6 +173,8 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + + SalX11Screen m_nXScreen; + GtkWidget* m_pWindow; ++ GtkEventBox* m_pEventBox; ++ GtkFixed* m_pFixedContainer; + GdkWindow* m_pForeignParent; + GdkNativeWindow m_aForeignParentWindow; + GdkWindow* m_pForeignTopLevel; +@@ -180,7 +182,6 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + Pixmap m_hBackgroundPixmap; + sal_uLong m_nStyle; + SalExtStyle m_nExtStyle; +- GtkFixed* m_pFixedContainer; + GtkSalFrame* m_pParent; + std::list< GtkSalFrame* > m_aChildren; + GdkWindowState m_nState; +@@ -335,6 +336,7 @@ public: + guint m_nActionGroupExportId; + guint m_nAppActionGroupExportId; + guint m_nHudAwarenessId; ++ std::vector m_aMouseSignalIds; + + // dispatches an event, returns true if dispatched + // and false else; if true was returned the event should +@@ -347,6 +349,7 @@ public: + static GdkDisplay* getGdkDisplay(); + GtkWidget* getWindow() const { return m_pWindow; } + GtkFixed* getFixedContainer() const { return m_pFixedContainer; } ++ GtkWidget* getMouseEventWidget() const; + GdkWindow* getForeignParent() const { return m_pForeignParent; } + GdkNativeWindow getForeignParentWindow() const { return m_aForeignParentWindow; } + GdkWindow* getForeignTopLevel() const { return m_pForeignTopLevel; } +diff --git a/vcl/unx/gtk/a11y/atkfactory.cxx b/vcl/unx/gtk/a11y/atkfactory.cxx +index 99ed750..9edc7ab 100644 +--- a/vcl/unx/gtk/a11y/atkfactory.cxx ++++ b/vcl/unx/gtk/a11y/atkfactory.cxx +@@ -101,14 +101,27 @@ wrapper_factory_get_accessible_type() + static AtkObject* + wrapper_factory_create_accessible( GObject *obj ) + { +- GtkWidget* parent_widget = gtk_widget_get_parent( GTK_WIDGET( obj ) ); ++#if GTK_CHECK_VERSION(3,0,0) ++ GtkWidget* pEventBox = gtk_widget_get_parent(GTK_WIDGET(obj)); + + // gail_container_real_remove_gtk tries to re-instanciate an accessible + // for a widget that is about to vanish .. +- if( ! parent_widget ) ++ if (!pEventBox) + return atk_noop_object_wrapper_new(); + +- GtkSalFrame* pFrame = GtkSalFrame::getFromWindow( GTK_WINDOW( parent_widget ) ); ++ GtkWidget* pTopLevel = gtk_widget_get_parent(pEventBox); ++ if (!pTopLevel) ++ return atk_noop_object_wrapper_new(); ++#else ++ GtkWidget* pTopLevel = gtk_widget_get_parent(GTK_WIDGET(obj)); ++ ++ // gail_container_real_remove_gtk tries to re-instanciate an accessible ++ // for a widget that is about to vanish .. ++ if (!pTopLevel) ++ return atk_noop_object_wrapper_new(); ++#endif ++ ++ GtkSalFrame* pFrame = GtkSalFrame::getFromWindow(GTK_WINDOW(pTopLevel)); + g_return_val_if_fail( pFrame != NULL, NULL ); + + vcl::Window* pFrameWindow = pFrame->GetWindow(); +@@ -130,7 +143,7 @@ wrapper_factory_create_accessible( GObject *obj ) + if( accessible ) + g_object_ref( G_OBJECT(accessible) ); + else +- accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(parent_widget) ); ++ accessible = atk_object_wrapper_new( xAccessible, gtk_widget_get_accessible(pTopLevel) ); + + return accessible; + } +diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx +index eef48cd..8acdf8a 100644 +--- a/vcl/unx/gtk/window/gtksalframe.cxx ++++ b/vcl/unx/gtk/window/gtksalframe.cxx +@@ -414,7 +414,7 @@ void GtkSalFrame::doKeyCallback( guint state, + if (keyval == GDK_0) + { + fprintf( stderr, "force widget_queue_draw\n"); +- gtk_widget_queue_draw (m_pWindow); ++ gtk_widget_queue_draw (m_pFixedContainer); + return; + } + else if (keyval == GDK_1) +@@ -894,8 +894,13 @@ GtkSalFrame::~GtkSalFrame() + if( m_pIMHandler ) + delete m_pIMHandler; + ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ for (auto handler_id : m_aMouseSignalIds) ++ g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); + if( m_pFixedContainer ) + gtk_widget_destroy( GTK_WIDGET( m_pFixedContainer ) ); ++ if( m_pEventBox ) ++ gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); + { + SolarMutexGuard aGuard; + #if defined ENABLE_GMENU_INTEGRATION +@@ -1036,38 +1041,75 @@ void GtkSalFrame::updateScreenNumber() + maGeometry.nDisplayScreenNumber = nScreen; + } + ++GtkWidget *GtkSalFrame::getMouseEventWidget() const ++{ ++#if GTK_CHECK_VERSION(3,0,0) ++ return GTK_WIDGET(m_pEventBox); ++#else ++ return m_pWindow; ++#endif ++} ++ + void GtkSalFrame::InitCommon() + { ++#if GTK_CHECK_VERSION(3,0,0) ++ m_pEventBox = GTK_EVENT_BOX(gtk_event_box_new()); ++ gtk_widget_add_events( GTK_WIDGET(m_pEventBox), ++ GDK_ALL_EVENTS_MASK ); ++ gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pEventBox) ); ++ ++ // add the fixed container child, ++ // fixed is needed since we have to position plugin windows ++ m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); ++ gtk_container_add( GTK_CONTAINER(m_pEventBox), GTK_WIDGET(m_pFixedContainer) ); ++#else ++ m_pEventBox = 0; ++ // add the fixed container child, ++ // fixed is needed since we have to position plugin windows ++ m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); ++ gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) ); ++#endif ++ ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ ++ gtk_widget_set_app_paintable(GTK_WIDGET(m_pFixedContainer), true); ++ /*non-X11 displays won't show anything at all without double-buffering ++ enabled*/ ++ if (GDK_IS_X11_DISPLAY(getGdkDisplay())) ++ gtk_widget_set_double_buffered(GTK_WIDGET(m_pFixedContainer), false); ++ gtk_widget_set_redraw_on_allocate(GTK_WIDGET(m_pFixedContainer), false); ++ ++ + // connect signals + g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "button-press-event", G_CALLBACK(signalButton), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "button-release-event", G_CALLBACK(signalButton), this ); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-press-event", G_CALLBACK(signalButton), this )); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this )); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this )); + #if GTK_CHECK_VERSION(3,0,0) +- g_signal_connect( G_OBJECT(m_pWindow), "draw", G_CALLBACK(signalDraw), this ); ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "draw", G_CALLBACK(signalDraw), this ); + g_signal_connect( G_OBJECT(m_pWindow), "size-allocate", G_CALLBACK(sizeAllocated), this ); + // g_signal_connect( G_OBJECT(m_pWindow), "state-flags-changed", G_CALLBACK(signalFlagsChanged), this ); + #if GTK_CHECK_VERSION(3,14,0) +- GtkGesture *pSwipe = gtk_gesture_swipe_new(m_pWindow); ++ GtkGesture *pSwipe = gtk_gesture_swipe_new(pEventWidget); + g_signal_connect(pSwipe, "swipe", G_CALLBACK(gestureSwipe), this); + gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pSwipe), GTK_PHASE_TARGET); +- g_object_weak_ref(G_OBJECT(m_pWindow), reinterpret_cast(g_object_unref), pSwipe); ++ g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pSwipe); + +- GtkGesture *pLongPress = gtk_gesture_long_press_new(m_pWindow); ++ GtkGesture *pLongPress = gtk_gesture_long_press_new(pEventWidget); + g_signal_connect(pLongPress, "pressed", G_CALLBACK(gestureLongPress), this); + gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pLongPress), GTK_PHASE_TARGET); +- g_object_weak_ref(G_OBJECT(m_pWindow), reinterpret_cast(g_object_unref), pLongPress); ++ g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pLongPress); + + #endif + + #else +- g_signal_connect( G_OBJECT(m_pWindow), "expose-event", G_CALLBACK(signalExpose), this ); ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "expose-event", G_CALLBACK(signalExpose), this ); + #endif + g_signal_connect( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this ); + g_signal_connect( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this ); + g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this ); + g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this ); + g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "motion-notify-event", G_CALLBACK(signalMotion), this ); + g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this ); + g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); + g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this ); +@@ -1102,26 +1144,18 @@ void GtkSalFrame::InitCommon() + m_nAppActionGroupExportId = 0; + m_nHudAwarenessId = 0; + +- gtk_widget_set_app_paintable( m_pWindow, TRUE ); +- /*non-X11 displays won't show anything at all without double-buffering +- enabled*/ +- if (GDK_IS_X11_DISPLAY(getGdkDisplay())) +- gtk_widget_set_double_buffered( m_pWindow, FALSE ); +- gtk_widget_set_redraw_on_allocate( m_pWindow, FALSE ); +- + gtk_widget_add_events( m_pWindow, + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | + GDK_VISIBILITY_NOTIFY_MASK | GDK_SCROLL_MASK + ); + +- // add the fixed container child, +- // fixed is needed since we have to position plugin windows +- m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); +- gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) ); +- + // show the widgets +- gtk_widget_show( GTK_WIDGET(m_pFixedContainer) ); ++#if GTK_CHECK_VERSION(3,0,0) ++ gtk_widget_show_all( GTK_WIDGET(m_pEventBox) ); ++#else ++ gtk_widget_show_all( GTK_WIDGET(m_pFixedContainer) ); ++#endif + + // realize the window, we need an XWindow id + gtk_widget_realize( m_pWindow ); +@@ -2780,7 +2814,7 @@ void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents ) + GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay()); + GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager); + if (bGrab) +- gdk_device_grab(pPointer, widget_get_window(m_pWindow), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, GDK_CURRENT_TIME); ++ gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, GDK_CURRENT_TIME); + else + gdk_device_ungrab(pPointer, GDK_CURRENT_TIME); + #else +@@ -3189,8 +3223,14 @@ void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Scre + { + gdk_region_destroy( m_pRegion ); + } ++ ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ for (auto handler_id : m_aMouseSignalIds) ++ g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); + if( m_pFixedContainer ) + gtk_widget_destroy( GTK_WIDGET(m_pFixedContainer) ); ++ if( m_pEventBox ) ++ gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); + if( m_pWindow ) + gtk_widget_destroy( m_pWindow ); + if( m_pForeignParent ) +@@ -3651,7 +3691,7 @@ void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect) + cairo_destroy(cr); + } + +- gtk_widget_queue_draw_area(m_pWindow, ++ gtk_widget_queue_draw_area(GTK_WIDGET(m_pFixedContainer), + rDamageRect.getMinX(), + rDamageRect.getMinY(), + rDamageRect.getWidth(), +@@ -3874,7 +3914,7 @@ void GtkSalFrame::TriggerPaintEvent() + SAL_INFO("vcl.gtk3", "force painting" << 0 << "," << 0 << " " << maGeometry.nWidth << "x" << maGeometry.nHeight); + SalPaintEvent aPaintEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight, true); + CallCallback(SALEVENT_PAINT, &aPaintEvt); +- gtk_widget_queue_draw(m_pWindow); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pFixedContainer)); + #endif + } + +@@ -4212,6 +4252,7 @@ void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame ) + if( pObj == pThis->m_pWindow ) + { + pThis->m_pFixedContainer = NULL; ++ pThis->m_pEventBox = NULL; + pThis->m_pWindow = NULL; + pThis->InvalidateGraphics(); + } +-- +2.5.0 + diff --git a/SOURCES/0001-Related-rhbz-1290014-gtk3-use-gtk_window_set_modal-o.patch b/SOURCES/0001-Related-rhbz-1290014-gtk3-use-gtk_window_set_modal-o.patch new file mode 100644 index 0000000..421bcbb --- /dev/null +++ b/SOURCES/0001-Related-rhbz-1290014-gtk3-use-gtk_window_set_modal-o.patch @@ -0,0 +1,107 @@ +From 8a30dab4e78b42cf3ce587965414b98a50830a78 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 14 Dec 2015 11:36:50 +0000 +Subject: [PATCH 1/2] Related: rhbz#1290014 gtk3: use gtk_window_set_modal on + modal dialogs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +which makes modal dialogs (which are most of them) place correctly +under wayland. Modeless ones are still uselessly shoved far to the +left, but this makes things near usable and gives the same "graying +into the bg" effect for the main window as other gtk apps + +Change-Id: If1486feb7631c5a0c2aa6efac3a6b9dd1b215daf +Reviewed-on: https://gerrit.libreoffice.org/20699 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 8d5822983e9b6a1e04874ce4d2c807fd0cf1ee04) +Reviewed-on: https://gerrit.libreoffice.org/20700 +--- + vcl/inc/salframe.hxx | 4 ++++ + vcl/inc/unx/gtk/gtkframe.hxx | 4 ++++ + vcl/source/window/dialog.cxx | 3 ++- + vcl/unx/gtk3/gtk3gtkframe.cxx | 7 +++++++ + 4 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx +index 4e52fe4..484504c 100644 +--- a/vcl/inc/salframe.hxx ++++ b/vcl/inc/salframe.hxx +@@ -233,6 +233,10 @@ public: + // done setting up the clipregion + virtual void EndSetClipRegion() = 0; + ++ virtual void SetModal(bool /*bModal*/) ++ { ++ } ++ + // Callbacks (indepent part in vcl/source/window/winproc.cxx) + // for default message handling return 0 + void SetCallback( vcl::Window* pWindow, SALFRAMEPROC pProc ); +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index 3bd5353..ee19e6c 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -465,6 +465,10 @@ public: + // done setting up the clipregion + virtual void EndSetClipRegion() SAL_OVERRIDE; + ++#if GTK_CHECK_VERSION(3,0,0) ++ virtual void SetModal(bool bModal) override; ++#endif ++ + static GtkSalFrame *getFromWindow( GtkWindow *pWindow ); + + virtual Window GetX11Window() SAL_OVERRIDE; +diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx +index 4ce15de..cd1f0da 100644 +--- a/vcl/source/window/dialog.cxx ++++ b/vcl/source/window/dialog.cxx +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + #include + +@@ -1001,7 +1002,6 @@ void Dialog::SetModalInputMode( bool bModal ) + mpDialogParent = pParent->mpWindowImpl->mpFrameWindow; + mpDialogParent->ImplIncModalCount(); + } +- + } + else + { +@@ -1037,6 +1037,7 @@ void Dialog::SetModalInputMode( bool bModal ) + } + } + } ++ ImplGetFrame()->SetModal(bModal); + } + + void Dialog::SetModalInputMode( bool bModal, bool bSubModalDialogs ) +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index 1443054..ca9d371 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -2616,6 +2616,13 @@ void GtkSalFrame::EndSetClipRegion() + gdk_window_shape_combine_region( widget_get_window(m_pWindow), m_pRegion, 0, 0 ); + } + ++void GtkSalFrame::SetModal(bool bModal) ++{ ++ if (!m_pWindow) ++ return; ++ gtk_window_set_modal(GTK_WINDOW(m_pWindow), bModal); ++} ++ + gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) + { + GtkSalFrame* pThis = static_cast(frame); +-- +2.5.0 + diff --git a/SOURCES/0001-Related-tdf-72880-presumably-using-startcenter-as-ge.patch b/SOURCES/0001-Related-tdf-72880-presumably-using-startcenter-as-ge.patch new file mode 100644 index 0000000..17ab102 --- /dev/null +++ b/SOURCES/0001-Related-tdf-72880-presumably-using-startcenter-as-ge.patch @@ -0,0 +1,29 @@ +From ac33ef3a4abe73c65600e1f199d25e1a1f0080db Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 8 Oct 2015 12:38:06 +0100 +Subject: [PATCH] Related: tdf#72880 presumably using startcenter as generic LO + target will work + +for the gnome case + +Change-Id: Icb5ad2d50d672b35783720c100a408fa3e5cb63e +--- + sysui/desktop/menus/startcenter.desktop | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysui/desktop/menus/startcenter.desktop b/sysui/desktop/menus/startcenter.desktop +index ed333b6..f0d2b63 100644 +--- a/sysui/desktop/menus/startcenter.desktop ++++ b/sysui/desktop/menus/startcenter.desktop +@@ -23,7 +23,7 @@ Icon=startcenter + Type=Application + Categories=Office;X-Red-Hat-Base;X-SuSE-Core-Office;X-MandrivaLinux-Office-Other; + Exec=${UNIXBASISROOTNAME} %%FILE%% +-MimeType=application/vnd.openofficeorg.extension; ++MimeType=application/vnd.openofficeorg.extension;x-scheme-handler/vnd.libreoffice.cmis; + Name=%PRODUCTNAME + GenericName=Office + Comment=The office productivity suite compatible to the open and standardized ODF document format. Supported by The Document Foundation. +-- +2.4.3 + diff --git a/SOURCES/0001-Related-tdf-93676-msword-wraps-slightly-differently-.patch b/SOURCES/0001-Related-tdf-93676-msword-wraps-slightly-differently-.patch new file mode 100644 index 0000000..2771111 --- /dev/null +++ b/SOURCES/0001-Related-tdf-93676-msword-wraps-slightly-differently-.patch @@ -0,0 +1,49 @@ +From 1ff5ecda9ccfcf3e65e90c404db93fcbbefb889e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 7 Sep 2015 16:37:22 +0100 +Subject: [PATCH] Related: tdf#93676 msword wraps slightly differently than us + +Change-Id: I91ba41cb052c38aa3b047cf079090b01bbe93b39 +--- + sw/source/filter/ww8/wrtw8esh.cxx | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx +index 763fb44..fd6dfbc 100644 +--- a/sw/source/filter/ww8/wrtw8esh.cxx ++++ b/sw/source/filter/ww8/wrtw8esh.cxx +@@ -803,6 +803,19 @@ void PlcDrawObj::WritePlc( WW8Export& rWrt ) const + + SwTwips nLeft = aRect.Left() + nThick; + SwTwips nRight = aRect.Right() - nThick; ++ SwTwips nTop = aRect.Top() + nThick; ++ SwTwips nBottom = aRect.Bottom() - nThick; ++ ++ // tdf#93675, 0 below line/paragraph and/or top line/paragraph with ++ // wrap top+bottom or other wraps is affecting the line directly ++ // above the anchor line, which seems odd, but a tiny adjustment ++ // here to bring the top down convinces msoffice to wrap like us ++ if (nTop < 8 && !rFrameFormat.IsInline() && ++ rVOr.GetVertOrient() == text::VertOrientation::NONE && ++ rVOr.GetRelationOrient() == text::RelOrientation::FRAME) ++ { ++ nTop = 8; ++ } + + //Nasty swap for bidi if necessary + rWrt.MiserableRTLFrameFormatHack(nLeft, nRight, rFrameFormat); +@@ -811,9 +824,9 @@ void PlcDrawObj::WritePlc( WW8Export& rWrt ) const + //(most of) the border is outside the graphic is word, so + //change dimensions to fit + SwWW8Writer::WriteLong(*rWrt.pTableStrm, nLeft); +- SwWW8Writer::WriteLong(*rWrt.pTableStrm,aRect.Top() + nThick); ++ SwWW8Writer::WriteLong(*rWrt.pTableStrm, nTop); + SwWW8Writer::WriteLong(*rWrt.pTableStrm, nRight); +- SwWW8Writer::WriteLong(*rWrt.pTableStrm,aRect.Bottom() - nThick); ++ SwWW8Writer::WriteLong(*rWrt.pTableStrm, nBottom); + + //fHdr/bx/by/wr/wrk/fRcaSimple/fBelowText/fAnchorLock + sal_uInt16 nFlags=0; +-- +2.1.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1035092-no-shortcut-key-for-Italian-To.patch b/SOURCES/0001-Resolves-rhbz-1035092-no-shortcut-key-for-Italian-To.patch new file mode 100644 index 0000000..417e7d4 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1035092-no-shortcut-key-for-Italian-To.patch @@ -0,0 +1,27 @@ +From eaf5194e57a9a6b82672a019c8db30c9a67ff21a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 27 Nov 2013 11:20:04 +0000 +Subject: [PATCH] Resolves: rhbz#1035092 no shortcut key for Italian 'Tools' + menu + +Change-Id: I2f8867e7d4b9c7884d1d3af4f34a93fa5da08b47 +--- + source/it/officecfg/registry/data/org/openoffice/Office/UI.po | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source/it/officecfg/registry/data/org/openoffice/Office/UI.po b/source/it/officecfg/registry/data/org/openoffice/Office/UI.po +index ea1ff2f..97dc332 100644 +--- a/translations/source/it/officecfg/registry/data/org/openoffice/Office/UI.po ++++ b/translations/source/it/officecfg/registry/data/org/openoffice/Office/UI.po +@@ -18673,7 +18673,7 @@ msgctxt "" + "Label\n" + "value.text" + msgid "~Tools" +-msgstr "Strumenti" ++msgstr "~Strumenti" + + #: GenericCommands.xcu + msgctxt "" +-- +1.8.3.1 + diff --git a/SOURCES/0001-Resolves-rhbz-1256843-no-obvious-means-to-close-temp.patch b/SOURCES/0001-Resolves-rhbz-1256843-no-obvious-means-to-close-temp.patch new file mode 100644 index 0000000..2f2e11c --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1256843-no-obvious-means-to-close-temp.patch @@ -0,0 +1,786 @@ +From c33062fc07ac20b1ac28bd000fd3c57016d72e34 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 1 Sep 2015 11:59:32 +0100 +Subject: [PATCH] Resolves: rhbz#1256843 no obvious means to close template + dialog + +under gnome-shell which doesn't put an "X" to close things in +the wm decorations if the GDK DIALOG hint it set + +prior to tdf#72587 this was a modeless dialog and in that case +it doesn't have a parent, in which case the hint is NORMAL +and it used to get close decorations. + +easist thing to do is to remain modal so the crashes and +confusion of tdf#72587 remain fixed but add a close to it to +behave like all the other dialogs do + +Change-Id: I64450be0ad1bc7b06196e1342679e15b60fc60d9 +--- + sfx2/uiconfig/ui/templatedlg.ui | 653 +++++++++++++++++++++------------------- + 1 file changed, 346 insertions(+), 307 deletions(-) + +diff --git a/sfx2/uiconfig/ui/templatedlg.ui b/sfx2/uiconfig/ui/templatedlg.ui +index de8270c..6ed0172 100644 +--- a/sfx2/uiconfig/ui/templatedlg.ui ++++ b/sfx2/uiconfig/ui/templatedlg.ui +@@ -1,111 +1,327 @@ + + + +- ++ + +- ++ + 800 +- 560 ++ 600 + False +- True + 6 + Template Manager +- +- +- True ++ True ++ normal ++ ++ + False +- 6 + vertical ++ 2 ++ ++ ++ False ++ end ++ ++ ++ gtk-close ++ True ++ True ++ True ++ True ++ True ++ True ++ ++ ++ True ++ True ++ 0 ++ ++ ++ ++ ++ False ++ False ++ 1 ++ ++ + +- ++ + True +- True +- True +- True ++ False ++ vertical + +- ++ + True +- False ++ True + True + True +- vertical +- 6 + +- ++ + True + False + True ++ True ++ vertical + 6 + +- ++ + True + False + True ++ 6 + +- ++ + True + False +- repository +- Repository +- True +- sfx2/imglst/actionview026.png +- +- +- False +- True +- +- +- +- +- False +- import +- Import +- True +- sfx2/imglst/actionview010.png +- +- +- False +- True +- +- +- +- +- False +- delete +- Delete +- True +- sfx2/imglst/actionview025.png ++ True ++ ++ ++ True ++ False ++ repository ++ Repository ++ True ++ sfx2/imglst/actionview026.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ import ++ Import ++ True ++ sfx2/imglst/actionview010.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ delete ++ Delete ++ True ++ sfx2/imglst/actionview025.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ False ++ save ++ Save ++ True ++ sfx2/imglst/actionview028.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ new_folder ++ New Folder ++ True ++ sfx2/imglst/actionview029.png ++ ++ ++ False ++ True ++ ++ + + + False +- True ++ True ++ 0 + + + +- ++ + False +- save +- Save +- True +- sfx2/imglst/actionview028.png ++ True ++ ++ ++ False ++ template_save ++ Save ++ True ++ sfx2/imglst/actionview028.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ open ++ Open ++ True ++ sfx2/imglst/actionview030.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ edit ++ Edit ++ True ++ sfx2/imglst/actiontemplates019.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ properties ++ Properties ++ True ++ sfx2/imglst/actiontemplates016.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ default ++ Set as Default ++ True ++ sfx2/imglst/actiontemplates015.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ move ++ Move to Folder ++ True ++ sfx2/imglst/actiontemplates017.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ export ++ Export ++ True ++ sfx2/imglst/actiontemplates020.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ template_delete ++ Delete ++ True ++ sfx2/imglst/actiontemplates018.png ++ ++ ++ False ++ True ++ ++ + + + False +- True ++ True ++ 1 + + + +- ++ + True + False +- new_folder +- New Folder +- True +- sfx2/imglst/actionview029.png ++ end ++ True ++ ++ ++ True ++ False ++ search ++ Search ++ True ++ sfx2/imglst/actionaction012.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ action_menu ++ Action Menu ++ True ++ sfx2/imglst/actionaction013.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ template_link ++ Get more templates for %PRODUCTNAME ++ True ++ sfx2/imglst/actionview010.png ++ ++ ++ False ++ True ++ ++ + + + False +- True ++ True ++ 2 + + + +@@ -116,120 +332,10 @@ + + + +- +- False ++ ++ True + True +- +- +- False +- template_save +- Save +- True +- sfx2/imglst/actionview028.png +- +- +- False +- True +- +- +- +- +- True +- False +- open +- Open +- True +- sfx2/imglst/actionview030.png +- +- +- False +- True +- +- +- +- +- True +- False +- edit +- Edit +- True +- sfx2/imglst/actiontemplates019.png +- +- +- False +- True +- +- +- +- +- True +- False +- properties +- Properties +- True +- sfx2/imglst/actiontemplates016.png +- +- +- False +- True +- +- +- +- +- True +- False +- default +- Set as Default +- True +- sfx2/imglst/actiontemplates015.png +- +- +- False +- True +- +- +- +- +- True +- False +- move +- Move to Folder +- True +- sfx2/imglst/actiontemplates017.png +- +- +- False +- True +- +- +- +- +- True +- False +- export +- Export +- True +- sfx2/imglst/actiontemplates020.png +- +- +- False +- True +- +- +- +- +- True +- False +- template_delete +- Delete +- True +- sfx2/imglst/actiontemplates018.png +- +- +- False +- True +- +- ++ + + + False +@@ -238,53 +344,11 @@ + + + +- ++ + True + False +- end + True +- +- +- True +- False +- search +- Search +- True +- sfx2/imglst/actionaction012.png +- +- +- False +- True +- +- +- +- +- True +- False +- action_menu +- Action Menu +- True +- sfx2/imglst/actionaction013.png +- +- +- False +- True +- +- +- +- +- True +- False +- template_link +- Get more templates for %PRODUCTNAME +- True +- sfx2/imglst/actionview010.png +- +- +- False +- True +- +- ++ True + + + False +@@ -292,123 +356,98 @@ + 2 + + ++ ++ ++ True ++ True ++ 0 ++ True ++ True ++ ++ ++ False ++ True ++ 3 ++ ++ ++ ++ ++ True ++ True ++ 0 ++ True ++ True ++ ++ ++ False ++ True ++ 4 ++ ++ ++ ++ ++ ++ ++ True ++ False ++ Documents + + +- False +- True +- 0 ++ False + + + +- +- True +- True +- ++ ++ ++ ++ ++ True ++ False ++ Spreadsheets + + +- False +- True + 1 ++ False + + + +- ++ ++ ++ ++ + True +- True +- True +- True ++ False ++ Presentations + + +- False +- True + 2 ++ False + + + +- +- True +- True +- 0 +- True +- True +- +- +- False +- True +- 3 +- ++ + +- +- +- True +- True +- 0 +- True +- True ++ ++ ++ True ++ False ++ Drawings + + +- False +- True +- 4 ++ 3 ++ False + + + +- +- +- +- True +- False +- Documents +- + +- False +- +- +- +- +- +- +- +- True +- False +- Spreadsheets +- +- +- 1 +- False +- +- +- +- +- +- +- +- True +- False +- Presentations +- +- +- 2 +- False +- +- +- +- +- +- +- +- True +- False +- Drawings +- +- +- 3 +- False ++ False ++ True ++ 0 + + + + +- False ++ True + True + 0 + +-- +2.4.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1285380-get-menus-working-under-waylan.patch b/SOURCES/0001-Resolves-rhbz-1285380-get-menus-working-under-waylan.patch new file mode 100644 index 0000000..83a0e95 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1285380-get-menus-working-under-waylan.patch @@ -0,0 +1,60 @@ +From c46d05caf360cfb43215e15d466016728d021c15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 30 Nov 2015 14:03:34 +0000 +Subject: [PATCH] Resolves: rhbz#1285380 get menus working under wayland + +use GDK_WINDOW_TYPE_HINT_POPUP_MENU hint for menus + +and set hints after widget is realized + +and set gtk_window_set_transient_for menus too + +then you get menus and tooltips apparently in the right place + +Change-Id: Ib1046fb0872b9d8a5f80cc5f48828ef7f086b1a1 +--- + vcl/unx/gtk/window/gtksalframe.cxx | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx +index 8acdf8a..0053e5b 100644 +--- a/vcl/unx/gtk/window/gtksalframe.cxx ++++ b/vcl/unx/gtk/window/gtksalframe.cxx +@@ -1401,6 +1401,15 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + if( m_pParent && m_pParent->m_pWindow && ! isChild() ) + gtk_window_set_screen( GTK_WINDOW(m_pWindow), gtk_window_get_screen( GTK_WINDOW(m_pParent->m_pWindow) ) ); + ++ if (m_pParent) ++ { ++ if (!(m_pParent->m_nStyle & SAL_FRAME_STYLE_PLUG)) ++ gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) ); ++ m_pParent->m_aChildren.push_back( this ); ++ } ++ ++ InitCommon(); ++ + // set window type + bool bDecoHandling = + ! isChild() && +@@ -1441,17 +1450,11 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + #endif + gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); + gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); +- if( m_pParent && ! (m_pParent->m_nStyle & SAL_FRAME_STYLE_PLUG) ) +- gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) ); + } + else if( (nStyle & SAL_FRAME_STYLE_FLOAT) ) + { +- gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_UTILITY ); ++ gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_POPUP_MENU ); + } +- if( m_pParent ) +- m_pParent->m_aChildren.push_back( this ); +- +- InitCommon(); + + #if !GTK_CHECK_VERSION(3,0,0) + if( eWinType == GTK_WINDOW_TOPLEVEL ) +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1287581-explicitly-state-we-don-t-want.patch b/SOURCES/0001-Resolves-rhbz-1287581-explicitly-state-we-don-t-want.patch new file mode 100644 index 0000000..074ff16 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1287581-explicitly-state-we-don-t-want.patch @@ -0,0 +1,26 @@ +From 991b9c32e98a924d659dc94923d9e85c8955d17a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 15 Dec 2015 13:47:39 +0000 +Subject: [PATCH] Resolves: rhbz#1287581 explicitly state we don't want + decorated toolbars + +Change-Id: Ibbf45b44eba9f5f65db0e7ae26cf6946b32f879d +--- + vcl/unx/gtk3/gtk3gtkframe.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index 592c872..7c24d2b 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -1180,6 +1180,7 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + { + eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; + gtk_window_set_accept_focus(GTK_WINDOW(m_pWindow), false); ++ gtk_window_set_decorated(GTK_WINDOW(m_pWindow), false); + } + else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) + { +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1289394-gtk3-implement-tooltips-native.patch b/SOURCES/0001-Resolves-rhbz-1289394-gtk3-implement-tooltips-native.patch new file mode 100644 index 0000000..f787102 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1289394-gtk3-implement-tooltips-native.patch @@ -0,0 +1,469 @@ +From ee49f01f73348c9e7c822212a7ed69ab2e916946 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 14 Dec 2015 14:05:53 +0000 +Subject: [PATCH] Resolves: rhbz#1289394 gtk3: implement tooltips natively + +side step the whole pile of misery by using native gtk tooltips + +also gets transparency and native themeing too by default + +Related: rhbz#1289394 always provide the screen area the tip applies to + +this will make it easier to implement native help tips + +Change-Id: I984dfadaf02e9b7bf542ba82cf070911c89cb699 +(cherry picked from commit 01ef12d173fb2c54a49186c8eb4fa40288b82945) + +Change-Id: I59552661cd9dc18a563341885bc40fcdadc5264f +(cherry picked from commit c96eeb5bf2ef428e7d147258d69825ff97acb226) +--- + cui/source/customize/acccfg.cxx | 2 +- + cui/source/customize/selector.cxx | 10 +++-- + include/vcl/help.hxx | 3 -- + sfx2/source/dialog/dinfdlg.cxx | 2 +- + sw/source/core/draw/dpage.cxx | 6 +-- + sw/source/uibase/docvw/edtwin2.cxx | 17 +++++---- + vcl/inc/helpwin.hxx | 4 +- + vcl/inc/salframe.hxx | 7 ++++ + vcl/inc/unx/gtk/gtkframe.hxx | 6 +++ + vcl/source/app/help.cxx | 75 +++++++++++++++++--------------------- + vcl/source/window/menuwindow.cxx | 2 +- + vcl/source/window/window.cxx | 9 ++++- + vcl/unx/gtk3/gtk3gtkframe.cxx | 28 ++++++++++++++ + 13 files changed, 106 insertions(+), 65 deletions(-) + +diff --git a/cui/source/customize/acccfg.cxx b/cui/source/customize/acccfg.cxx +index b3511e9..2125990 100644 +--- a/cui/source/customize/acccfg.cxx ++++ b/cui/source/customize/acccfg.cxx +@@ -1117,7 +1117,7 @@ IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RemoveHdl) + IMPL_LINK( SfxAcceleratorConfigPage, SelectHdl, Control*, pListBox ) + { + // disable help +- Help::ShowBalloon( this, Point(), OUString() ); ++ Help::ShowBalloon( this, Point(), Rectangle(), OUString() ); + if (pListBox == m_pEntriesBox) + { + sal_uLong nPos = SvTreeList::GetRelPos( m_pEntriesBox->FirstSelected() ); +diff --git a/cui/source/customize/selector.cxx b/cui/source/customize/selector.cxx +index 781ddbf..2da0b77 100644 +--- a/cui/source/customize/selector.cxx ++++ b/cui/source/customize/selector.cxx +@@ -130,7 +130,8 @@ void SvxConfigFunctionListBox::MouseMove( const MouseEvent& rMEvt ) + aTimer.Start(); + else + { +- Help::ShowBalloon( this, aMousePos, OUString() ); ++ Rectangle aRect(GetPosPixel(), GetSizePixel()); ++ Help::ShowBalloon( this, aMousePos, aRect, OUString() ); + aTimer.Stop(); + } + } +@@ -142,7 +143,10 @@ IMPL_LINK_NOARG_TYPED(SvxConfigFunctionListBox, TimerHdl, Timer *, void) + Point aMousePos = GetPointerPosPixel(); + SvTreeListEntry *pEntry = GetCurEntry(); + if ( pEntry && GetEntry( aMousePos ) == pEntry && pCurEntry == pEntry ) +- Help::ShowBalloon( this, OutputToScreenPixel( aMousePos ), GetHelpText( pEntry ) ); ++ { ++ Rectangle aRect(GetPosPixel(), GetSizePixel()); ++ Help::ShowBalloon( this, OutputToScreenPixel(aMousePos), aRect, GetHelpText( pEntry ) ); ++ } + } + + void SvxConfigFunctionListBox::ClearAll() +@@ -177,7 +181,7 @@ OUString SvxConfigFunctionListBox::GetHelpText( SvTreeListEntry *pEntry ) + + void SvxConfigFunctionListBox::FunctionSelected() + { +- Help::ShowBalloon( this, Point(), OUString() ); ++ Help::ShowBalloon( this, Point(), Rectangle(), OUString() ); + } + + // drag and drop support +diff --git a/include/vcl/help.hxx b/include/vcl/help.hxx +index 40dfcf2..4d226a8 100644 +--- a/include/vcl/help.hxx ++++ b/include/vcl/help.hxx +@@ -86,9 +86,6 @@ public: + static bool IsBalloonHelpEnabled(); + static bool ShowBalloon( vcl::Window* pParent, + const Point& rScreenPos, +- const OUString& rHelpText ); +- static bool ShowBalloon( vcl::Window* pParent, +- const Point& rScreenPos, + const Rectangle&, + const OUString& rHelpText ); + +diff --git a/sfx2/source/dialog/dinfdlg.cxx b/sfx2/source/dialog/dinfdlg.cxx +index 0e47101..56d4d98 100644 +--- a/sfx2/source/dialog/dinfdlg.cxx ++++ b/sfx2/source/dialog/dinfdlg.cxx +@@ -1336,7 +1336,7 @@ void CustomPropertiesDurationField::RequestHelp( const HelpEvent& rHEvt ) + Size aSize( GetSizePixel() ); + Rectangle aItemRect( rHEvt.GetMousePosPixel(), aSize ); + if (Help::IsBalloonHelpEnabled()) +- Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), GetText() ); ++ Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aItemRect, GetText() ); + else + Help::ShowQuickHelp( this, aItemRect, GetText(), + QuickHelpFlags::Left|QuickHelpFlags::VCenter ); +diff --git a/sw/source/core/draw/dpage.cxx b/sw/source/core/draw/dpage.cxx +index db5707c..e401512 100644 +--- a/sw/source/core/draw/dpage.cxx ++++ b/sw/source/core/draw/dpage.cxx +@@ -237,14 +237,14 @@ bool SwDPage::RequestHelp( vcl::Window* pWindow, SdrView* pView, + sText = SwViewShell::GetShellRes()->aLinkClick + ": " + sText; + } + ++ // then display the help: ++ Rectangle aRect( rEvt.GetMousePosPixel(), Size(1,1) ); + if( rEvt.GetMode() & HelpEventMode::BALLOON ) + { +- Help::ShowBalloon( pWindow, rEvt.GetMousePosPixel(), sText ); ++ Help::ShowBalloon( pWindow, rEvt.GetMousePosPixel(), aRect, sText ); + } + else + { +- // then display the help: +- Rectangle aRect( rEvt.GetMousePosPixel(), Size(1,1) ); + Help::ShowQuickHelp( pWindow, aRect, sText ); + } + bContinue = false; +diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx +index dd78039..a7d55b3 100644 +--- a/sw/source/uibase/docvw/edtwin2.cxx ++++ b/sw/source/uibase/docvw/edtwin2.cxx +@@ -365,18 +365,19 @@ void SwEditWin::RequestHelp(const HelpEvent &rEvt) + } + if (!sText.isEmpty()) + { ++ Rectangle aRect( aFieldRect.SVRect() ); ++ Point aPt( OutputToScreenPixel( LogicToPixel( aRect.TopLeft() ))); ++ aRect.Left() = aPt.X(); ++ aRect.Top() = aPt.Y(); ++ aPt = OutputToScreenPixel( LogicToPixel( aRect.BottomRight() )); ++ aRect.Right() = aPt.X(); ++ aRect.Bottom() = aPt.Y(); ++ + if( bBalloon ) +- Help::ShowBalloon( this, rEvt.GetMousePosPixel(), sText ); ++ Help::ShowBalloon( this, rEvt.GetMousePosPixel(), aRect, sText ); + else + { + // the show the help +- Rectangle aRect( aFieldRect.SVRect() ); +- Point aPt( OutputToScreenPixel( LogicToPixel( aRect.TopLeft() ))); +- aRect.Left() = aPt.X(); +- aRect.Top() = aPt.Y(); +- aPt = OutputToScreenPixel( LogicToPixel( aRect.BottomRight() )); +- aRect.Right() = aPt.X(); +- aRect.Bottom() = aPt.Y(); + OUString sDisplayText(ClipLongToolTip(sText)); + Help::ShowQuickHelp(this, aRect, sDisplayText, nStyle); + } +diff --git a/vcl/inc/helpwin.hxx b/vcl/inc/helpwin.hxx +index 5889a4f..7ff4072 100644 +--- a/vcl/inc/helpwin.hxx ++++ b/vcl/inc/helpwin.hxx +@@ -78,10 +78,10 @@ public: + + void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle, + const OUString& rHelpText, const OUString& rStatusText, +- const Point& rScreenPos, const Rectangle* pHelpArea = NULL ); ++ const Point& rScreenPos, const Rectangle& rHelpArea ); + void ImplDestroyHelpWindow( bool bUpdateHideTime ); + void ImplSetHelpWindowPos( vcl::Window* pHelpWindow, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle, +- const Point& rPos, const Rectangle* pHelpArea ); ++ const Point& rPos, const Rectangle& rHelpArea ); + + #endif // INCLUDED_VCL_INC_HELPWIN_HXX + +diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx +index 484504c..cfd401d 100644 +--- a/vcl/inc/salframe.hxx ++++ b/vcl/inc/salframe.hxx +@@ -237,6 +237,13 @@ public: + { + } + ++ // return true to indicate tooltips are shown natively, false otherwise ++ virtual bool ShowTooltip(const OUString& /*rHelpText*/, const Rectangle& /*rHelpArea*/ ) ++ { ++ return false; ++ } ++ ++ + // Callbacks (indepent part in vcl/source/window/winproc.cxx) + // for default message handling return 0 + void SetCallback( vcl::Window* pWindow, SALFRAMEPROC pProc ); +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index ee19e6c..b779d39 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -211,6 +211,8 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + Rectangle m_aRestorePosSize; + + #if GTK_CHECK_VERSION(3,0,0) ++ OUString m_aTooltip; ++ Rectangle m_aHelpArea; + guint32 m_nLastScrollEventTime; + long m_nWidthRequest; + long m_nHeightRequest; +@@ -243,6 +245,9 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + #if GTK_CHECK_VERSION(3,0,0) + static gboolean signalDraw( GtkWidget*, cairo_t *cr, gpointer ); + static void sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer frame); ++ static gboolean signalTooltipQuery(GtkWidget*, gint x, gint y, ++ gboolean keyboard_mode, GtkTooltip *tooltip, ++ gpointer frame); + #if GTK_CHECK_VERSION(3,14,0) + static void gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame); + static void gestureLongPress(GtkGestureLongPress* gesture, gpointer frame); +@@ -467,6 +472,7 @@ public: + + #if GTK_CHECK_VERSION(3,0,0) + virtual void SetModal(bool bModal) override; ++ virtual bool ShowTooltip(const OUString& rHelpText, const Rectangle& rHelpArea) override; + #endif + + static GtkSalFrame *getFromWindow( GtkWindow *pWindow ); +diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx +index 7014a79..9a6e845 100644 +--- a/vcl/source/app/help.cxx ++++ b/vcl/source/app/help.cxx +@@ -31,6 +31,7 @@ + #include "vcl/settings.hxx" + + #include "helpwin.hxx" ++#include "salframe.hxx" + #include "svdata.hxx" + + #define HELPWINSTYLE_QUICK 0 +@@ -147,21 +148,11 @@ bool Help::IsBalloonHelpEnabled() + } + + bool Help::ShowBalloon( vcl::Window* pParent, +- const Point& rScreenPos, +- const OUString& rHelpText ) +-{ +- ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, QuickHelpFlags::NONE, +- rHelpText, OUString(), rScreenPos ); +- +- return true; +-} +- +-bool Help::ShowBalloon( vcl::Window* pParent, + const Point& rScreenPos, const Rectangle& rRect, + const OUString& rHelpText ) + { + ImplShowHelpWindow( pParent, HELPWINSTYLE_BALLOON, QuickHelpFlags::NONE, +- rHelpText, OUString(), rScreenPos, &rRect ); ++ rHelpText, OUString(), rScreenPos, rRect ); + + return true; + } +@@ -189,7 +180,7 @@ bool Help::ShowQuickHelp( vcl::Window* pParent, + { + ImplShowHelpWindow( pParent, HELPWINSTYLE_QUICK, nStyle, + rHelpText, rLongHelpText, +- pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect ); ++ pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), rScreenRect ); + return true; + } + +@@ -221,7 +212,7 @@ void Help::UpdateTip( sal_uIntPtr nId, vcl::Window* pParent, const Rectangle& rS + Size aSz = pHelpWin->CalcOutSize(); + pHelpWin->SetOutputSizePixel( aSz ); + ImplSetHelpWindowPos( pHelpWin, pHelpWin->GetWinStyle(), pHelpWin->GetStyle(), +- pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), &rScreenRect ); ++ pParent->OutputToScreenPixel( pParent->GetPointerPosPixel() ), rScreenRect ); + + pHelpWin->SetHelpText( rText ); + pHelpWin->Invalidate(); +@@ -475,8 +466,14 @@ OUString HelpTextWindow::GetText() const + + void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle, + const OUString& rHelpText, const OUString& rStatusText, +- const Point& rScreenPos, const Rectangle* pHelpArea ) ++ const Point& rScreenPos, const Rectangle& rHelpArea ) + { ++ if (pParent->ImplGetFrame()->ShowTooltip(rHelpText, rHelpArea)) ++ { ++ //tooltips are handled natively, return early ++ return; ++ } ++ + ImplSVData* pSVData = ImplGetSVData(); + + if (rHelpText.isEmpty() && !pSVData->maHelpData.mbRequestingHelp) +@@ -490,9 +487,7 @@ void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHe + + if ( ( ( pHelpWin->GetHelpText() != rHelpText ) + || ( pHelpWin->GetWinStyle() != nHelpWinStyle ) +- || ( pHelpArea +- && ( pHelpWin->GetHelpArea() != *pHelpArea ) +- ) ++ || ( pHelpWin->GetHelpArea() != rHelpArea ) + ) + && pSVData->maHelpData.mbRequestingHelp + ) +@@ -517,7 +512,7 @@ void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHe + + pHelpWin->SetHelpText( rHelpText ); + // approach mouse position +- ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea ); ++ ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, rHelpArea ); + if( pHelpWin->IsVisible() ) + pHelpWin->Invalidate(); + } +@@ -536,13 +531,12 @@ void ImplShowHelpWindow( vcl::Window* pParent, sal_uInt16 nHelpWinStyle, QuickHe + pHelpWin = VclPtr::Create( pParent, rHelpText, nHelpWinStyle, nStyle ); + pSVData->maHelpData.mpHelpWin = pHelpWin; + pHelpWin->SetStatusText( rStatusText ); +- if ( pHelpArea ) +- pHelpWin->SetHelpArea( *pHelpArea ); ++ pHelpWin->SetHelpArea( rHelpArea ); + + // positioning + Size aSz = pHelpWin->CalcOutSize(); + pHelpWin->SetOutputSizePixel( aSz ); +- ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, pHelpArea ); ++ ImplSetHelpWindowPos( pHelpWin, nHelpWinStyle, nStyle, rScreenPos, rHelpArea ); + // if not called from Window::RequestHelp, then without delay... + if ( !pSVData->maHelpData.mbRequestingHelp ) + nDelayMode = HELPDELAY_NONE; +@@ -571,7 +565,7 @@ void ImplDestroyHelpWindow( bool bUpdateHideTime ) + } + + void ImplSetHelpWindowPos( vcl::Window* pHelpWin, sal_uInt16 nHelpWinStyle, QuickHelpFlags nStyle, +- const Point& rPos, const Rectangle* pHelpArea ) ++ const Point& rPos, const Rectangle& rHelpArea ) + { + Point aPos = rPos; + Size aSz = pHelpWin->GetSizePixel(); +@@ -606,26 +600,23 @@ void ImplSetHelpWindowPos( vcl::Window* pHelpWin, sal_uInt16 nHelpWinStyle, Quic + + if ( nStyle & QuickHelpFlags::NoAutoPos ) + { +- if ( pHelpArea ) +- { +- // convert help area to screen coords +- Rectangle devHelpArea( +- pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->TopLeft() ), +- pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( pHelpArea->BottomRight() ) ); +- +- // Welche Position vom Rechteck? +- aPos = devHelpArea.Center(); +- +- if ( nStyle & QuickHelpFlags::Left ) +- aPos.X() = devHelpArea.Left(); +- else if ( nStyle & QuickHelpFlags::Right ) +- aPos.X() = devHelpArea.Right(); +- +- if ( nStyle & QuickHelpFlags::Top ) +- aPos.Y() = devHelpArea.Top(); +- else if ( nStyle & QuickHelpFlags::Bottom ) +- aPos.Y() = devHelpArea.Bottom(); +- } ++ // convert help area to screen coords ++ Rectangle devHelpArea( ++ pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea.TopLeft() ), ++ pHelpWin->GetParent()->ImplGetFrameWindow()->OutputToAbsoluteScreenPixel( rHelpArea.BottomRight() ) ); ++ ++ // Welche Position vom Rechteck? ++ aPos = devHelpArea.Center(); ++ ++ if ( nStyle & QuickHelpFlags::Left ) ++ aPos.X() = devHelpArea.Left(); ++ else if ( nStyle & QuickHelpFlags::Right ) ++ aPos.X() = devHelpArea.Right(); ++ ++ if ( nStyle & QuickHelpFlags::Top ) ++ aPos.Y() = devHelpArea.Top(); ++ else if ( nStyle & QuickHelpFlags::Bottom ) ++ aPos.Y() = devHelpArea.Bottom(); + + // which direction? + if ( nStyle & QuickHelpFlags::Left ) +diff --git a/vcl/source/window/menuwindow.cxx b/vcl/source/window/menuwindow.cxx +index e915c33..4e89f44 100644 +--- a/vcl/source/window/menuwindow.cxx ++++ b/vcl/source/window/menuwindow.cxx +@@ -63,7 +63,7 @@ bool MenuWindow::ImplHandleHelpEvent(vcl::Window* pMenuWindow, Menu* pMenu, sal_ + + Rectangle aRect( aPos, Size() ); + if (!pMenu->GetHelpText(nId).isEmpty()) +- Help::ShowBalloon( pMenuWindow, aPos, pMenu->GetHelpText( nId ) ); ++ Help::ShowBalloon( pMenuWindow, aPos, aRect, pMenu->GetHelpText( nId ) ); + else + { + // give user a chance to read the full filename +diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx +index e8d2b96..20377ac 100644 +--- a/vcl/source/window/window.cxx ++++ b/vcl/source/window/window.cxx +@@ -1976,7 +1976,14 @@ void Window::RequestHelp( const HelpEvent& rHEvt ) + if ( rStr.isEmpty() && ImplGetParent() && !ImplIsOverlapWindow() ) + ImplGetParent()->RequestHelp( rHEvt ); + else +- Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), rStr ); ++ { ++ Point aPos = GetPosPixel(); ++ if ( ImplGetParent() && !ImplIsOverlapWindow() ) ++ aPos = ImplGetParent()->OutputToScreenPixel( aPos ); ++ Rectangle aRect( aPos, GetSizePixel() ); ++ ++ Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aRect, rStr ); ++ } + } + else if ( rHEvt.GetMode() & HelpEventMode::QUICK ) + { +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index ca9d371..592c872 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -978,6 +978,8 @@ void GtkSalFrame::InitCommon() + + // connect signals + g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this ); ++ gtk_widget_set_has_tooltip(pEventWidget, true); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "query-tooltip", G_CALLBACK(signalTooltipQuery), this )); + m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-press-event", G_CALLBACK(signalButton), this )); + m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this )); + m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this )); +@@ -2623,6 +2625,32 @@ void GtkSalFrame::SetModal(bool bModal) + gtk_window_set_modal(GTK_WINDOW(m_pWindow), bModal); + } + ++gboolean GtkSalFrame::signalTooltipQuery(GtkWidget*, gint /*x*/, gint /*y*/, ++ gboolean /*keyboard_mode*/, GtkTooltip *tooltip, ++ gpointer frame) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ if (pThis->m_aTooltip.isEmpty()) ++ return false; ++ gtk_tooltip_set_text(tooltip, ++ OUStringToOString(pThis->m_aTooltip, RTL_TEXTENCODING_UTF8).getStr()); ++ GdkRectangle aHelpArea; ++ aHelpArea.x = pThis->m_aHelpArea.Left(); ++ aHelpArea.y = pThis->m_aHelpArea.Top(); ++ aHelpArea.width = pThis->m_aHelpArea.GetWidth(); ++ aHelpArea.height = pThis->m_aHelpArea.GetHeight(); ++ gtk_tooltip_set_tip_area(tooltip, &aHelpArea); ++ return true; ++} ++ ++bool GtkSalFrame::ShowTooltip(const OUString& rHelpText, const Rectangle& rHelpArea) ++{ ++ m_aTooltip = rHelpText; ++ m_aHelpArea = rHelpArea; ++ gtk_widget_trigger_tooltip_query(getMouseEventWidget()); ++ return true; ++} ++ + gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) + { + GtkSalFrame* pThis = static_cast(frame); +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1289398-unable-to-use-scroll-wheel-und.patch b/SOURCES/0001-Resolves-rhbz-1289398-unable-to-use-scroll-wheel-und.patch new file mode 100644 index 0000000..a834ec3 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1289398-unable-to-use-scroll-wheel-und.patch @@ -0,0 +1,125 @@ +From ab20ea1d78697aa88dd84b8be4ac385cf295ea20 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 8 Dec 2015 15:52:47 +0000 +Subject: [PATCH] Resolves: rhbz#1289398 unable to use scroll wheel under + wayland + +because we only get smooth scroll events, so implement that as +best we can. + +(cherry picked from commit c5c1f8f710760d40ca1004c5fdd69f8fa2c87496) + +Change-Id: I7701949cf7c9ffdc9d062f75b23db7c6add3c6a9 +--- + vcl/inc/unx/gtk/gtkframe.hxx | 1 + + vcl/unx/gtk/window/gtksalframe.cxx | 70 +++++++++++++++++++++++++++----------- + 2 files changed, 52 insertions(+), 19 deletions(-) + +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index 3531c41..4594249 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -211,6 +211,7 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + Rectangle m_aRestorePosSize; + + #if GTK_CHECK_VERSION(3,0,0) ++ guint32 m_nLastScrollEventTime; + cairo_region_t* m_pRegion; + #else + GdkRegion* m_pRegion; +diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx +index 614974a..616f73f 100644 +--- a/vcl/unx/gtk/window/gtksalframe.cxx ++++ b/vcl/unx/gtk/window/gtksalframe.cxx +@@ -1129,6 +1129,9 @@ void GtkSalFrame::InitCommon() + m_bSpanMonitorsWhenFullscreen = false; + m_nState = GDK_WINDOW_STATE_WITHDRAWN; + m_nVisibility = GDK_VISIBILITY_FULLY_OBSCURED; ++#if GTK_CHECK_VERSION(3,0,0) ++ m_nLastScrollEventTime = GDK_CURRENT_TIME; ++#endif + m_bSendModChangeOnRelease = false; + m_pIMHandler = NULL; + m_hBackgroundPixmap = None; +@@ -3542,30 +3545,59 @@ gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame + GdkEventScroll* pSEvent = reinterpret_cast(pEvent); + + #if GTK_CHECK_VERSION(3,0,0) +- //TODO: do something less feeble here +- if (pSEvent->direction == GDK_SCROLL_SMOOTH) ++ // gnome#726878 check for duplicate legacy scroll event ++ if (pSEvent->direction != GDK_SCROLL_SMOOTH && ++ pThis->m_nLastScrollEventTime == pSEvent->time) ++ { + return true; ++ } + #endif + +- static sal_uLong nLines = 0; +- if( ! nLines ) ++ SalWheelMouseEvent aEvent; ++ ++ aEvent.mnTime = pSEvent->time; ++ aEvent.mnX = (sal_uLong)pSEvent->x; ++ aEvent.mnY = (sal_uLong)pSEvent->y; ++ aEvent.mnCode = GetMouseModCode( pSEvent->state ); ++ aEvent.mnScrollLines = 3; ++ ++ switch (pSEvent->direction) + { +- char* pEnv = getenv( "SAL_WHEELLINES" ); +- nLines = pEnv ? atoi( pEnv ) : 3; +- if( nLines > 10 ) +- nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL; +- } ++#if GTK_CHECK_VERSION(3,0,0) ++ case GDK_SCROLL_SMOOTH: ++ { ++ double delta_x, delta_y; ++ gdk_event_get_scroll_deltas(pEvent, &delta_x, &delta_y); ++ //pick the bigger one I guess ++ aEvent.mbHorz = fabs(delta_x) > fabs(delta_y); ++ if (aEvent.mbHorz) ++ aEvent.mnDelta = -delta_x; ++ else ++ aEvent.mnDelta = -delta_y; ++ aEvent.mnScrollLines = 1; ++ pThis->m_nLastScrollEventTime = pSEvent->time; ++ break; ++ } ++#endif ++ case GDK_SCROLL_UP: ++ aEvent.mnDelta = 120; ++ aEvent.mbHorz = false; ++ break; ++ case GDK_SCROLL_DOWN: ++ aEvent.mnDelta = -120; ++ aEvent.mbHorz = false; ++ break; ++ case GDK_SCROLL_LEFT: ++ aEvent.mbHorz = true; ++ aEvent.mnDelta = 120; ++ break; ++ case GDK_SCROLL_RIGHT: ++ aEvent.mnDelta = -120; ++ aEvent.mbHorz = true; ++ break; ++ }; + +- bool bNeg = (pSEvent->direction == GDK_SCROLL_DOWN || pSEvent->direction == GDK_SCROLL_RIGHT ); +- SalWheelMouseEvent aEvent; +- aEvent.mnTime = pSEvent->time; +- aEvent.mnX = (sal_uLong)pSEvent->x; +- aEvent.mnY = (sal_uLong)pSEvent->y; +- aEvent.mnDelta = bNeg ? -120 : 120; +- aEvent.mnNotchDelta = bNeg ? -1 : 1; +- aEvent.mnScrollLines = nLines; +- aEvent.mnCode = GetMouseModCode( pSEvent->state ); +- aEvent.mbHorz = (pSEvent->direction == GDK_SCROLL_LEFT || pSEvent->direction == GDK_SCROLL_RIGHT); ++ aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : 1; + + // --- RTL --- (mirror mouse pos) + if( AllSettings::GetLayoutRTL() ) +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1291925-implement-SAL_INVERT_TRACKFRAM.patch b/SOURCES/0001-Resolves-rhbz-1291925-implement-SAL_INVERT_TRACKFRAM.patch new file mode 100644 index 0000000..690f197 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1291925-implement-SAL_INVERT_TRACKFRAM.patch @@ -0,0 +1,186 @@ +From add0b75abd601d5d80e5ad6f20ab63ac1489f028 Mon Sep 17 00:00:00 2001 +From: rpmbuild +Date: Wed, 16 Dec 2015 10:18:52 +0000 +Subject: [PATCH] Resolves: rhbz#1291925 implement SAL_INVERT_TRACKFRAME + +Change-Id: Iec7df66f9bfddcb916047aff569cf2070dd2fa4f +--- + vcl/headless/svpgdi.cxx | 85 +++++++++++++++++++++++++++---------------------- + 1 file changed, 47 insertions(+), 38 deletions(-) + +diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx +index a79142c..ed2c8cf 100644 +--- a/vcl/headless/svpgdi.cxx ++++ b/vcl/headless/svpgdi.cxx +@@ -109,13 +109,9 @@ namespace + if (rBuffer->getScanlineFormat() != basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX) + return false; + +-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0) + basegfx::B2IVector size = rBuffer->getSize(); + sal_Int32 nStride = rBuffer->getScanlineStride(); + return (cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, size.getX()) == nStride); +-#else +- return false; +-#endif + } + } + +@@ -135,7 +131,7 @@ void SvpSalGraphics::clipRegion(cairo_t* cr) + cairo_clip(cr); + } + } +-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0) ++ + namespace + { + cairo_rectangle_int_t getFillDamage(cairo_t* cr) +@@ -163,22 +159,20 @@ namespace + double x1, y1, x2, y2; + + cairo_clip_extents(cr, &x1, &y1, &x2, &y2); +- extents.x = x1, extents.y = x2, extents.width = x2-x1, extents.height = y2-y1; +-#if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 10) ++ extents.x = x1, extents.y = y1, extents.width = x2-x1, extents.height = y2-y1; ++ + cairo_region_t *region = cairo_region_create_rectangle(&extents); + + cairo_stroke_extents(cr, &x1, &y1, &x2, &y2); +- extents.x = x1, extents.y = x2, extents.width = x2-x1, extents.height = y2-y1; ++ extents.x = x1, extents.y = y1, extents.width = x2-x1, extents.height = y2-y1; + cairo_region_intersect_rectangle(region, &extents); + + cairo_region_get_extents(region, &extents); + cairo_region_destroy(region); +-#endif + + return extents; + } + } +-#endif + + #endif + +@@ -213,7 +207,7 @@ bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight, + fTransparency); + cairo_rectangle(cr, nX, nY, nWidth, nHeight); + +- cairo_rectangle_int_t extents; ++ cairo_rectangle_int_t extents = {0, 0, 0, 0}; + basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aOrigDevice->getDamageTracker()); + if (xDamageTracker) + extents = getFillDamage(cr); +@@ -798,7 +792,7 @@ bool SvpSalGraphics::drawPolyLine( + + AddPolygonToPath(cr, rPolyLine, rPolyLine.isClosed()); + +- cairo_rectangle_int_t extents; ++ cairo_rectangle_int_t extents = {0, 0, 0, 0}; + basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aDevice->getDamageTracker()); + + cairo_set_source_rgba(cr, m_aLineColor.getRed()/255.0, +@@ -884,7 +878,7 @@ bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, d + for (const basegfx::B2DPolygon* pPoly = rPolyPoly.begin(); pPoly != rPolyPoly.end(); ++pPoly) + AddPolygonToPath(cr, *pPoly, true); + +- cairo_rectangle_int_t extents; ++ cairo_rectangle_int_t extents = {0, 0, 0, 0}; + basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aOrigDevice->getDamageTracker()); + if (xDamageTracker) + extents = getFillDamage(cr); +@@ -1067,15 +1061,10 @@ namespace + void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) + { + #if ENABLE_CAIRO_CANVAS +-#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0) +- // FIXME: handle SAL_INVERT_TRACKFRAME +- if ( nFlags & SAL_INVERT_TRACKFRAME ) +- { +- SAL_WARN("vcl.gdi", "SvpSalGraphics::invert, unhandled SAL_INVERT_TRACKFRAME"); +- } +- else if ( nFlags & SAL_INVERT_50 ) ++ if (m_aDrawMode != basebmp::DrawMode_XOR) + { +- if (cairo_t* cr = createCairoContext(m_aOrigDevice)) ++ cairo_t* cr = createCairoContext(m_aOrigDevice); ++ if (cr && cairo_version() >= CAIRO_VERSION_ENCODE(1, 10, 0)) + { + if (!m_aOrigDevice->isTopDown()) + { +@@ -1085,36 +1074,56 @@ void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv + + clipRegion(cr); + +- cairo_pattern_t *pattern = create_stipple(); +- +- cairo_rectangle_int_t extents; ++ cairo_rectangle_int_t extents = {0, 0, 0, 0}; + basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aOrigDevice->getDamageTracker()); + + cairo_rectangle(cr, nX, nY, nWidth, nHeight); + +- if (xDamageTracker) +- extents = getFillDamage(cr); +- +- cairo_clip(cr); +- + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); +- cairo_mask(cr, pattern); +- cairo_pattern_destroy(pattern); ++ ++ if (nFlags & SAL_INVERT_TRACKFRAME) ++ { ++ cairo_set_line_width(cr, 2.0); ++ const double dashLengths[2] = { 4.0, 4.0 }; ++ cairo_set_dash(cr, dashLengths, 2, 0); ++ ++ if (xDamageTracker) ++ extents = getStrokeDamage(cr); ++ ++ cairo_stroke(cr); ++ } ++ else ++ { ++ if (xDamageTracker) ++ extents = getFillDamage(cr); ++ ++ cairo_clip(cr); ++ ++ if (nFlags & SAL_INVERT_50) ++ { ++ cairo_pattern_t *pattern = create_stipple(); ++ cairo_mask(cr, pattern); ++ cairo_pattern_destroy(pattern); ++ } ++ else ++ { ++ cairo_paint(cr); ++ } ++ } + + cairo_surface_flush(cairo_get_target(cr)); + cairo_destroy(cr); // unref + ++ if (xDamageTracker) ++ { ++ xDamageTracker->damaged(basegfx::B2IBox(extents.x, extents.y, extents.x + extents.width, ++ extents.y + extents.height)); ++ } ++ + return; + } +- else +- SAL_WARN("vcl.gdi", "SvpSalGraphics::invert unhandled XOR (?)"); + } +- else +- { +- SAL_WARN("vcl.gdi", "SvpSalGraphics::invert, unhandled SAL_INVERT_TRACKFRAME"); +- } +-#endif + #endif + + basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) ); +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1294208-trackpad-two-finger-scroll-doe.patch b/SOURCES/0001-Resolves-rhbz-1294208-trackpad-two-finger-scroll-doe.patch new file mode 100644 index 0000000..87a249e --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1294208-trackpad-two-finger-scroll-doe.patch @@ -0,0 +1,37 @@ +From 14e7252cc4ceaf1a732034696a17dd3ad1439902 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 27 Jan 2016 16:20:35 +0000 +Subject: [PATCH] Resolves: rhbz#1294208 trackpad two finger scroll does into + reverse + +Change-Id: Ic576f14cae82781a93e52972513a28c4a141d1a2 +(cherry picked from commit e734c7f53cfffa6141e6b46c06825ee273e2136b) +--- + vcl/unx/gtk3/gtk3gtkframe.cxx | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index af284ca..3914de5 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -2557,14 +2557,12 @@ gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame + { + case GDK_SCROLL_SMOOTH: + { +- double delta_x, delta_y; +- gdk_event_get_scroll_deltas(pEvent, &delta_x, &delta_y); + //pick the bigger one I guess +- aEvent.mbHorz = fabs(delta_x) > fabs(delta_y); ++ aEvent.mbHorz = fabs(pSEvent->delta_x) > fabs(pSEvent->delta_y); + if (aEvent.mbHorz) +- aEvent.mnDelta = -delta_x; ++ aEvent.mnDelta = -pSEvent->delta_x * 40; + else +- aEvent.mnDelta = -delta_y; ++ aEvent.mnDelta = -pSEvent->delta_y * 40; + aEvent.mnScrollLines = 1; + pThis->m_nLastScrollEventTime = pSEvent->time; + break; +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-rhbz-1315385-use-preferred-size-if-widget-s.patch b/SOURCES/0001-Resolves-rhbz-1315385-use-preferred-size-if-widget-s.patch new file mode 100644 index 0000000..747ef70 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1315385-use-preferred-size-if-widget-s.patch @@ -0,0 +1,30 @@ +From 86692366b7edbd6dd1ce329a172fb78d402ac328 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 9 Mar 2016 11:01:43 +0000 +Subject: [PATCH] Resolves: rhbz#1315385 use preferred size if widget supports + it + +when deciding if a popup needs to be placed up or down to stay +visible on screen + +Change-Id: I718e0ee4a79152e919ac95841e15d4b53764ac78 +--- + vcl/source/window/floatwin.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx +index 00c3b34..6553f94 100644 +--- a/vcl/source/window/floatwin.cxx ++++ b/vcl/source/window/floatwin.cxx +@@ -244,7 +244,7 @@ Point FloatingWindow::ImplCalcPos( vcl::Window* pWindow, + { + // get window position + Point aPos; +- Size aSize = pWindow->GetSizePixel(); ++ Size aSize = ::isLayoutEnabled(pWindow) ? pWindow->get_preferred_size() : pWindow->GetSizePixel(); + Rectangle aScreenRect = pWindow->ImplGetFrameWindow()->GetDesktopRectPixel(); + FloatingWindow *pFloatingWindow = dynamic_cast( pWindow ); + +-- +2.7.1 + diff --git a/SOURCES/0001-Resolves-rhbz-1364335-tooltips-are-truncated.patch b/SOURCES/0001-Resolves-rhbz-1364335-tooltips-are-truncated.patch new file mode 100644 index 0000000..16f3a2a --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1364335-tooltips-are-truncated.patch @@ -0,0 +1,47 @@ +From 2d7b2c6357d478b83fce8f457305e7c2932c4656 Mon Sep 17 00:00:00 2001 +From: rpmbuild +Date: Mon, 15 Aug 2016 15:17:11 +0100 +Subject: [PATCH] Resolves: rhbz#1364335 tooltips are truncated + +--- + vcl/inc/helpwin.hxx | 1 + + vcl/source/app/help.cxx | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +diff --git a/vcl/inc/helpwin.hxx b/vcl/inc/helpwin.hxx +index 5889a4f..def965d 100644 +--- a/vcl/inc/helpwin.hxx ++++ b/vcl/inc/helpwin.hxx +@@ -49,6 +49,7 @@ protected: + virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle&) SAL_OVERRIDE; + virtual void RequestHelp( const HelpEvent& rHEvt ) SAL_OVERRIDE; + virtual void ApplySettings(vcl::RenderContext& rRenderContext) SAL_OVERRIDE; ++ virtual void StateChanged(StateChangedType nType) SAL_OVERRIDE; + + virtual OUString GetText() const SAL_OVERRIDE; + void ImplShow(); +diff --git a/vcl/source/app/help.cxx b/vcl/source/app/help.cxx +index 7014a79..13b0c24 100644 +--- a/vcl/source/app/help.cxx ++++ b/vcl/source/app/help.cxx +@@ -269,6 +269,17 @@ HelpTextWindow::HelpTextWindow( vcl::Window* pParent, const OUString& rText, sal + maHideTimer.SetTimeout( rHelpSettings.GetTipTimeout() ); + } + ++void HelpTextWindow::StateChanged(StateChangedType nType) ++{ ++ FloatingWindow::StateChanged(nType); ++ if (nType == StateChangedType::InitShow) ++ { ++ ApplySettings(*this); ++ SetHelpText(maHelpText); ++ Invalidate(); ++ } ++} ++ + void HelpTextWindow::ApplySettings(vcl::RenderContext& rRenderContext) + { + const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); +-- +1.8.3.1 + diff --git a/SOURCES/0001-Resolves-rhbz-1401082-gnome-hangs-opening-a-certain-.patch b/SOURCES/0001-Resolves-rhbz-1401082-gnome-hangs-opening-a-certain-.patch new file mode 100644 index 0000000..3bbb518 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1401082-gnome-hangs-opening-a-certain-.patch @@ -0,0 +1,143 @@ +From 9f5e3b61e7b3a7dd3cca369d153b3993b10496ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 6 Dec 2016 15:17:38 +0000 +Subject: [PATCH] Resolves: rhbz#1401082 gnome hangs opening a certain .docx +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +this seems to be a problem since.... + +commit 199eb08be994ef968eb38f4966bc27ef1756d382 +Author: Miklos Vajna +Date: Thu Jun 5 16:25:01 2014 +0200 + + SwAnchoredDrawObject::GetObjBoundRect: avoid SwDoc::SetModified() + + This is a const method, but it does a const_cast to still resize an + object... if that's so, then we should ensure that the "is modified" + flag of SwDoc is untouched. + + CppunitTest_sw_ooxmlimport's testChartSize is a reproducer for this, + when shape text is imported as textbox. + +(note under gtk3 and wayland this isn't as noticable, there use +export GDK_BACKEND=x11 to reproduce the freeze effect where even +the mouse cursor doesn't move during part of the load) + +Change-Id: Ic0bd98b032dfe1255d79d8070d50f65fcfa676dd +Reviewed-on: https://gerrit.libreoffice.org/31687 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit d393039655edf9bb884fc2956674badde59d2326) +Reviewed-on: https://gerrit.libreoffice.org/31948 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +--- + sw/inc/IDocumentState.hxx | 3 +++ + sw/source/core/doc/DocumentStateManager.cxx | 13 +++++++++++++ + sw/source/core/inc/DocumentStateManager.hxx | 5 ++++- + sw/source/core/layout/anchoreddrawobject.cxx | 7 ++++--- + 4 files changed, 24 insertions(+), 4 deletions(-) + +diff --git a/sw/inc/IDocumentState.hxx b/sw/inc/IDocumentState.hxx +index a6fc748..41fa8e4 100644 +--- a/sw/inc/IDocumentState.hxx ++++ b/sw/inc/IDocumentState.hxx +@@ -58,6 +58,9 @@ public: + + virtual void SetLoaded(bool b = true) = 0; + ++ virtual bool IsEnableSetModified() const = 0; ++ virtual void SetEnableSetModified(bool bEnableSetModified) = 0; ++ + protected: + virtual ~IDocumentState() {}; + }; +diff --git a/sw/source/core/doc/DocumentStateManager.cxx b/sw/source/core/doc/DocumentStateManager.cxx +index ede8ef9..cf755e1 100644 +--- a/sw/source/core/doc/DocumentStateManager.cxx ++++ b/sw/source/core/doc/DocumentStateManager.cxx +@@ -29,6 +29,7 @@ namespace sw + + DocumentStateManager::DocumentStateManager( SwDoc& i_rSwdoc ) : + m_rDoc( i_rSwdoc ), ++ mbEnableSetModified(true), + mbModified(false), + mbLoaded(false), + mbUpdateExpField(false), +@@ -40,6 +41,8 @@ DocumentStateManager::DocumentStateManager( SwDoc& i_rSwdoc ) : + + void DocumentStateManager::SetModified() + { ++ if (!IsEnableSetModified()) ++ return; + m_rDoc.GetDocumentLayoutManager().ClearSwLayouterEntries(); + // give the old and new modified state to the link + // Bit 0: -> old state +@@ -80,6 +83,16 @@ bool DocumentStateManager::IsModified() const + return mbModified; + } + ++bool DocumentStateManager::IsEnableSetModified() const ++{ ++ return mbEnableSetModified; ++} ++ ++void DocumentStateManager::SetEnableSetModified(bool bEnableSetModified) ++{ ++ mbEnableSetModified = bEnableSetModified; ++} ++ + bool DocumentStateManager::IsInCallModified() const + { + return mbInCallModified; +diff --git a/sw/source/core/inc/DocumentStateManager.hxx b/sw/source/core/inc/DocumentStateManager.hxx +index 1d67a36..f3ca7d9 100644 +--- a/sw/source/core/inc/DocumentStateManager.hxx ++++ b/sw/source/core/inc/DocumentStateManager.hxx +@@ -38,6 +38,8 @@ public: + void SetModified() SAL_OVERRIDE; + void ResetModified() SAL_OVERRIDE; + bool IsModified() const SAL_OVERRIDE; ++ bool IsEnableSetModified() const SAL_OVERRIDE; ++ void SetEnableSetModified(bool bEnableSetModified) SAL_OVERRIDE; + bool IsInCallModified() const SAL_OVERRIDE; + bool IsLoaded() const SAL_OVERRIDE; + bool IsUpdateExpField() const SAL_OVERRIDE; +@@ -51,9 +53,10 @@ public: + private: + SwDoc& m_rDoc; + ++ bool mbEnableSetModified; //< FALSE: changing document modification status (temporarily) locked + bool mbModified ; //< TRUE: document has changed. + bool mbLoaded ; //< TRUE: Doc loaded. +- bool mbUpdateExpField ; //< TRUE: Update expression fields. ++ bool mbUpdateExpField; //< TRUE: Update expression fields. + bool mbNewDoc ; //< TRUE: new Doc. + bool mbPageNums ; //< TRUE: There are virtual page numbers. + bool mbInCallModified; //< TRUE: in Set/Reset-Modified link. +diff --git a/sw/source/core/layout/anchoreddrawobject.cxx b/sw/source/core/layout/anchoreddrawobject.cxx +index 7051a2a..644d7e6 100644 +--- a/sw/source/core/layout/anchoreddrawobject.cxx ++++ b/sw/source/core/layout/anchoreddrawobject.cxx +@@ -659,12 +659,13 @@ const SwRect SwAnchoredDrawObject::GetObjBoundRect() const + if ( nTargetWidth != aCurrObjRect.GetWidth( ) || nTargetHeight != aCurrObjRect.GetHeight( ) ) + { + SwDoc* pDoc = const_cast(GetPageFrm()->GetFormat()->GetDoc()); +- bool bModified = pDoc->getIDocumentState().IsModified(); ++ ++ bool bEnableSetModified = pDoc->getIDocumentState().IsEnableSetModified(); ++ pDoc->getIDocumentState().SetEnableSetModified(false); + const_cast< SdrObject* >( GetDrawObj() )->Resize( aCurrObjRect.TopLeft(), + Fraction( nTargetWidth, aCurrObjRect.GetWidth() ), + Fraction( nTargetHeight, aCurrObjRect.GetHeight() ), false ); +- if (!bModified) +- pDoc->getIDocumentState().ResetModified(); ++ pDoc->getIDocumentState().SetEnableSetModified(bEnableSetModified); + } + } + return GetDrawObj()->GetCurrentBoundRect(); +-- +2.9.3 + diff --git a/SOURCES/0001-Resolves-rhbz-1454693-segv-on-interrupting-tiled-ren.patch b/SOURCES/0001-Resolves-rhbz-1454693-segv-on-interrupting-tiled-ren.patch new file mode 100644 index 0000000..d843b90 --- /dev/null +++ b/SOURCES/0001-Resolves-rhbz-1454693-segv-on-interrupting-tiled-ren.patch @@ -0,0 +1,50 @@ +From 23ee72212d5df5fd11a36b6b1b45b02ef23dcaf1 Mon Sep 17 00:00:00 2001 +From: rpmbuild +Date: Fri, 16 Jun 2017 15:53:41 +0100 +Subject: [PATCH] Resolves: rhbz#1454693 segv on interrupting tiled rendering + +--- + libreofficekit/source/gtk/lokdocview.cxx | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index b6f34ac..584ab57 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -942,6 +942,14 @@ callback (gpointer pData) + LOKDocView* pDocView = LOK_DOC_VIEW (pCallback->m_pDocView); + LOKDocViewPrivate& priv = getPrivate(pDocView); + ++ //callback registered before the widget was destroyed. ++ //Use existance of lokThreadPool as flag it was torn down ++ if (!priv->lokThreadPool) ++ { ++ delete pCallback; ++ return G_SOURCE_REMOVE; ++ } ++ + switch (pCallback->m_nType) + { + case LOK_CALLBACK_INVALIDATE_TILES: +@@ -2061,11 +2069,18 @@ static void lok_doc_view_destroy (GtkWidget* widget) + LOKDocView* pDocView = LOK_DOC_VIEW (widget); + LOKDocViewPrivate& priv = getPrivate(pDocView); + ++ if (priv->lokThreadPool) ++ { ++ g_thread_pool_free(priv->lokThreadPool, true, true); ++ priv->lokThreadPool = nullptr; ++ } ++ + if (priv->m_pDocument) + { + priv->m_pDocument->pClass->destroy (priv->m_pDocument); + priv->m_pDocument = nullptr; + } ++ + if (priv->m_pOffice) + { + priv->m_pOffice->pClass->destroy (priv->m_pOffice); +-- +1.8.3.1 + diff --git a/SOURCES/0001-Resolves-tdf-101213-drop-use-of-CAIRO_OPERATOR_DIFFE.patch b/SOURCES/0001-Resolves-tdf-101213-drop-use-of-CAIRO_OPERATOR_DIFFE.patch new file mode 100644 index 0000000..007fd85 --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-101213-drop-use-of-CAIRO_OPERATOR_DIFFE.patch @@ -0,0 +1,69 @@ +From d89abe0806947149eafbd9d7ce4b3095ec38b236 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 4 Aug 2016 17:23:30 +0100 +Subject: [PATCH] Resolves: tdf#101213 drop use of CAIRO_OPERATOR_DIFFERENCE + +for tdf#99446 and rhbz#1283420 there is a hackaround which ended up in 5.1.5, +which is not in 5.1.4, for corrupt glyphs under X. I can still reproduce the +problem if I drop the CAIRO_OPERATOR_DIFFERENCE usage here with master and +gtk2. + +This alternative hackaround to force a read of the underlying surface works +just as well (help->license information is the reproducer) but reportedly +solves the performance regression. + +(cherry picked from commit 705d7597480b2307d7e4929ce9386d80ce2a0f16) + +Change-Id: Ie3c5b07409537a1734226b4ce034620351297e25 +Reviewed-on: https://gerrit.libreoffice.org/27984 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +--- + vcl/unx/generic/gdi/x11cairotextrender.cxx | 23 +++++++++-------------- + 1 file changed, 9 insertions(+), 14 deletions(-) + +diff --git a/vcl/unx/generic/gdi/x11cairotextrender.cxx b/vcl/unx/generic/gdi/x11cairotextrender.cxx +index 17cb462..c2242b5 100644 +--- a/vcl/unx/generic/gdi/x11cairotextrender.cxx ++++ b/vcl/unx/generic/gdi/x11cairotextrender.cxx +@@ -42,10 +42,6 @@ struct _XRegion + BOX extents; + }; + +-#if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 10, 0) +-# define CAIRO_OPERATOR_DIFFERENCE (static_cast(23)) +-#endif +- + X11CairoTextRender::X11CairoTextRender(X11SalGraphics& rParent) + : mrParent(rParent) + { +@@ -83,17 +79,16 @@ cairo_t* X11CairoTextRender::getCairoContext() + cairo_t *cr = cairo_create(surface); + cairo_surface_destroy(surface); + +- //rhbz#1283420 bodge to draw and undraw something which has the side effect +- //of making the mysterious xrender related problem go away +- if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 10, 0)) ++ //rhbz#1283420 bodge to force a read from the underlying surface which has ++ //the side effect of making the mysterious xrender related problem go away + { +- cairo_save(cr); +- cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); +- cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); +- cairo_rectangle(cr, 0, 0, 1, 1); +- cairo_fill_preserve(cr); +- cairo_fill(cr); +- cairo_restore(cr); ++ cairo_surface_t *target = cairo_get_target(cr); ++ cairo_surface_t *throw_away = cairo_surface_create_similar(target, cairo_surface_get_content(target), 1, 1); ++ cairo_t *force_read_cr = cairo_create(throw_away); ++ cairo_set_source_surface(force_read_cr, target, 0, 0); ++ cairo_paint(force_read_cr); ++ cairo_destroy(force_read_cr); ++ cairo_surface_destroy(throw_away); + } + + return cr; +-- +2.9.3 + diff --git a/SOURCES/0001-Resolves-tdf-49407-enable-CaseMap-property-in-impres.patch b/SOURCES/0001-Resolves-tdf-49407-enable-CaseMap-property-in-impres.patch new file mode 100644 index 0000000..8327d31 --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-49407-enable-CaseMap-property-in-impres.patch @@ -0,0 +1,222 @@ +From fb65ac2e3028c4fc160a47448bc44d73d282c9f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 8 Jun 2015 12:21:01 +0100 +Subject: [PATCH] Resolves: tdf#49407 enable CaseMap property in impress/draw + +I don't see why this was explicitly disabled, works fine +out of the box for me, import/export already hooked up +in odf + +Change-Id: I5e6bdbc6a4f3cbcd97330c7d9fb33589489afee2 +--- + cui/source/inc/chardlg.hxx | 10 ---------- + sd/sdi/drtxtob.sdi | 6 ++++++ + sd/source/core/typemap.cxx | 1 + + sd/source/ui/dlg/dlgchar.cxx | 1 - + sd/source/ui/dlg/prltempl.cxx | 1 - + sd/source/ui/dlg/tabtempl.cxx | 1 - + sd/source/ui/func/fuchar.cxx | 1 + + sd/source/ui/func/futext.cxx | 7 ++++--- + sd/source/ui/view/drtxtob.cxx | 3 ++- + sd/source/ui/view/drviews2.cxx | 11 +++++++++++ + sd/source/ui/view/drviewsf.cxx | 1 + + sw/source/ui/chrdlg/chardlg.cxx | 8 +------- + 12 files changed, 27 insertions(+), 24 deletions(-) + +diff --git a/cui/source/inc/chardlg.hxx b/cui/source/inc/chardlg.hxx +index 4eb009a..a023a45 100644 +--- a/cui/source/inc/chardlg.hxx ++++ b/cui/source/inc/chardlg.hxx +@@ -32,16 +32,6 @@ + class SvxFontListItem; + class FontList; + +- +- +-#define DISABLE_CASEMAP ((sal_uInt16)0x0001) +-#define DISABLE_WORDLINE ((sal_uInt16)0x0002) +-#define DISABLE_BLINK ((sal_uInt16)0x0004) +-#define DISABLE_UNDERLINE_COLOR ((sal_uInt16)0x0008) +- +-#define DISABLE_LANGUAGE ((sal_uInt16)0x0010) +-#define DISABLE_HIDE_LANGUAGE ((sal_uInt16)0x0020) +- + // class SvxCharBasePage ------------------------------------------------- + + class SvxCharBasePage : public SfxTabPage +diff --git a/sd/sdi/drtxtob.sdi b/sd/sdi/drtxtob.sdi +index 3e975d4..ed564e4 100644 +--- a/sd/sdi/drtxtob.sdi ++++ b/sd/sdi/drtxtob.sdi +@@ -92,6 +92,12 @@ shell TextObjectBar + StateMethod = GetAttrState; + ] + ++ SID_ATTR_CHAR_CASEMAP // ole : ?, status : ? ++ [ ++ ExecMethod = Execute; ++ StateMethod = GetAttrState; ++ ] ++ + SID_ATTR_PARA_ADJUST_LEFT // ole : ?, status : ? + [ + ExecMethod = Execute; +diff --git a/sd/source/core/typemap.cxx b/sd/source/core/typemap.cxx +index a5548a3..65f7cf0 100644 +--- a/sd/source/core/typemap.cxx ++++ b/sd/source/core/typemap.cxx +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + #include + #include +diff --git a/sd/source/ui/dlg/dlgchar.cxx b/sd/source/ui/dlg/dlgchar.cxx +index a23cd80..5e44899 100644 +--- a/sd/source/ui/dlg/dlgchar.cxx ++++ b/sd/source/ui/dlg/dlgchar.cxx +@@ -60,7 +60,6 @@ void SdCharDlg::PageCreated( sal_uInt16 nId, SfxTabPage &rPage ) + } + else if (nId == mnCharEffects) + { +- aSet.Put (SfxUInt16Item(SID_DISABLE_CTL,DISABLE_CASEMAP)); + rPage.PageCreated(aSet); + } + } +diff --git a/sd/source/ui/dlg/prltempl.cxx b/sd/source/ui/dlg/prltempl.cxx +index 74c010e..c503c93 100644 +--- a/sd/source/ui/dlg/prltempl.cxx ++++ b/sd/source/ui/dlg/prltempl.cxx +@@ -281,7 +281,6 @@ void SdPresLayoutTemplateDlg::PageCreated( sal_uInt16 nId, SfxTabPage &rPage ) + + else if (nId == mnEffects) + { +- aSet.Put (SfxUInt16Item(SID_DISABLE_CTL,DISABLE_CASEMAP)); + rPage.PageCreated(aSet); + } + } +diff --git a/sd/source/ui/dlg/tabtempl.cxx b/sd/source/ui/dlg/tabtempl.cxx +index 61514ee..1189922 100644 +--- a/sd/source/ui/dlg/tabtempl.cxx ++++ b/sd/source/ui/dlg/tabtempl.cxx +@@ -152,7 +152,6 @@ void SdTabTemplateDlg::PageCreated( sal_uInt16 nId, SfxTabPage &rPage ) + } + else if (nId == m_nFontEffectId) + { +- aSet.Put (SfxUInt16Item(SID_DISABLE_CTL,DISABLE_CASEMAP)); + rPage.PageCreated(aSet); + } + else if (nId == m_nTextId) +diff --git a/sd/source/ui/func/fuchar.cxx b/sd/source/ui/func/fuchar.cxx +index 174391a..b8166c2 100644 +--- a/sd/source/ui/func/fuchar.cxx ++++ b/sd/source/ui/func/fuchar.cxx +@@ -106,6 +106,7 @@ void FuChar::DoExecute( SfxRequest& rReq ) + SID_ATTR_CHAR_FONTHEIGHT, + SID_ATTR_CHAR_COLOR, + SID_ATTR_CHAR_KERNING, ++ SID_ATTR_CHAR_CASEMAP, + SID_SET_SUPER_SCRIPT, + SID_SET_SUB_SCRIPT, + 0 }; +diff --git a/sd/source/ui/func/futext.cxx b/sd/source/ui/func/futext.cxx +index ac6fb71..33e5339 100644 +--- a/sd/source/ui/func/futext.cxx ++++ b/sd/source/ui/func/futext.cxx +@@ -85,12 +85,13 @@ static sal_uInt16 SidArray[] = { + SID_ATTR_CHAR_FONT, // 10007 + SID_ATTR_CHAR_POSTURE, // 10008 + SID_ATTR_CHAR_WEIGHT, // 10009 +- SID_ATTR_CHAR_SHADOWED, //10010 +- SID_ATTR_CHAR_STRIKEOUT, //10013 ++ SID_ATTR_CHAR_SHADOWED, // 10010 ++ SID_ATTR_CHAR_STRIKEOUT, // 10013 + SID_ATTR_CHAR_UNDERLINE, // 10014 + SID_ATTR_CHAR_FONTHEIGHT, // 10015 + SID_ATTR_CHAR_COLOR, // 10017 +- SID_ATTR_CHAR_KERNING, //10018 ++ SID_ATTR_CHAR_KERNING, // 10018 ++ SID_ATTR_CHAR_CASEMAP, // 10019 + SID_ATTR_PARA_ADJUST_LEFT, // 10028 + SID_ATTR_PARA_ADJUST_RIGHT, // 10029 + SID_ATTR_PARA_ADJUST_CENTER, // 10030 +diff --git a/sd/source/ui/view/drtxtob.cxx b/sd/source/ui/view/drtxtob.cxx +index 25913dd..45c868f 100644 +--- a/sd/source/ui/view/drtxtob.cxx ++++ b/sd/source/ui/view/drtxtob.cxx +@@ -171,8 +171,9 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) + case SID_ATTR_CHAR_FONTHEIGHT: + case SID_ATTR_CHAR_WEIGHT: + case SID_ATTR_CHAR_POSTURE: +- case SID_ATTR_CHAR_SHADOWED: ++ case SID_ATTR_CHAR_SHADOWED: + case SID_ATTR_CHAR_STRIKEOUT: ++ case SID_ATTR_CHAR_CASEMAP: + { + sal_uInt16 stretchX = 100; + sal_uInt16 stretchY = 100; +diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx +index d4ed8fa..ffbb503 100644 +--- a/sd/source/ui/view/drviews2.cxx ++++ b/sd/source/ui/view/drviews2.cxx +@@ -87,6 +87,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -3032,6 +3033,16 @@ void DrawViewShell::ExecChar( SfxRequest &rReq ) + } + } + break; ++ case SID_ATTR_CHAR_CASEMAP: ++ if( rReq.GetArgs() ) ++ { ++ SFX_REQUEST_ARG( rReq, pItem, SvxCaseMapItem, SID_ATTR_CHAR_CASEMAP , false ); ++ if (pItem) ++ { ++ aNewAttr.Put(*pItem); ++ } ++ } ++ break; + case SID_SET_SUB_SCRIPT: + { + SvxEscapementItem aItem( EE_CHAR_ESCAPEMENT ); +diff --git a/sd/source/ui/view/drviewsf.cxx b/sd/source/ui/view/drviewsf.cxx +index 56d7a88..a5183c1 100644 +--- a/sd/source/ui/view/drviewsf.cxx ++++ b/sd/source/ui/view/drviewsf.cxx +@@ -409,6 +409,7 @@ void DrawViewShell::GetAttrState( SfxItemSet& rSet ) + case SID_ATTR_CHAR_WEIGHT: + case SID_ATTR_CHAR_COLOR: + case SID_ATTR_CHAR_KERNING: ++ case SID_ATTR_CHAR_CASEMAP: + case SID_SET_SUB_SCRIPT: + case SID_SET_SUPER_SCRIPT: + { +diff --git a/sw/source/ui/chrdlg/chardlg.cxx b/sw/source/ui/chrdlg/chardlg.cxx +index b20dfdc2..2483fda 100644 +--- a/sw/source/ui/chrdlg/chardlg.cxx ++++ b/sw/source/ui/chrdlg/chardlg.cxx +@@ -112,13 +112,7 @@ void SwCharDlg::PageCreated( sal_uInt16 nId, SfxTabPage &rPage ) + } + else if (nId == m_nCharExtId) + { +- if(m_nDialogMode == DLG_CHAR_DRAW || m_nDialogMode == DLG_CHAR_ANN) +- aSet.Put (SfxUInt16Item(SID_DISABLE_CTL,DISABLE_CASEMAP)); +- +- else +- { +- aSet.Put (SfxUInt32Item(SID_FLAG_TYPE,SVX_PREVIEW_CHARACTER|SVX_ENABLE_FLASH)); +- } ++ aSet.Put (SfxUInt32Item(SID_FLAG_TYPE,SVX_PREVIEW_CHARACTER|SVX_ENABLE_FLASH)); + rPage.PageCreated(aSet); + } + else if (nId == m_nCharPosId) +-- +2.4.0 + diff --git a/SOURCES/0001-Resolves-tdf-89905-don-t-copy-palettes-from-shared-t.patch b/SOURCES/0001-Resolves-tdf-89905-don-t-copy-palettes-from-shared-t.patch new file mode 100644 index 0000000..4dc0a71 --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-89905-don-t-copy-palettes-from-shared-t.patch @@ -0,0 +1,599 @@ +From f47aa0dbb17a998bdeb01036b9fd9ba0b74b8704 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 6 Jun 2015 14:24:46 +0100 +Subject: [PATCH] Resolves: tdf#89905 don't copy palettes from shared to user + +make this a multi-path element with a shared read-only location +and a user read/write location and don't copy the presets, instead +just keep them in the shared location + +Now an admin can copy extra palettes into the shared location +and they magically appear in the user deployments + +Change-Id: I7585789c0c59941094f6128368df94b834d3c2a2 +(cherry picked from commit 29202a16d9f1934684c7d0978112849f2a21fe2f) + +Related: tdf#89905 these PalettePath uses appear to really be UserConfigPath + +which is the same path at the moment + +Change-Id: Ifdefa478003a2b5cc5c065b1942194dda1275f5e +(cherry picked from commit 2c3bf6bfc244517a0134e320acaa1f720703d8f2) +--- + cui/source/tabpages/tabarea.cxx | 9 ++- + cui/source/tabpages/tabline.cxx | 10 +++- + cui/source/tabpages/tpbitmap.cxx | 22 ++++++- + cui/source/tabpages/tpcolor.cxx | 22 ++++++- + cui/source/tabpages/tpgradnt.cxx | 22 ++++++- + cui/source/tabpages/tphatch.cxx | 22 ++++++- + cui/source/tabpages/tplnedef.cxx | 22 ++++++- + cui/source/tabpages/tplneend.cxx | 23 +++++++- + extras/Package_palettes.mk | 2 +- + offapi/com/sun/star/util/XPathSettings.idl | 3 +- + .../registry/data/org/openoffice/Office/Paths.xcu | 3 + + .../schema/org/openoffice/Office/Common.xcs | 7 ++- + sd/source/ui/dlg/PhotoAlbumDialog.cxx | 2 +- + svx/source/sidebar/nbdtmg.cxx | 4 +- + svx/source/tbxctrls/PaletteManager.cxx | 67 +++++++++++++++------- + svx/source/xoutdev/xtable.cxx | 54 ++++++++++++----- + 16 files changed, 237 insertions(+), 57 deletions(-) + +diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx +index 7ecc836..1bdaa17 100644 +--- a/cui/source/tabpages/tabarea.cxx ++++ b/cui/source/tabpages/tabarea.cxx +@@ -142,7 +142,14 @@ void SvxAreaTabDialog::SavePalettes() + + // save the tables when they have been changed + +- const OUString aPath( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aPath; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aPath = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); + + if( mnHatchingListState & ChangeType::MODIFIED ) + { +diff --git a/cui/source/tabpages/tabline.cxx b/cui/source/tabpages/tabline.cxx +index aa99b2c..6049c8c 100644 +--- a/cui/source/tabpages/tabline.cxx ++++ b/cui/source/tabpages/tabline.cxx +@@ -130,8 +130,14 @@ void SvxLineTabDialog::SavePalettes() + } + + // Save the tables when they have been changed +- +- const OUString aPath( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aPath; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aPath = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); + + if( nDashListState & ChangeType::MODIFIED ) + { +diff --git a/cui/source/tabpages/tpbitmap.cxx b/cui/source/tabpages/tpbitmap.cxx +index 0d11116..71c23e6 100644 +--- a/cui/source/tabpages/tpbitmap.cxx ++++ b/cui/source/tabpages/tpbitmap.cxx +@@ -795,7 +795,16 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickLoadHdl_Impl) + ::sfx2::FileDialogHelper aDlg( com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 ); + OUString aStrFilterType( "*.sob" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) ); + + if ( aDlg.Execute() == ERRCODE_NONE ) +@@ -875,7 +884,16 @@ IMPL_LINK_NOARG(SvxBitmapTabPage, ClickSaveHdl_Impl) + OUString aStrFilterType( "*.sob" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" ); + + if( !pBitmapList->GetName().isEmpty() ) +diff --git a/cui/source/tabpages/tpcolor.cxx b/cui/source/tabpages/tpcolor.cxx +index 94231c5..50b74de 100644 +--- a/cui/source/tabpages/tpcolor.cxx ++++ b/cui/source/tabpages/tpcolor.cxx +@@ -142,7 +142,16 @@ IMPL_LINK_NOARG(SvxColorTabPage, ClickLoadHdl_Impl) + OUString aStrFilterType( XPropertyList::GetDefaultExtFilter( meType ) ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) ); + + if ( aDlg.Execute() == ERRCODE_NONE ) +@@ -202,7 +211,16 @@ IMPL_LINK_NOARG(SvxColorTabPage, ClickSaveHdl_Impl) + OUString aStrFilterType( XPropertyList::GetDefaultExtFilter( meType ) ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" ); + + XPropertyListRef pList = GetList(); +diff --git a/cui/source/tabpages/tpgradnt.cxx b/cui/source/tabpages/tpgradnt.cxx +index e737410..380f36a 100644 +--- a/cui/source/tabpages/tpgradnt.cxx ++++ b/cui/source/tabpages/tpgradnt.cxx +@@ -655,7 +655,16 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickLoadHdl_Impl) + ::sfx2::FileDialogHelper aDlg( com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 ); + OUString aStrFilterType( "*.sog" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) ); + + if( aDlg.Execute() == ERRCODE_NONE ) +@@ -739,7 +748,16 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickSaveHdl_Impl) + OUString aStrFilterType( "*.sog" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" ); + + if( !pGradientList->GetName().isEmpty() ) +diff --git a/cui/source/tabpages/tphatch.cxx b/cui/source/tabpages/tphatch.cxx +index bad1e71..0060b36 100644 +--- a/cui/source/tabpages/tphatch.cxx ++++ b/cui/source/tabpages/tphatch.cxx +@@ -692,7 +692,16 @@ IMPL_LINK_NOARG(SvxHatchTabPage, ClickLoadHdl_Impl) + ::sfx2::FileDialogHelper aDlg( com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 ); + OUString aStrFilterType( "*.soh" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) ); + + if( aDlg.Execute() == ERRCODE_NONE ) +@@ -765,7 +774,16 @@ IMPL_LINK_NOARG(SvxHatchTabPage, ClickSaveHdl_Impl) + OUString aStrFilterType( "*.soh" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" ); + + if( !pHatchingList->GetName().isEmpty() ) +diff --git a/cui/source/tabpages/tplnedef.cxx b/cui/source/tabpages/tplnedef.cxx +index 6694a54..38a7c7f 100644 +--- a/cui/source/tabpages/tplnedef.cxx ++++ b/cui/source/tabpages/tplnedef.cxx +@@ -761,7 +761,16 @@ IMPL_LINK_NOARG(SvxLineDefTabPage, ClickLoadHdl_Impl) + ::sfx2::FileDialogHelper aDlg( com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 ); + OUString aStrFilterType( "*.sod" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) ); + + if( aDlg.Execute() == ERRCODE_NONE ) +@@ -821,7 +830,16 @@ IMPL_LINK_NOARG(SvxLineDefTabPage, ClickSaveHdl_Impl) + OUString aStrFilterType( "*.sod" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" ); + + if( !pDashList->GetName().isEmpty() ) +diff --git a/cui/source/tabpages/tplneend.cxx b/cui/source/tabpages/tplneend.cxx +index aff55b9..478ab46 100644 +--- a/cui/source/tabpages/tplneend.cxx ++++ b/cui/source/tabpages/tplneend.cxx +@@ -573,7 +573,17 @@ IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickLoadHdl_Impl) + ::sfx2::FileDialogHelper aDlg(com::sun::star::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, 0 ); + OUString aStrFilterType( "*.soe" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::NO_DECODE ) ); + + if( aDlg.Execute() == ERRCODE_NONE ) +@@ -633,7 +643,16 @@ IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickSaveHdl_Impl) + OUString aStrFilterType( "*.soe" ); + aDlg.AddFilter( aStrFilterType, aStrFilterType ); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ OUString aPalettePath(SvtPathOptions().GetPalettePath()); ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = aPalettePath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aFile(aLastDir); + DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" ); + + if( !pLineEndList->GetName().isEmpty() ) +diff --git a/extras/Package_palettes.mk b/extras/Package_palettes.mk +index bc317e2..5cf4c61 100644 +--- a/extras/Package_palettes.mk ++++ b/extras/Package_palettes.mk +@@ -9,7 +9,7 @@ + + $(eval $(call gb_Package_Package,extras_palettes,$(SRCDIR)/extras/source/palettes)) + +-$(eval $(call gb_Package_add_files,extras_palettes,$(LIBO_SHARE_PRESETS_FOLDER)/config,\ ++$(eval $(call gb_Package_add_files,extras_palettes,$(LIBO_SHARE_FOLDER)/palette,\ + arrowhd.soe \ + classic.sog \ + cmyk.soc \ +diff --git a/offapi/com/sun/star/util/XPathSettings.idl b/offapi/com/sun/star/util/XPathSettings.idl +index 5f202a3..d54c122 100644 +--- a/offapi/com/sun/star/util/XPathSettings.idl ++++ b/offapi/com/sun/star/util/XPathSettings.idl +@@ -89,7 +89,8 @@ published interface XPathSettings + [attribute] string Module; + + /** This is the path to the palette files *.SOB to *.SOF containing +- user-defined colors and patterns. */ ++ user-defined colors and patterns. The value can be more than ++ one path separated by a semicolon.*/ + [attribute] string Palette; + + /** Plugins are saved in these directories. The value can be more than +diff --git a/officecfg/registry/data/org/openoffice/Office/Paths.xcu b/officecfg/registry/data/org/openoffice/Office/Paths.xcu +index 6d739e6..965a629 100644 +--- a/officecfg/registry/data/org/openoffice/Office/Paths.xcu ++++ b/officecfg/registry/data/org/openoffice/Office/Paths.xcu +@@ -124,6 +124,9 @@ + + + ++ ++ ++ + + $(userurl)/config + +diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs +index 0bc0dc8..8922889 100644 +--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs ++++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs +@@ -1642,12 +1642,15 @@ + + $(progpath) + +- ++ + + Specifies the path to the palette files *.SOB to *.SOF + containing user-defined colors and patterns. + +- $(userurl)/config ++ ++ $(insturl)/@LIBO_SHARE_FOLDER@/palette ++ $(userurl)/config ++ + + + +diff --git a/sd/source/ui/dlg/PhotoAlbumDialog.cxx b/sd/source/ui/dlg/PhotoAlbumDialog.cxx +index d5dcd09..b29ea21 100644 +--- a/sd/source/ui/dlg/PhotoAlbumDialog.cxx ++++ b/sd/source/ui/dlg/PhotoAlbumDialog.cxx +@@ -480,7 +480,7 @@ IMPL_LINK_NOARG(SdPhotoAlbumDialog, FileHdl) + // Read configuration + OUString sUrl(officecfg::Office::Impress::Pictures::Path::get()); + +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ INetURLObject aFile( SvtPathOptions().GetUserConfigPath() ); + if (!sUrl.isEmpty()) + aDlg.SetDisplayDirectory(sUrl); + else +diff --git a/svx/source/sidebar/nbdtmg.cxx b/svx/source/sidebar/nbdtmg.cxx +index 7c7e2c4..9570c2b 100644 +--- a/svx/source/sidebar/nbdtmg.cxx ++++ b/svx/source/sidebar/nbdtmg.cxx +@@ -157,7 +157,7 @@ void NBOTypeMgrBase::ImplLoad(const OUString& filename) + bIsLoading = true; + SfxMapUnit eOldCoreUnit=eCoreUnit; + eCoreUnit = SFX_MAPUNIT_100TH_MM; +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ INetURLObject aFile( SvtPathOptions().GetUserConfigPath() ); + aFile.Append( filename); + std::unique_ptr xIStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::NO_DECODE ), StreamMode::READ )); + if( xIStm ) { +@@ -196,7 +196,7 @@ void NBOTypeMgrBase::ImplStore(const OUString& filename) + if (bIsLoading) return; + SfxMapUnit eOldCoreUnit=eCoreUnit; + eCoreUnit = SFX_MAPUNIT_100TH_MM; +- INetURLObject aFile( SvtPathOptions().GetPalettePath() ); ++ INetURLObject aFile( SvtPathOptions().GetUserConfigPath() ); + aFile.Append( filename); + std::unique_ptr xOStm(::utl::UcbStreamHelper::CreateStream( aFile.GetMainURL( INetURLObject::NO_DECODE ), StreamMode::WRITE )); + if( xOStm ) { +diff --git a/svx/source/tbxctrls/PaletteManager.cxx b/svx/source/tbxctrls/PaletteManager.cxx +index 109f934..3334afc 100644 +--- a/svx/source/tbxctrls/PaletteManager.cxx ++++ b/svx/source/tbxctrls/PaletteManager.cxx +@@ -27,6 +27,8 @@ + #include + #include + #include ++#include ++#include + + PaletteManager::PaletteManager() : + mnMaxRecentColors(Application::GetSettings().GetStyleSettings().GetColorValueSetColumnCount()), +@@ -47,31 +49,52 @@ PaletteManager::~PaletteManager() + void PaletteManager::LoadPalettes() + { + maPalettes.clear(); +- OUString aPalPath = SvtPathOptions().GetPalettePath(); +- +- osl::Directory aDir(aPalPath); +- osl::DirectoryItem aDirItem; +- osl::FileStatus aFileStat( osl_FileStatus_Mask_FileName | +- osl_FileStatus_Mask_FileURL | +- osl_FileStatus_Mask_Type ); +- if( aDir.open() == osl::FileBase::E_None ) ++ OUString aPalPaths = SvtPathOptions().GetPalettePath(); ++ ++ std::stack aDirs; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aDirs.push(aPalPaths.getToken(0, ';', nIndex)); ++ } ++ while (nIndex >= 0); ++ ++ std::set aNames; ++ //try all entries palette path list user first, then ++ //system, ignoring duplicate file names ++ while (!aDirs.empty()) + { +- while( aDir.getNextItem(aDirItem) == osl::FileBase::E_None ) ++ OUString aPalPath = aDirs.top(); ++ aDirs.pop(); ++ ++ osl::Directory aDir(aPalPath); ++ osl::DirectoryItem aDirItem; ++ osl::FileStatus aFileStat( osl_FileStatus_Mask_FileName | ++ osl_FileStatus_Mask_FileURL | ++ osl_FileStatus_Mask_Type ); ++ if( aDir.open() == osl::FileBase::E_None ) + { +- aDirItem.getFileStatus(aFileStat); +- if(aFileStat.isRegular() || aFileStat.isLink()) ++ while( aDir.getNextItem(aDirItem) == osl::FileBase::E_None ) + { +- OUString aFName = aFileStat.getFileName(); +- Palette* pPalette = 0; +- if( aFName.endsWithIgnoreAsciiCase(".gpl") ) +- pPalette = new PaletteGPL( aFileStat.getFileURL(), aFName ); +- else if( aFName.endsWithIgnoreAsciiCase(".soc") ) +- pPalette = new PaletteSOC( aFileStat.getFileURL(), aFName ); +- else if ( aFName.endsWithIgnoreAsciiCase(".ase") ) +- pPalette = new PaletteASE( aFileStat.getFileURL(), aFName ); +- +- if( pPalette && pPalette->IsValid() ) +- maPalettes.push_back( pPalette ); ++ aDirItem.getFileStatus(aFileStat); ++ if(aFileStat.isRegular() || aFileStat.isLink()) ++ { ++ OUString aFName = aFileStat.getFileName(); ++ if (aNames.find(aFName) == aNames.end()) ++ { ++ Palette* pPalette = 0; ++ if( aFName.endsWithIgnoreAsciiCase(".gpl") ) ++ pPalette = new PaletteGPL( aFileStat.getFileURL(), aFName ); ++ else if( aFName.endsWithIgnoreAsciiCase(".soc") ) ++ pPalette = new PaletteSOC( aFileStat.getFileURL(), aFName ); ++ else if ( aFName.endsWithIgnoreAsciiCase(".ase") ) ++ pPalette = new PaletteASE( aFileStat.getFileURL(), aFName ); ++ ++ if( pPalette && pPalette->IsValid() ) ++ maPalettes.push_back( pPalette ); ++ aNames.insert(aFName); ++ } ++ } + } + } + } +diff --git a/svx/source/xoutdev/xtable.cxx b/svx/source/xoutdev/xtable.cxx +index 5e35be9..b3f1416d 100644 +--- a/svx/source/xoutdev/xtable.cxx ++++ b/svx/source/xoutdev/xtable.cxx +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + using namespace com::sun::star; + +@@ -224,23 +225,41 @@ bool XPropertyList::Load() + if( mbListDirty ) + { + mbListDirty = false; ++ std::stack aDirs; + +- INetURLObject aURL( maPath ); +- +- if( INetProtocol::NotValid == aURL.GetProtocol() ) ++ sal_Int32 nIndex = 0; ++ do + { +- DBG_ASSERT( maPath.isEmpty(), "invalid URL" ); +- return false; ++ aDirs.push(maPath.getToken(0, ';', nIndex)); + } ++ while (nIndex >= 0); ++ ++ //try all entries palette path list working back to front until one ++ //succeeds ++ while (!aDirs.empty()) ++ { ++ OUString aPath(aDirs.top()); ++ aDirs.pop(); ++ ++ INetURLObject aURL(aPath); ++ ++ if( INetProtocol::NotValid == aURL.GetProtocol() ) ++ { ++ DBG_ASSERT( aPath.isEmpty(), "invalid URL" ); ++ return false; ++ } + +- aURL.Append( maName ); ++ aURL.Append( maName ); + +- if( aURL.getExtension().isEmpty() ) +- aURL.setExtension( GetDefaultExt() ); ++ if( aURL.getExtension().isEmpty() ) ++ aURL.setExtension( GetDefaultExt() ); + +- return SvxXMLXTableImport::load( aURL.GetMainURL( INetURLObject::NO_DECODE ), maReferer, +- uno::Reference < embed::XStorage >(), +- createInstance(), NULL ); ++ bool bRet = SvxXMLXTableImport::load(aURL.GetMainURL(INetURLObject::NO_DECODE), ++ maReferer, uno::Reference < embed::XStorage >(), ++ createInstance(), NULL ); ++ if (bRet) ++ return bRet; ++ } + } + return false; + } +@@ -256,11 +275,20 @@ bool XPropertyList::LoadFrom( const uno::Reference < embed::XStorage > &xStorage + + bool XPropertyList::Save() + { +- INetURLObject aURL( maPath ); ++ //save to the last path in the palette path list ++ OUString aLastDir; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ aLastDir = maPath.getToken(0, ';', nIndex); ++ } ++ while (nIndex >= 0); ++ ++ INetURLObject aURL(aLastDir); + + if( INetProtocol::NotValid == aURL.GetProtocol() ) + { +- DBG_ASSERT( maPath.isEmpty(), "invalid URL" ); ++ DBG_ASSERT( aLastDir.isEmpty(), "invalid URL" ); + return false; + } + +-- +2.4.0 + diff --git a/SOURCES/0001-Resolves-tdf-91778-drawing-the-background-over-an-ac.patch b/SOURCES/0001-Resolves-tdf-91778-drawing-the-background-over-an-ac.patch new file mode 100644 index 0000000..522ea58 --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-91778-drawing-the-background-over-an-ac.patch @@ -0,0 +1,52 @@ +From f34863825fca2002b420d10679d0cdbb9d767a81 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 20 Apr 2016 11:55:01 +0100 +Subject: [PATCH] Resolves: tdf#91778 drawing the background over an active + cursor + +will overwrite it, which means that when it toggles "off" afterwards, it uses +invert on the freshly drawn background which will visually make it appear "on" +and not off + +Just explictly turn it off and restore it and avoid the whole potential +problem. + +Change-Id: Ie21d77e9d704124011e43b42c98b26eaf208eef2 +(cherry picked from commit 29a9f433c268414747d8ec7343fc2b5987971738) +--- + sc/source/ui/view/gridwin4.cxx | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx +index ceaf3d8..5ec4bf0 100644 +--- a/sc/source/ui/view/gridwin4.cxx ++++ b/sc/source/ui/view/gridwin4.cxx +@@ -902,6 +902,14 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI + aEnd.X() -= 2 * nLayoutSign; + aEnd.Y() -= 2; + ++ // toggle the cursor off if its on to ensure the cursor invert ++ // background logic remains valid after the background is cleared on ++ // the next cursor flash ++ vcl::Cursor* pCrsr = pEditView->GetCursor(); ++ const bool bVisCursor = pCrsr && pCrsr->IsVisible(); ++ if (bVisCursor) ++ pCrsr->Hide(); ++ + // set the correct mapmode + Rectangle aBackground(aStart, aEnd); + if (bIsTiledRendering) +@@ -918,6 +926,10 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI + // paint the editeng text + pEditView->Paint(rDevice.PixelToLogic(Rectangle(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()))), &rDevice); + rDevice.SetMapMode(MAP_PIXEL); ++ ++ // restore the cursor it it was originally visible ++ if (bVisCursor) ++ pCrsr->Show(); + } + + if (pViewData->HasEditView(eWhich)) +-- +2.7.3 + diff --git a/SOURCES/0001-Resolves-tdf-94146-a11y-crash-obtain-formula-using-t.patch b/SOURCES/0001-Resolves-tdf-94146-a11y-crash-obtain-formula-using-t.patch new file mode 100644 index 0000000..69801eb --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-94146-a11y-crash-obtain-formula-using-t.patch @@ -0,0 +1,55 @@ +From 7581b5de05259dfcf65fc0d3b6fa565f74acaf8a Mon Sep 17 00:00:00 2001 +Message-Id: <7581b5de05259dfcf65fc0d3b6fa565f74acaf8a.1462364344.git.erack@redhat.com> +From: Eike Rathke +Date: Wed, 4 May 2016 13:41:59 +0200 +Subject: [PATCH] Resolves: tdf#94146 a11y crash, obtain formula using the + correct pointer +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------erAck-patch-parts" + +This is a multi-part message in MIME format. +--------------erAck-patch-parts +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +Fallout from IAccessible2 integration. Of the union, wrong string +pointer instead of formula cell pointer was used. + +Change-Id: I1afaf0ffff14a770ab52e8cbf880708bd66b3ef2 +(cherry picked from commit 3a767d91bfa70af4303b905cefa038181d56cc9a) +--- + sc/source/ui/view/tabvwsh.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + + +--------------erAck-patch-parts +Content-Type: text/x-patch; name="0001-Resolves-tdf-94146-a11y-crash-obtain-formula-using-t.patch" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="0001-Resolves-tdf-94146-a11y-crash-obtain-formula-using-t.patch" + +diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx +index 632757d..0675e69 100644 +--- a/sc/source/ui/view/tabvwsh.cxx ++++ b/sc/source/ui/view/tabvwsh.cxx +@@ -39,6 +39,7 @@ + #include "dwfunctr.hxx" + #include "sc.hrc" + #include "spelldialog.hxx" ++#include "formulacell.hxx" + #include + + #include +@@ -116,7 +117,7 @@ OUString ScTabViewShell::GetFormula(ScAddress& rAddress) + aCell.assign(*pDoc, rAddress); + if (!aCell.isEmpty() && aCell.meType == CELLTYPE_FORMULA) + { +- sFormula = aCell.mpString->getString(); ++ aCell.mpFormula->GetFormula( sFormula); + } + return sFormula; + } + +--------------erAck-patch-parts-- + + diff --git a/SOURCES/0001-Resolves-tdf-95682-spell-dialog-add-a-button-to-open.patch b/SOURCES/0001-Resolves-tdf-95682-spell-dialog-add-a-button-to-open.patch new file mode 100644 index 0000000..0fe5d9c --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-95682-spell-dialog-add-a-button-to-open.patch @@ -0,0 +1,480 @@ +From f46860e84df8548daa12f180f27deef7a1d708d3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 13 Nov 2015 09:56:01 +0000 +Subject: [PATCH] Resolves: tdf#95682 spell dialog: add a button to open + special character + +(cherry picked from commit b08b76774fbd253cba587207d471f9bf0c0b0a82) + +Change-Id: I0d070dee9e940b93b294c6b2de180005a5c2248e + +Related: tdf#95682 set edit to modified after insert symbol/paste + +Change-Id: If5892931649bde3d1fc00c0e5817149d0623cb1e +(cherry picked from commit de0a391137080a18e73f315b6dc5342b5b078574) + +clear VclPtr warning + +Change-Id: I13f08989034a656bc6f0ae6b556272802f4b8fc2 +(cherry picked from commit 9c7d3345b02bcf69f28bdbc956a7cedaabe894a0) +--- + cui/source/dialogs/SpellDialog.cxx | 54 ++++++++++++-- + cui/source/inc/SpellDialog.hxx | 8 +++ + cui/uiconfig/ui/spellingdialog.ui | 143 ++++++++++++++++++++----------------- + 3 files changed, 135 insertions(+), 70 deletions(-) + +diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx +index f8952df..7f09b7f 100644 +--- a/cui/source/dialogs/SpellDialog.cxx ++++ b/cui/source/dialogs/SpellDialog.cxx +@@ -222,6 +222,8 @@ SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow, + get(m_pOptionsPB, "options"); + get(m_pUndoPB, "undo"); + get(m_pClosePB, "close"); ++ get(m_pToolbar, "toolbar"); ++ m_pSentenceED->Init(m_pToolbar); + xSpell = LinguMgr::GetSpellChecker(); + pImpl = new SpellDialog_Impl; + +@@ -243,8 +245,6 @@ SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow, + LINK( this, SpellDialog, InitHdl ), NULL, true ); + } + +- +- + SpellDialog::~SpellDialog() + { + disposeOnce(); +@@ -282,6 +282,7 @@ void SpellDialog::dispose() + m_pOptionsPB.clear(); + m_pUndoPB.clear(); + m_pClosePB.clear(); ++ m_pToolbar.clear(); + SfxModelessDialog::dispose(); + } + +@@ -318,8 +319,6 @@ void SpellDialog::Init_Impl() + SvxGetChangeAllList()->clear(); + } + +- +- + void SpellDialog::UpdateBoxes_Impl() + { + sal_Int32 i; +@@ -443,6 +442,7 @@ void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence, bool bIgnoreCurrent + */ + IMPL_LINK( SpellDialog, InitHdl, SpellDialog *, ) + { ++ m_pToolbar->Disable(); + SetUpdateMode( false ); + //show or hide AutoCorrect depending on the modules abilities + m_pAutoCorrPB->Show(rParent.HasAutoCorrection()); +@@ -1219,6 +1219,11 @@ SentenceEditWindow_Impl::SentenceEditWindow_Impl(vcl::Window * pParent, WinBits + DisableSelectionOnFocus(); + } + ++SentenceEditWindow_Impl::~SentenceEditWindow_Impl() ++{ ++ disposeOnce(); ++} ++ + VCL_BUILDER_DECL_FACTORY(SentenceEditWindow) + { + (void)rMap; +@@ -1559,9 +1564,50 @@ bool SentenceEditWindow_Impl::PreNotify( NotifyEvent& rNEvt ) + else + bChange = false; + } ++ else if (rNEvt.GetType() == MouseNotifyEvent::GETFOCUS && m_xToolbar) ++ { ++ m_xToolbar->Enable(); ++ } ++ else if(rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS && m_xToolbar) ++ { ++ m_xToolbar->Disable(); ++ } + return bChange || VclMultiLineEdit::PreNotify(rNEvt); + } + ++void SentenceEditWindow_Impl::Init(VclPtr &rToolbar) ++{ ++ m_xToolbar = rToolbar; ++ m_xToolbar->SetSelectHdl(LINK(this,SentenceEditWindow_Impl,ToolbarHdl)); ++} ++ ++IMPL_LINK_NOARG_TYPED(SentenceEditWindow_Impl, ToolbarHdl, ToolBox *, void) ++{ ++ const sal_uInt16 nCurItemId = m_xToolbar->GetCurItemId(); ++ if (nCurItemId == m_xToolbar->GetItemId("paste")) ++ { ++ Paste(); ++ CallModifyLink(); ++ } ++ else if (nCurItemId == m_xToolbar->GetItemId("insert")) ++ { ++ if (Edit::GetGetSpecialCharsFunction()) ++ { ++ OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() ); ++ if (!aChars.isEmpty()) ++ { ++ ReplaceSelected(aChars); ++ CallModifyLink(); ++ } ++ } ++ } ++} ++ ++void SentenceEditWindow_Impl::dispose() ++{ ++ m_xToolbar.clear(); ++ VclMultiLineEdit::dispose(); ++} + + bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, com::sun::star::uno::Reference xSpell ) + { +diff --git a/cui/source/inc/SpellDialog.hxx b/cui/source/inc/SpellDialog.hxx +index 38a08cf..543581c 100644 +--- a/cui/source/inc/SpellDialog.hxx ++++ b/cui/source/inc/SpellDialog.hxx +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + + +@@ -62,6 +63,7 @@ class SentenceEditWindow_Impl : public VclMultiLineEdit + + private: + std::set< sal_uInt16 > m_aIgnoreErrorsAt; ++ VclPtr m_xToolbar; + sal_uInt16 m_nErrorStart; + sal_uInt16 m_nErrorEnd; + bool m_bIsUndoEditMode; +@@ -71,13 +73,17 @@ private: + void CallModifyLink() {m_aModifyLink.Call(this);} + + inline SpellDialog* GetSpellDialog() const; ++ ++ DECL_LINK_TYPED(ToolbarHdl, ToolBox*, void); + protected: + virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE; + + public: + SentenceEditWindow_Impl(vcl::Window* pParent, WinBits nBits); ++ ~SentenceEditWindow_Impl(); + + void SetModifyHdl(const Link<>& rLink) SAL_OVERRIDE { m_aModifyLink = rLink;} ++ void Init(VclPtr &rToolbar); + + void SetAttrib( const TextAttrib& rAttr, sal_uLong nPara, sal_uInt16 nStart, sal_uInt16 nEnd ); + void SetText( const OUString& rStr ) SAL_OVERRIDE; +@@ -96,6 +102,7 @@ public: + + void ResetModified() { GetTextEngine()->SetModified(false); m_bIsUndoEditMode = false;} + virtual bool IsModified() const SAL_OVERRIDE { return GetTextEngine()->IsModified(); } ++ virtual void dispose() SAL_OVERRIDE; + + bool IsUndoEditMode() const { return m_bIsUndoEditMode;} + void SetUndoEditMode(bool bSet); +@@ -151,6 +158,7 @@ private: + VclPtr m_pOptionsPB; + VclPtr m_pUndoPB; + VclPtr m_pClosePB; ++ VclPtr m_pToolbar; + + OUString m_sResumeST; + OUString m_sIgnoreOnceST; +diff --git a/cui/uiconfig/ui/spellingdialog.ui b/cui/uiconfig/ui/spellingdialog.ui +index 5d89284..94b5307 100644 +--- a/cui/uiconfig/ui/spellingdialog.ui ++++ b/cui/uiconfig/ui/spellingdialog.ui +@@ -1,8 +1,8 @@ + +- ++ + + +- ++ + + False + 6 +@@ -103,24 +103,6 @@ + + 1 + 0 +- 1 +- 1 +- +- +- +- +- True +- False +- 0 +- _Not in dictionary +- True +- sentence +- +- +- 0 +- 2 +- 3 +- 1 + + + +@@ -135,8 +117,6 @@ + + 2 + 3 +- 1 +- 1 + + + +@@ -154,22 +134,6 @@ + + + +- +- True +- False +- 0 +- _Suggestions +- True +- suggestionslb +- +- +- 0 +- 8 +- 3 +- 1 +- +- +- + + Co_rrect + True +@@ -181,8 +145,6 @@ + + 2 + 9 +- 1 +- 1 + + + +@@ -197,8 +159,6 @@ + + 2 + 10 +- 1 +- 1 + + + +@@ -213,8 +173,6 @@ + + 2 + 11 +- 1 +- 1 + + + +@@ -231,7 +189,6 @@ + 0 + 12 + 3 +- 1 + + + +@@ -246,8 +203,6 @@ + + 2 + 4 +- 1 +- 1 + + + +@@ -262,39 +217,34 @@ + + 2 + 5 +- 1 +- 1 + + + + + True + False +- 0 + Text languag_e: + True + languagelb ++ 0 + + + 0 + 0 +- 1 +- 1 + + + + + False + True +- 0 + True + True ++ 0 + + + 0 + 1 + 2 +- 1 + + + +@@ -309,8 +259,6 @@ + + 2 + 1 +- 1 +- 1 + + + +@@ -323,8 +271,6 @@ + + 0 + 13 +- 1 +- 1 + + + +@@ -337,8 +283,6 @@ + + 1 + 13 +- 1 +- 1 + + + +@@ -351,8 +295,6 @@ + + 2 + 13 +- 1 +- 1 + + + +@@ -384,8 +326,6 @@ + + 2 + 6 +- 1 +- 1 + + + +@@ -400,11 +340,82 @@ + + 2 + 7 +- 1 +- 1 + + + ++ ++ True ++ False ++ _Suggestions ++ True ++ suggestionslb ++ 0 ++ ++ ++ 0 ++ 8 ++ 3 ++ ++ ++ ++ ++ True ++ False ++ True ++ _Not in dictionary ++ True ++ sentence ++ 0 ++ ++ ++ 0 ++ 2 ++ ++ ++ ++ ++ True ++ False ++ end ++ icons ++ ++ ++ True ++ False ++ paste ++ Paste ++ True ++ cmd/sc_paste.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ True ++ False ++ insert ++ Special Character ++ True ++ cmd/sc_insertsymbol.png ++ ++ ++ False ++ True ++ ++ ++ ++ ++ 1 ++ 2 ++ ++ ++ ++ ++ ++ + + + +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-tdf-95962-incorrect-scanline-stride.patch b/SOURCES/0001-Resolves-tdf-95962-incorrect-scanline-stride.patch new file mode 100644 index 0000000..f6ffa32 --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-95962-incorrect-scanline-stride.patch @@ -0,0 +1,794 @@ +From beaba7e2e7a3248cbe87870c84b2c0df0a25503d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 25 Nov 2015 10:32:33 +0000 +Subject: [PATCH] Resolves: tdf#95962 incorrect scanline stride +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +gtk3: it's the *Original* device we care about, not the temp clip hack devices + +Change-Id: I2ac61cd2a99da25122165af692154fdbc2ac6d2e +(cherry picked from commit 872c1b7654510daa4a6974150490623745d931bf) + +we were reusing the stride of the surface we were cloning, +but the new surface has a different underlying size. + +remove the custom stride argument and just change our stride +calculation to use the same scheme that cairo and GDI uses, which +remove another platform/drawing-system variable + +Reviewed-on: https://gerrit.libreoffice.org/20149 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 9b52b8999be86e5c6e5f5901b2640b16f08a2323) + +Change-Id: I257dac9757b121642e9ccfde7db0911edc9f3fb1 +--- + basebmp/source/bitmapdevice.cxx | 25 +++++++------------------ + basebmp/test/basictest.cxx | 30 +++++++++++++----------------- + basebmp/test/bmpmasktest.cxx | 24 +++++++----------------- + basebmp/test/bmptest.cxx | 12 ++++-------- + basebmp/test/cliptest.cxx | 12 ++++-------- + basebmp/test/filltest.cxx | 6 ++---- + basebmp/test/linetest.cxx | 12 ++++-------- + basebmp/test/masktest.cxx | 9 +++------ + basebmp/test/polytest.cxx | 6 ++---- + include/basebmp/bitmapdevice.hxx | 9 +++------ + sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 2 +- + vcl/headless/svpbmp.cxx | 6 ++---- + vcl/headless/svpframe.cxx | 3 +-- + vcl/headless/svpgdi.cxx | 31 ++++++++++++++++--------------- + vcl/headless/svptextrender.cxx | 2 +- + vcl/headless/svpvd.cxx | 7 +++---- + vcl/qa/cppunit/BitmapTest.cxx | 15 +++++---------- + vcl/unx/gtk/window/gtksalframe.cxx | 3 +-- + 18 files changed, 79 insertions(+), 135 deletions(-) + +diff --git a/basebmp/source/bitmapdevice.cxx b/basebmp/source/bitmapdevice.cxx +index 04d4892..1517f05 100644 +--- a/basebmp/source/bitmapdevice.cxx ++++ b/basebmp/source/bitmapdevice.cxx +@@ -1956,7 +1956,6 @@ namespace + BitmapDeviceSharedPtr createBitmapDeviceImplInner( const basegfx::B2IVector& rSize, + bool bTopDown, + Format nScanlineFormat, +- sal_Int32 nScanlineStride, + boost::shared_array< sal_uInt8 > pMem, + PaletteMemorySharedVector pPal, + const basegfx::B2IBox* pSubset, +@@ -1977,6 +1976,8 @@ BitmapDeviceSharedPtr createBitmapDeviceImplInner( const basegfx::B2IVector& + return BitmapDeviceSharedPtr(); + } + ++ sal_Int32 nScanlineStride = getBitmapDeviceStrideForWidth(nScanlineFormat, rSize.getX()); ++ + // factor in bottom-up scanline order case + nScanlineStride *= bTopDown ? 1 : -1; + +@@ -2139,14 +2140,13 @@ BitmapDeviceSharedPtr createBitmapDeviceImplInner( const basegfx::B2IVector& + BitmapDeviceSharedPtr createBitmapDeviceImpl( const basegfx::B2IVector& rSize, + bool bTopDown, + Format nScanlineFormat, +- sal_Int32 nScanlineStride, + boost::shared_array< sal_uInt8 > pMem, + PaletteMemorySharedVector pPal, + const basegfx::B2IBox* pSubset, + const IBitmapDeviceDamageTrackerSharedPtr& rDamage, + bool bBlack = true) + { +- BitmapDeviceSharedPtr result( createBitmapDeviceImplInner( rSize, bTopDown, nScanlineFormat, nScanlineStride, pMem, pPal, pSubset, rDamage, bBlack ) ); ++ BitmapDeviceSharedPtr result( createBitmapDeviceImplInner( rSize, bTopDown, nScanlineFormat, pMem, pPal, pSubset, rDamage, bBlack ) ); + + #ifdef SAL_LOG_INFO + std::ostringstream subset; +@@ -2172,24 +2172,20 @@ sal_Int32 getBitmapDeviceStrideForWidth(Format nScanlineFormat, sal_Int32 nWidth + // round up to full 8 bit, divide by 8 + sal_Int32 nScanlineStride = (nWidth*nBitsPerPixel + 7) >> 3; + +- // rounded up to next full power-of-two number of bytes +- const sal_uInt32 bytesPerPixel = nextPow2( +- (bitsPerPixel[nScanlineFormat] + 7) >> 3); ++ // pixman (cairo) and GDI (windows) pad to multiples of 32bits ++ // so do the same to be easily compatible ++ nScanlineStride = (nScanlineStride + 3) & ~0x3; + +- // now make nScanlineStride a multiple of bytesPerPixel +- nScanlineStride = (nScanlineStride + bytesPerPixel - 1) / bytesPerPixel * bytesPerPixel; + return nScanlineStride; + } + + BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, +- Format nScanlineFormat, +- sal_Int32 nScanlineStride ) ++ Format nScanlineFormat ) + { + return createBitmapDeviceImpl( rSize, + bTopDown, + nScanlineFormat, +- nScanlineStride, + boost::shared_array< sal_uInt8 >(), + PaletteMemorySharedVector(), + NULL, +@@ -2199,13 +2195,11 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + Format nScanlineFormat, +- sal_Int32 nScanlineStride, + const PaletteMemorySharedVector& rPalette ) + { + return createBitmapDeviceImpl( rSize, + bTopDown, + nScanlineFormat, +- nScanlineStride, + boost::shared_array< sal_uInt8 >(), + rPalette, + NULL, +@@ -2215,14 +2209,12 @@ BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize + BitmapDeviceSharedPtr createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + Format nScanlineFormat, +- sal_Int32 nScanlineStride, + const RawMemorySharedArray& rMem, + const PaletteMemorySharedVector& rPalette ) + { + return createBitmapDeviceImpl( rSize, + bTopDown, + nScanlineFormat, +- nScanlineStride, + rMem, + rPalette, + NULL, +@@ -2235,7 +2227,6 @@ BitmapDeviceSharedPtr createClipDevice( const basegfx::B2IVector& rSize ) + createBitmapDeviceImpl( rSize, + false, /* bTopDown */ + basebmp::FORMAT_ONE_BIT_MSB_GREY, +- getBitmapDeviceStrideForWidth(basebmp::FORMAT_ONE_BIT_MSB_GREY, rSize.getX()), + boost::shared_array< sal_uInt8 >(), + PaletteMemorySharedVector(), + NULL, +@@ -2251,7 +2242,6 @@ BitmapDeviceSharedPtr subsetBitmapDevice( const BitmapDeviceSharedPtr& rProto, + return createBitmapDeviceImpl( rProto->getSize(), + rProto->isTopDown(), + rProto->getScanlineFormat(), +- rProto->getScanlineStride(), + rProto->getBuffer(), + rProto->getPalette(), + &rSubset, +@@ -2264,7 +2254,6 @@ BitmapDeviceSharedPtr cloneBitmapDevice( const basegfx::B2IVector& rSize, + return createBitmapDeviceImpl( rSize, + rProto->isTopDown(), + rProto->getScanlineFormat(), +- rProto->getScanlineStride(), + boost::shared_array< sal_uInt8 >(), + rProto->getPalette(), + NULL, +diff --git a/basebmp/test/basictest.cxx b/basebmp/test/basictest.cxx +index 293fbe5..671320d 100644 +--- a/basebmp/test/basictest.cxx ++++ b/basebmp/test/basictest.cxx +@@ -83,16 +83,19 @@ public: + basegfx::B2ISize aSize2(aSize); + BitmapDeviceSharedPtr pDevice( createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()))); ++ FORMAT_ONE_BIT_MSB_PAL ++ ) ); + CPPUNIT_ASSERT_MESSAGE("right size", + pDevice->getSize() == aSize2 ); + CPPUNIT_ASSERT_MESSAGE("Top down format", + pDevice->isTopDown() ); + CPPUNIT_ASSERT_MESSAGE("Scanline format", + pDevice->getScanlineFormat() == FORMAT_ONE_BIT_MSB_PAL ); ++ sal_Int32 nExpectedStride = (aSize2.getY() + 7)/8; ++ sal_Int32 nAlign = sizeof(sal_uInt32); ++ nExpectedStride = ((nExpectedStride + nAlign-1) / nAlign) * nAlign; + CPPUNIT_ASSERT_MESSAGE("Scanline len", +- pDevice->getScanlineStride() == (aSize2.getY() + 7)/8 ); ++ pDevice->getScanlineStride() == nExpectedStride ); + CPPUNIT_ASSERT_MESSAGE("Palette existence", + pDevice->getPalette() ); + CPPUNIT_ASSERT_MESSAGE("Palette entry 0 is black", +@@ -107,8 +110,7 @@ public: + basegfx::B2ISize aSize2(3,3); + BitmapDeviceSharedPtr pDevice( createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()))); ++ FORMAT_ONE_BIT_MSB_PAL) ); + + BitmapDeviceSharedPtr pClone( cloneBitmapDevice( + aSize2, +@@ -123,8 +125,7 @@ public: + const basegfx::B2ISize aSize(64,64); + BitmapDeviceSharedPtr pDevice( createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()))); ++ FORMAT_ONE_BIT_MSB_PAL) ); + + const basegfx::B2IPoint aPt(3,3); + CPPUNIT_ASSERT_MESSAGE("getPixelData for virgin device", +@@ -171,8 +172,7 @@ public: + { + pDevice = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_LSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_LSB_PAL, aSize.getX())); ++ FORMAT_ONE_BIT_LSB_PAL); + + pDevice->setPixel( aPt2, aCol, DrawMode_PAINT ); + CPPUNIT_ASSERT_MESSAGE("get/setPixel roundtrip #4", +@@ -197,8 +197,7 @@ public: + { + pDevice = createBitmapDevice( aSize, + true, +- FORMAT_EIGHT_BIT_GREY, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_EIGHT_BIT_GREY, aSize.getX())); ++ FORMAT_EIGHT_BIT_GREY); + + const Color aCol4(0x010101); + pDevice->setPixel( aPt, aCol4, DrawMode_PAINT ); +@@ -220,8 +219,7 @@ public: + { + pDevice = createBitmapDevice( aSize, + true, +- FORMAT_SIXTEEN_BIT_LSB_TC_MASK, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_SIXTEEN_BIT_LSB_TC_MASK, aSize.getX())); ++ FORMAT_SIXTEEN_BIT_LSB_TC_MASK); + const Color aCol7(0); + pDevice->clear( aCol7 ); + +@@ -245,8 +243,7 @@ public: + { + pDevice = createBitmapDevice( aSize, + true, +- FORMAT_TWENTYFOUR_BIT_TC_MASK, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_TWENTYFOUR_BIT_TC_MASK, aSize.getX())); ++ FORMAT_TWENTYFOUR_BIT_TC_MASK); + + const Color aCol4(0x01010101); + pDevice->setPixel( aPt, aCol4, DrawMode_PAINT ); +@@ -273,8 +270,7 @@ public: + { + pDevice = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX())); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA); + + const Color aCol4(0x01010101); + pDevice->setPixel( aPt, aCol4, DrawMode_PAINT ); +diff --git a/basebmp/test/bmpmasktest.cxx b/basebmp/test/bmpmasktest.cxx +index 611e189..ded87f8 100644 +--- a/basebmp/test/bmpmasktest.cxx ++++ b/basebmp/test/bmpmasktest.cxx +@@ -91,26 +91,21 @@ public: + const basegfx::B2ISize aSize(10,10); + mpDevice1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX())); ++ FORMAT_ONE_BIT_MSB_PAL); + mpDevice32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX())); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA); + + mpMaskBmp1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_GREY, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_GREY, aSize.getX())); ++ FORMAT_ONE_BIT_MSB_GREY); + + mpBmp1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX())); ++ FORMAT_ONE_BIT_MSB_PAL); + mpBmp32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX())); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA); + + OUString aSvg( "m 0 0h5v10h5v-5h-10z" ); + +@@ -169,7 +164,6 @@ public: + // nFormat = Format::OneBitMsbGrey; // FIXME - un-comment me to crash hard. + xMask = createBitmapDevice( aSize, false /* bTopDown */, + nFormat, +- basebmp::getBitmapDeviceStrideForWidth( nFormat, aSize.getX()), + PaletteMemorySharedVector( + new std::vector< basebmp::Color >(aDevPal) ) ); + // wipe to copy everything. +@@ -183,17 +177,13 @@ public: + DrawMode::DrawMode_PAINT ); + + xBitmap = createBitmapDevice( aSize, false, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX, +- basebmp::getBitmapDeviceStrideForWidth( +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX, aSize.getX() ) ); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX ); + xBitmap->clear(Color(0x80808080)); + } + { // mpOutput & mpBitmap + const basegfx::B2ISize aSize(9, 9); + xOutput = createBitmapDevice( aSize, false, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX, +- basebmp::getBitmapDeviceStrideForWidth( +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX, aSize.getX()) ); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX); + xOutput->clear(Color(0xffffffff)); + } + +diff --git a/basebmp/test/bmptest.cxx b/basebmp/test/bmptest.cxx +index 30644fb..f6ea0b6 100644 +--- a/basebmp/test/bmptest.cxx ++++ b/basebmp/test/bmptest.cxx +@@ -148,23 +148,19 @@ public: + void setUp() SAL_OVERRIDE + { + const basegfx::B2ISize aSize(10,10); +- sal_Int32 nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()); + mpDevice1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, nStride ); +- nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX()); ++ FORMAT_ONE_BIT_MSB_PAL ); + mpDevice32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, nStride ); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA); + +- nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()); + mpBmp1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, nStride ); +- nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX()); ++ FORMAT_ONE_BIT_MSB_PAL); + mpBmp32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, nStride ); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA ); + + OUString aSvg( "m 0 0h5v10h5v-5h-10z" ); + +diff --git a/basebmp/test/cliptest.cxx b/basebmp/test/cliptest.cxx +index 13ad48c..8526964 100644 +--- a/basebmp/test/cliptest.cxx ++++ b/basebmp/test/cliptest.cxx +@@ -154,10 +154,9 @@ private: + + void implTestMaskColorClip(const BitmapDeviceSharedPtr& rDevice) + { +- sal_Int32 nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_EIGHT_BIT_GREY, rDevice->getSize().getX()); + BitmapDeviceSharedPtr pBmp( createBitmapDevice( rDevice->getSize(), + true, +- FORMAT_EIGHT_BIT_GREY, nStride )); ++ FORMAT_EIGHT_BIT_GREY )); + + OUString aSvg( "m 0 0h5v10h5v-5h-10z" ); + +@@ -189,18 +188,15 @@ public: + void setUp() SAL_OVERRIDE + { + const basegfx::B2ISize aSize(11,11); +- sal_Int32 nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_GREY, aSize.getX()); + mpClipMask = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_GREY, nStride ); +- nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()); ++ FORMAT_ONE_BIT_MSB_GREY ); + mpDevice1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, nStride ); +- nStride = basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX()); ++ FORMAT_ONE_BIT_MSB_PAL ); + mpDevice32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, nStride ); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA ); + + OUString aSvg( "m 0 0 h5 l5 5 v5 h-5 l-5-5 z" ); + basegfx::B2DPolyPolygon aPoly; +diff --git a/basebmp/test/filltest.cxx b/basebmp/test/filltest.cxx +index 875a27d..067ec24 100644 +--- a/basebmp/test/filltest.cxx ++++ b/basebmp/test/filltest.cxx +@@ -211,12 +211,10 @@ public: + const basegfx::B2ISize aSize(11,11); + mpDevice1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX())); ++ FORMAT_ONE_BIT_MSB_PAL ); + mpDevice32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX())); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA ); + } + + void testRectFill() +diff --git a/basebmp/test/linetest.cxx b/basebmp/test/linetest.cxx +index 731158e..f6a3909 100644 +--- a/basebmp/test/linetest.cxx ++++ b/basebmp/test/linetest.cxx +@@ -151,12 +151,10 @@ public: + const basegfx::B2ISize aSize(11,11); + mpDevice1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()) ); ++ FORMAT_ONE_BIT_MSB_PAL ); + mpDevice32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX()) ); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA ); + } + + void testCornerCases() +@@ -165,8 +163,7 @@ public: + BitmapDeviceSharedPtr pDevice = createBitmapDevice( + aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()) ); ++ FORMAT_ONE_BIT_MSB_PAL ); + + const basegfx::B2IPoint aPt1(0,0); + const basegfx::B2IPoint aPt2(10,10); +@@ -182,8 +179,7 @@ public: + pDevice = createBitmapDevice( + aSize2, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX())); ++ FORMAT_ONE_BIT_MSB_PAL ); + + CPPUNIT_ASSERT_MESSAGE("only pixel cleared", + pDevice->getPixelData(aPt1) == 0); +diff --git a/basebmp/test/masktest.cxx b/basebmp/test/masktest.cxx +index 7b4559c..d53ba72 100644 +--- a/basebmp/test/masktest.cxx ++++ b/basebmp/test/masktest.cxx +@@ -104,17 +104,14 @@ public: + const basegfx::B2ISize aSize(10,10); + mpDevice1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX()) ); ++ FORMAT_ONE_BIT_MSB_PAL ); + mpDevice32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX()) ); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA ); + + mpMask = createBitmapDevice( aSize, + true, +- FORMAT_EIGHT_BIT_GREY, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_EIGHT_BIT_GREY, aSize.getX()) ); ++ FORMAT_EIGHT_BIT_GREY ); + + OUString aSvg( "m 0 0h5v10h5v-5h-10z" ); + +diff --git a/basebmp/test/polytest.cxx b/basebmp/test/polytest.cxx +index 60746d7..a0371eb 100644 +--- a/basebmp/test/polytest.cxx ++++ b/basebmp/test/polytest.cxx +@@ -296,12 +296,10 @@ public: + const basegfx::B2ISize aSize(10,10); + mpDevice1bpp = createBitmapDevice( aSize, + true, +- FORMAT_ONE_BIT_MSB_PAL, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_ONE_BIT_MSB_PAL, aSize.getX())); ++ FORMAT_ONE_BIT_MSB_PAL ); + mpDevice32bpp = createBitmapDevice( aSize, + true, +- FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, +- basebmp::getBitmapDeviceStrideForWidth(FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA, aSize.getX())); ++ FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA ); + } + + void testEmpty() +diff --git a/include/basebmp/bitmapdevice.hxx b/include/basebmp/bitmapdevice.hxx +index 5953741..6071c79 100644 +--- a/include/basebmp/bitmapdevice.hxx ++++ b/include/basebmp/bitmapdevice.hxx +@@ -668,8 +668,7 @@ sal_Int32 BASEBMP_DLLPUBLIC getBitmapDeviceStrideForWidth(Format nScanlineFormat + */ + BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, +- Format nScanlineFormat, +- sal_Int32 nScanlineStride ); ++ Format nScanlineFormat ); + + /** Function to create a BitmapDevice for given scanline format + with the given palette +@@ -681,7 +680,6 @@ BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC createBitmapDevice( const basegfx::B2IVe + BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + Format nScanlineFormat, +- sal_Int32 nScanlineStride, + const PaletteMemorySharedVector& rPalette ); + + /** Function to create a BitmapDevice for given scanline format +@@ -693,7 +691,6 @@ BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC createBitmapDevice( const basegfx::B2IVe + BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC createBitmapDevice( const basegfx::B2IVector& rSize, + bool bTopDown, + Format nScanlineFormat, +- sal_Int32 nScanlineStride, + const RawMemorySharedArray& rMem, + const PaletteMemorySharedVector& rPalette ); + +@@ -725,8 +722,8 @@ BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC subsetBitmapDevice( const BitmapDeviceSh + copied, only the size can be varied. Note that the prototype's + bitmap content is not copied, only a palette (if any). + */ +-BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC cloneBitmapDevice( const basegfx::B2IVector& rSize, +- const BitmapDeviceSharedPtr& rProto ); ++BitmapDeviceSharedPtr BASEBMP_DLLPUBLIC cloneBitmapDevice(const basegfx::B2IVector& rSize, ++ const BitmapDeviceSharedPtr& rProto); + + } + +diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +index 87435f5..b535187 100644 +--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx ++++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +@@ -771,7 +771,7 @@ DECLARE_OOXMLIMPORT_TEST(testN777345, "n777345.docx") + Graphic aGraphic(xGraphic); + // If this changes later, feel free to update it, but make sure it's not + // the checksum of a white/transparent placeholder rectangle. +- CPPUNIT_ASSERT_EQUAL(BitmapChecksum(3652741777587093783), aGraphic.GetChecksum()); ++ CPPUNIT_ASSERT_EQUAL(BitmapChecksum(SAL_CONST_UINT64(12149824012634930130)), aGraphic.GetChecksum()); + #endif + } + +diff --git a/vcl/headless/svpbmp.cxx b/vcl/headless/svpbmp.cxx +index 901526e..92c2835 100644 +--- a/vcl/headless/svpbmp.cxx ++++ b/vcl/headless/svpbmp.cxx +@@ -52,9 +52,8 @@ bool SvpSalBitmap::Create( const Size& rSize, + aSize.setX( 1 ); + if( aSize.getY() == 0 ) + aSize.setY( 1 ); +- sal_Int32 nStride = getBitmapDeviceStrideForWidth(nFormat, aSize.getX()); + if( nBitCount > 8 ) +- m_aBitmap = createBitmapDevice( aSize, false, nFormat, nStride ); ++ m_aBitmap = createBitmapDevice( aSize, false, nFormat ); + else + { + // prepare palette +@@ -67,7 +66,7 @@ bool SvpSalBitmap::Create( const Size& rSize, + const BitmapColor& rCol = rPalette[i]; + (*pPalette)[i] = basebmp::Color( rCol.GetRed(), rCol.GetGreen(), rCol.GetBlue() ); + } +- m_aBitmap = createBitmapDevice( aSize, false, nFormat, nStride, ++ m_aBitmap = createBitmapDevice( aSize, false, nFormat, + basebmp::RawMemorySharedArray(), + basebmp::PaletteMemorySharedVector( pPalette ) + ); +@@ -336,7 +335,6 @@ void SvpSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, BitmapAccessMode nMode + m_aBitmap = basebmp::createBitmapDevice( m_aBitmap->getSize(), + m_aBitmap->isTopDown(), + m_aBitmap->getScanlineFormat(), +- m_aBitmap->getScanlineStride(), + m_aBitmap->getBuffer(), + pPal ); + } +diff --git a/vcl/headless/svpframe.cxx b/vcl/headless/svpframe.cxx +index e1218d7..22ffaef 100644 +--- a/vcl/headless/svpframe.cxx ++++ b/vcl/headless/svpframe.cxx +@@ -292,8 +292,7 @@ void SvpSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u + aFrameSize.setX( 1 ); + if( aFrameSize.getY() == 0 ) + aFrameSize.setY( 1 ); +- sal_Int32 nStride = basebmp::getBitmapDeviceStrideForWidth(m_nScanlineFormat, aFrameSize.getX()); +- m_aFrame = createBitmapDevice( aFrameSize, m_bTopDown, m_nScanlineFormat, nStride ); ++ m_aFrame = createBitmapDevice( aFrameSize, m_bTopDown, m_nScanlineFormat ); + if (m_bDamageTracking) + m_aFrame->setDamageTracker( + basebmp::IBitmapDeviceDamageTrackerSharedPtr( new DamageTracker ) ); +diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx +index 0afce7e..cbe3dc1 100644 +--- a/vcl/headless/svpgdi.cxx ++++ b/vcl/headless/svpgdi.cxx +@@ -173,14 +173,14 @@ bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight, + return false; + } + +- cairo_t* cr = createCairoContext(m_aDevice); ++ cairo_t* cr = createCairoContext(m_aOrigDevice); + if (!cr) + return bRet; + +- if (!m_aDevice->isTopDown()) ++ if (!m_aOrigDevice->isTopDown()) + { + cairo_scale(cr, 1, -1.0); +- cairo_translate(cr, 0.0, -m_aDevice->getSize().getY()); ++ cairo_translate(cr, 0.0, -m_aOrigDevice->getSize().getY()); + } + + clipRegion(cr); +@@ -193,7 +193,7 @@ bool SvpSalGraphics::drawAlphaRect(long nX, long nY, long nWidth, long nHeight, + cairo_rectangle(cr, nX, nY, nWidth, nHeight); + + cairo_rectangle_int_t extents; +- basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aDevice->getDamageTracker()); ++ basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aOrigDevice->getDamageTracker()); + if (xDamageTracker) + extents = getFillDamage(cr); + +@@ -731,14 +731,14 @@ bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, d + return false; + } + +- cairo_t* cr = createCairoContext(m_aDevice); ++ cairo_t* cr = createCairoContext(m_aOrigDevice); + if (!cr) + return false; + +- if (!m_aDevice->isTopDown()) ++ if (!m_aOrigDevice->isTopDown()) + { + cairo_scale(cr, 1, -1.0); +- cairo_translate(cr, 0.0, -m_aDevice->getSize().getY()); ++ cairo_translate(cr, 0.0, -m_aOrigDevice->getSize().getY()); + } + + clipRegion(cr); +@@ -752,7 +752,7 @@ bool SvpSalGraphics::drawPolyPolygon(const basegfx::B2DPolyPolygon& rPolyPoly, d + AddPolygonToPath(cr, *pPoly, true); + + cairo_rectangle_int_t extents; +- basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aDevice->getDamageTracker()); ++ basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aOrigDevice->getDamageTracker()); + if (xDamageTracker) + extents = getFillDamage(cr); + +@@ -891,11 +891,12 @@ SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeigh + { + SvpSalBitmap* pBitmap = new SvpSalBitmap(); + +- if (m_aDevice) ++ if (m_aOrigDevice) + { + basebmp::BitmapDeviceSharedPtr aCopy; + aCopy = cloneBitmapDevice(basegfx::B2IVector(nWidth, nHeight), +- m_aDevice); ++ m_aOrigDevice); ++ basegfx::B2IVector size = aCopy->getSize(); + basegfx::B2IBox aSrcRect( nX, nY, nX+nWidth, nY+nHeight ); + basegfx::B2IBox aDestRect( 0, 0, nWidth, nHeight ); + +@@ -941,12 +942,12 @@ void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv + } + else if ( nFlags & SAL_INVERT_50 ) + { +- if (cairo_t* cr = createCairoContext(m_aDevice)) ++ if (cairo_t* cr = createCairoContext(m_aOrigDevice)) + { +- if (!m_aDevice->isTopDown()) ++ if (!m_aOrigDevice->isTopDown()) + { + cairo_scale(cr, 1, -1.0); +- cairo_translate(cr, 0.0, -m_aDevice->getSize().getY()); ++ cairo_translate(cr, 0.0, -m_aOrigDevice->getSize().getY()); + } + + clipRegion(cr); +@@ -954,7 +955,7 @@ void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv + cairo_pattern_t *pattern = create_stipple(); + + cairo_rectangle_int_t extents; +- basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aDevice->getDamageTracker()); ++ basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aOrigDevice->getDamageTracker()); + + cairo_rectangle(cr, nX, nY, nWidth, nHeight); + +@@ -1075,7 +1076,7 @@ bool SvpSalGraphics::supportsOperation(OutDevSupportType eType) const + #if ENABLE_CAIRO_CANVAS + if (m_aDrawMode == basebmp::DrawMode_XOR) + return false; +- if (!isCairoCompatible(m_aDevice)) ++ if (!isCairoCompatible(m_aOrigDevice)) + return false; + switch (eType) + { +diff --git a/vcl/headless/svptextrender.cxx b/vcl/headless/svptextrender.cxx +index f143da1..2cd51ef 100644 +--- a/vcl/headless/svptextrender.cxx ++++ b/vcl/headless/svptextrender.cxx +@@ -152,7 +152,7 @@ BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont, + pGcpHelper->maRawBitmap.mnScanlineSize, + pGcpHelper->maRawBitmap.mnHeight ); + static PaletteMemorySharedVector aDummyPAL; +- pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, aSize.getX(), pGcpHelper->maRawBitmap.mpBits, aDummyPAL ); ++ pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, pGcpHelper->maRawBitmap.mpBits, aDummyPAL ); + } + + rGlyphData.ExtDataRef().meInfo = nBmpFormat; +diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx +index 1e4050a..1c4237b 100644 +--- a/vcl/headless/svpvd.cxx ++++ b/vcl/headless/svpvd.cxx +@@ -71,21 +71,20 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY, + SvpSalInstance* pInst = SvpSalInstance::s_pDefaultInstance; + assert( pInst ); + basebmp::Format nFormat = pInst->getFormatForBitCount( m_nBitCount ); +- sal_Int32 nStride = basebmp::getBitmapDeviceStrideForWidth(nFormat, aDevSize.getX()); + + if ( m_nBitCount == 1 ) + { + std::vector< basebmp::Color > aDevPal(2); + aDevPal[0] = basebmp::Color( 0, 0, 0 ); + aDevPal[1] = basebmp::Color( 0xff, 0xff, 0xff ); +- m_aDevice = createBitmapDevice( aDevSize, bTopDown, nFormat, nStride, ++ m_aDevice = createBitmapDevice( aDevSize, bTopDown, nFormat, + PaletteMemorySharedVector( new std::vector< basebmp::Color >(aDevPal) ) ); + } + else + { + m_aDevice = pBuffer ? +- createBitmapDevice( aDevSize, bTopDown, nFormat, nStride, pBuffer, PaletteMemorySharedVector() ) +- : createBitmapDevice( aDevSize, bTopDown, nFormat, nStride ); ++ createBitmapDevice( aDevSize, bTopDown, nFormat, pBuffer, PaletteMemorySharedVector() ) ++ : createBitmapDevice( aDevSize, bTopDown, nFormat ); + } + + // update device in existing graphics +diff --git a/vcl/qa/cppunit/BitmapTest.cxx b/vcl/qa/cppunit/BitmapTest.cxx +index a5437c1..384afc7 100644 +--- a/vcl/qa/cppunit/BitmapTest.cxx ++++ b/vcl/qa/cppunit/BitmapTest.cxx +@@ -51,17 +51,12 @@ void BitmapTest::testConvert() + { + Bitmap::ScopedReadAccess pReadAccess(aBitmap); + CPPUNIT_ASSERT_EQUAL(static_cast(8), pReadAccess->GetBitCount()); +-#if defined WNT +- if (!OpenGLHelper::isVCLOpenGLEnabled()) +- { +- // GDI Scanlines padded to DWORD multiples, it seems +- CPPUNIT_ASSERT_EQUAL(static_cast(12), pReadAccess->GetScanlineSize()); +- } +- else ++#if defined MACOSX || defined IOS ++ //it would be nice to find and change the stride for quartz to be the same as everyone else ++ CPPUNIT_ASSERT_EQUAL(static_cast(10), pReadAccess->GetScanlineSize()); ++#else ++ CPPUNIT_ASSERT_EQUAL(static_cast(12), pReadAccess->GetScanlineSize()); + #endif +- { +- CPPUNIT_ASSERT_EQUAL(static_cast(10), pReadAccess->GetScanlineSize()); +- } + CPPUNIT_ASSERT(pReadAccess->HasPalette()); + const BitmapColor& rColor = pReadAccess->GetPaletteColor(pReadAccess->GetPixelIndex(1, 1)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(204), sal_Int32(rColor.GetRed())); +diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx +index a28c144..eef48cd 100644 +--- a/vcl/unx/gtk/window/gtksalframe.cxx ++++ b/vcl/unx/gtk/window/gtksalframe.cxx +@@ -2063,9 +2063,8 @@ void GtkSalFrame::AllocateFrame() + aFrameSize.setX( 1 ); + if( aFrameSize.getY() == 0 ) + aFrameSize.setY( 1 ); +- int cairo_stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, aFrameSize.getX()); + m_aFrame = basebmp::createBitmapDevice(aFrameSize, true, +- basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX, cairo_stride); ++ basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX); + m_aFrame->setDamageTracker( + basebmp::IBitmapDeviceDamageTrackerSharedPtr(new DamageTracker(*this)) ); + SAL_INFO("vcl.gtk3", "allocated m_aFrame size of " << maGeometry.nWidth << " x " << maGeometry.nHeight); +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-tdf-96285-restore-bodge-for-unresizable-win.patch b/SOURCES/0001-Resolves-tdf-96285-restore-bodge-for-unresizable-win.patch new file mode 100644 index 0000000..34af44b --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-96285-restore-bodge-for-unresizable-win.patch @@ -0,0 +1,83 @@ +From b7c0576a8e8f39171b94d08fddea868da0459597 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 8 Dec 2015 13:09:34 +0000 +Subject: [PATCH] Resolves: tdf#96285 restore bodge for unresizable windows + with no min size set + +(cherry picked from commit e1df21cfe0318bf287ae8ce29261d4759c49bd5a) + +Change-Id: Ia1af11514f6096ac55d561f729bbcba9ee5b0b14 +--- + vcl/inc/unx/gtk/gtkframe.hxx | 2 ++ + vcl/unx/gtk3/gtk3gtkframe.cxx | 21 ++++++++++++++++++++- + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index 0fb5da7..3bd5353 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -212,6 +212,8 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + + #if GTK_CHECK_VERSION(3,0,0) + guint32 m_nLastScrollEventTime; ++ long m_nWidthRequest; ++ long m_nHeightRequest; + cairo_region_t* m_pRegion; + #else + GdkRegion* m_pRegion; +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index dcfebbf..1443054 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -885,6 +885,8 @@ void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) + + void GtkSalFrame::window_resize(long nWidth, long nHeight) + { ++ m_nWidthRequest = nWidth; ++ m_nHeightRequest = nHeight; + gtk_window_resize(GTK_WINDOW(m_pWindow), nWidth, nHeight); + } + +@@ -1055,6 +1057,9 @@ void GtkSalFrame::InitCommon() + m_aSystemData.pAppContext = NULL; + m_aSystemData.pShellWidget = m_aSystemData.pWidget; + ++ m_nWidthRequest = 0; ++ m_nHeightRequest = 0; ++ + // fake an initial geometry, gets updated via configure event or SetPosSize + if( m_bDefaultPos || m_bDefaultSize ) + { +@@ -1592,6 +1597,20 @@ void GtkSalFrame::setMinMaxSize() + aHints |= GDK_HINT_MAX_SIZE; + } + } ++ else ++ { ++ if (!m_bFullscreen && m_nWidthRequest && m_nHeightRequest) ++ { ++ aGeo.min_width = m_nWidthRequest; ++ aGeo.min_height = m_nHeightRequest; ++ aHints |= GDK_HINT_MIN_SIZE; ++ ++ aGeo.max_width = m_nWidthRequest; ++ aGeo.max_height = m_nHeightRequest; ++ aHints |= GDK_HINT_MAX_SIZE; ++ } ++ } ++ + if( m_bFullscreen && m_aMaxSize.Width() && m_aMaxSize.Height() ) + { + aGeo.max_width = m_aMaxSize.Width(); +@@ -1623,7 +1642,7 @@ void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) + m_aMinSize = Size( nWidth, nHeight ); + if( m_pWindow ) + { +- widget_set_size_request(nWidth, nHeight ); ++ widget_set_size_request(nWidth, nHeight); + setMinMaxSize(); + } + } +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves-tdf-96989-videos-playback-at-maximum-possib.patch b/SOURCES/0001-Resolves-tdf-96989-videos-playback-at-maximum-possib.patch new file mode 100644 index 0000000..90ddbb4 --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-96989-videos-playback-at-maximum-possib.patch @@ -0,0 +1,192 @@ +From b09dbbfb58d67d1640709f71a7053a7ccea70cec Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 17 Mar 2016 12:21:16 +0000 +Subject: [PATCH] Resolves: tdf#96989 videos playback at maximum possible + volume + +On systems with flat-volumes then setting the volume directly on the playbin to +100% results in resetting the global volume to the maximum possible volume. + +We expect to set as % of the current system volume. Putting an intermediate +volume object into the pipeline does the more expected thing. + +(cherry picked from commit d4b48e0de7f817c0d4607382724778acf191f9f8) + +Change-Id: I911d6fffba0983e4fd7b455e820959a96115de34 +--- + avmedia/source/gstreamer/gstplayer.cxx | 90 ++++++++++++++++++++-------------- + avmedia/source/gstreamer/gstplayer.hxx | 1 + + 2 files changed, 54 insertions(+), 37 deletions(-) + +diff --git a/avmedia/source/gstreamer/gstplayer.cxx b/avmedia/source/gstreamer/gstplayer.cxx +index b820ae1..50f54ea 100644 +--- a/avmedia/source/gstreamer/gstplayer.cxx ++++ b/avmedia/source/gstreamer/gstplayer.cxx +@@ -131,7 +131,7 @@ void MissingPluginInstaller::report( + { + // assert(gst_is_missing_plugin_message(message)); + gchar * det = gst_missing_plugin_message_get_installer_detail(message); +- if (det == nullptr) { ++ if (det == NULL) { + SAL_WARN( + "avmedia.gstreamer", + "gst_missing_plugin_message_get_installer_detail failed"); +@@ -268,8 +268,8 @@ void MissingPluginInstallerThread::execute() { + for (auto const & i: details) { + args.push_back(const_cast(i.getStr())); + } +- args.push_back(nullptr); +- gst_install_plugins_sync(args.data(), nullptr); ++ args.push_back(NULL); ++ gst_install_plugins_sync(args.data(), NULL); + { + osl::MutexGuard g(inst.mutex_); + if (inst.queued_.empty() || inst.launchNewThread_) { +@@ -290,6 +290,7 @@ Player::Player( const uno::Reference< lang::XMultiServiceFactory >& rxMgr ) : + GstPlayer_BASE( m_aMutex ), + mxMgr( rxMgr ), + mpPlaybin( NULL ), ++ mpVolumeControl( NULL ), + mbFakeVideo (false ), + mnUnmutedVolume( 0 ), + mbPlayPending ( false ), +@@ -351,6 +352,7 @@ void SAL_CALL Player::disposing() + g_object_unref( G_OBJECT( mpPlaybin ) ); + + mpPlaybin = NULL; ++ mpVolumeControl = NULL; + } + + if( mpXOverlay ) { +@@ -576,41 +578,55 @@ GstBusSyncReply Player::processSyncMessage( GstMessage *message ) + + void Player::preparePlaybin( const OUString& rURL, GstElement *pSink ) + { +- GstBus *pBus; ++ GstBus *pBus; + +- if( mpPlaybin != NULL ) { +- gst_element_set_state( mpPlaybin, GST_STATE_NULL ); +- mbPlayPending = false; +- g_object_unref( mpPlaybin ); +- } ++ if( mpPlaybin != NULL ) { ++ gst_element_set_state( mpPlaybin, GST_STATE_NULL ); ++ mbPlayPending = false; ++ g_object_unref( mpPlaybin ); ++ } + +- mpPlaybin = gst_element_factory_make( "playbin", NULL ); +- if( pSink != NULL ) // used for getting preferred size etc. +- { +- g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pSink, NULL ); +- mbFakeVideo = true; +- } +- else +- mbFakeVideo = false; ++ mpPlaybin = gst_element_factory_make( "playbin", NULL ); ++ ++ //tdf#96989 on systems with flat-volumes setting the volume directly on the ++ //playbin to 100% results in setting the global volums to 100% of the ++ //maximum. We expect to set as % of the current volume. ++ mpVolumeControl = gst_element_factory_make( "volume", NULL ); ++ GstElement *pAudioSink = gst_element_factory_make( "autoaudiosink", NULL ); ++ GstElement* pAudioOutput = gst_bin_new("audio-output-bin"); ++ gst_bin_add_many(GST_BIN(pAudioOutput), mpVolumeControl, pAudioSink, NULL); ++ gst_element_link(mpVolumeControl, pAudioSink); ++ GstPad *pPad = gst_element_get_static_pad(mpVolumeControl, "sink"); ++ gst_element_add_pad(GST_ELEMENT(pAudioOutput), gst_ghost_pad_new("sink", pPad)); ++ gst_object_unref(GST_OBJECT(pPad)); ++ g_object_set(G_OBJECT(mpPlaybin), "audio-sink", pAudioOutput, NULL); ++ ++ if( pSink != NULL ) // used for getting preferred size etc. ++ { ++ g_object_set( G_OBJECT( mpPlaybin ), "video-sink", pSink, NULL ); ++ mbFakeVideo = true; ++ } ++ else ++ mbFakeVideo = false; + +- OString ascURL = OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ); +- g_object_set( G_OBJECT( mpPlaybin ), "uri", ascURL.getStr() , NULL ); ++ OString ascURL = OUStringToOString( rURL, RTL_TEXTENCODING_UTF8 ); ++ g_object_set( G_OBJECT( mpPlaybin ), "uri", ascURL.getStr() , NULL ); + +- pBus = gst_element_get_bus( mpPlaybin ); +- if (mbWatchID) +- { +- g_source_remove(mnWatchID); +- mbWatchID = false; +- } +- mnWatchID = gst_bus_add_watch( pBus, pipeline_bus_callback, this ); +- mbWatchID = true; +- DBG( "%p set sync handler", this ); ++ pBus = gst_element_get_bus( mpPlaybin ); ++ if (mbWatchID) ++ { ++ g_source_remove(mnWatchID); ++ mbWatchID = false; ++ } ++ mnWatchID = gst_bus_add_watch( pBus, pipeline_bus_callback, this ); ++ mbWatchID = true; ++ DBG( "%p set sync handler", this ); + #ifdef AVMEDIA_GST_0_10 +- gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this ); ++ gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this ); + #else +- gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this, NULL ); ++ gst_bus_set_sync_handler( pBus, pipeline_bus_sync_handler, this, NULL ); + #endif +- g_object_unref( pBus ); ++ g_object_unref( pBus ); + } + + bool Player::create( const OUString& rURL ) +@@ -784,7 +800,7 @@ void SAL_CALL Player::setMute( sal_Bool bSet ) + nVolume = 0.0; + } + +- g_object_set( G_OBJECT( mpPlaybin ), "volume", nVolume, NULL ); ++ g_object_set( G_OBJECT( mpVolumeControl ), "volume", nVolume, NULL); + + mbMuted = bSet; + } +@@ -812,10 +828,10 @@ void SAL_CALL Player::setVolumeDB( sal_Int16 nVolumeDB ) + DBG( "set volume: %d gst volume: %lf", nVolumeDB, mnUnmutedVolume ); + + // change volume +- if( !mbMuted && mpPlaybin ) +- { +- g_object_set( G_OBJECT( mpPlaybin ), "volume", (gdouble) mnUnmutedVolume, NULL ); +- } ++ if( !mbMuted && mpPlaybin ) ++ { ++ g_object_set( G_OBJECT( mpVolumeControl ), "volume", mnUnmutedVolume, NULL ); ++ } + } + + +@@ -830,7 +846,7 @@ sal_Int16 SAL_CALL Player::getVolumeDB() + if( mpPlaybin ) { + double nGstVolume = 0.0; + +- g_object_get( G_OBJECT( mpPlaybin ), "volume", &nGstVolume, NULL ); ++ g_object_get( G_OBJECT( mpVolumeControl ), "volume", &nGstVolume, NULL ); + + nVolumeDB = (sal_Int16) ( 20.0*log10 ( nGstVolume ) ); + } +diff --git a/avmedia/source/gstreamer/gstplayer.hxx b/avmedia/source/gstreamer/gstplayer.hxx +index c5fc4f6..ed60e79 100644 +--- a/avmedia/source/gstreamer/gstplayer.hxx ++++ b/avmedia/source/gstreamer/gstplayer.hxx +@@ -83,6 +83,7 @@ protected: + + // Add elements and pipeline here + GstElement* mpPlaybin; // the playbin is also a pipeline ++ GstElement* mpVolumeControl; // the playbin is also a pipeline + bool mbFakeVideo; + + gdouble mnUnmutedVolume; +-- +2.7.1 + diff --git a/SOURCES/0001-Resolves-tdf-99417-explicitly-track-formula-cells-fo.patch b/SOURCES/0001-Resolves-tdf-99417-explicitly-track-formula-cells-fo.patch new file mode 100644 index 0000000..731f055 --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-99417-explicitly-track-formula-cells-fo.patch @@ -0,0 +1,56 @@ +From 388129064d30cd28ce9011ca459b19c238b9d005 Mon Sep 17 00:00:00 2001 +Message-Id: <388129064d30cd28ce9011ca459b19c238b9d005.1462273102.git.erack@redhat.com> +From: Eike Rathke +Date: Mon, 2 May 2016 16:25:01 +0200 +Subject: [PATCH] Resolves: tdf#99417 explicitly track formula cells for + BROADCAST_BROADCASTERS +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------erAck-patch-parts" + +This is a multi-part message in MIME format. +--------------erAck-patch-parts +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +Change-Id: I717fc6d1d7c2bc01ed2a256f6fc08a055be24e4b +(cherry picked from commit a0b9fa819c9193dee1405cee13690adf00e2d9b9) +Reviewed-on: https://gerrit.libreoffice.org/24592 +Reviewed-by: Markus Mohrhard +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +--- + sc/source/core/data/column.cxx | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + + +--------------erAck-patch-parts +Content-Type: text/x-patch; name="0001-Resolves-tdf-99417-explicitly-track-formula-cells-fo.patch" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="0001-Resolves-tdf-99417-explicitly-track-formula-cells-fo.patch" + +diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx +index 3a7daf1..48fb280 100644 +--- a/sc/source/core/data/column.cxx ++++ b/sc/source/core/data/column.cxx +@@ -3165,7 +3165,14 @@ void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, BroadcastMode eMode ) + sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aHdl); + // Broadcast all broadcasters in range. + ScHint aHint( SC_HINT_DATACHANGED, ScAddress( nCol, nRow1, nTab)); +- BroadcastBroadcasters( nRow1, nRow2, aHint); ++ if (BroadcastBroadcasters( nRow1, nRow2, aHint)) ++ { ++ // SetDirtyOnRangeHandler implicitly tracks notified ++ // formulas via ScDocument::Broadcast(), which ++ // BroadcastBroadcastersHandler doesn't, so explicitly ++ // track them here. ++ pDocument->TrackFormulas(); ++ } + } + break; + } + +--------------erAck-patch-parts-- + + diff --git a/SOURCES/0001-Resolves-tdf-99498-don-t-overwrite-trwWidth-value-if.patch b/SOURCES/0001-Resolves-tdf-99498-don-t-overwrite-trwWidth-value-if.patch new file mode 100644 index 0000000..20f426f --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-99498-don-t-overwrite-trwWidth-value-if.patch @@ -0,0 +1,72 @@ +From b5d3739516032e8863ee60e0c614dd1ec9e262a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 27 Apr 2016 14:50:05 +0100 +Subject: [PATCH] Resolves: tdf#99498 don't overwrite trwWidth value if set on + a table + +Change-Id: Ia39da999a2de1ca2b8bec5fc7f35d2f9ffe2dd19 +--- + sw/qa/extras/rtfimport/rtfimport.cxx | 10 ++++++++++ + writerfilter/source/rtftok/rtfdocumentimpl.cxx | 18 ++++++++++++++---- + 2 files changed, 24 insertions(+), 4 deletions(-) + +diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx +index 4236a48..07dd0da 100644 +--- a/sw/qa/extras/rtfimport/rtfimport.cxx ++++ b/sw/qa/extras/rtfimport/rtfimport.cxx +@@ -2388,6 +2388,16 @@ DECLARE_RTFIMPORT_TEST(testTdf96308Tabpos, "tdf96308-tabpos.rtf") + CPPUNIT_ASSERT(!aTabStops.hasElements()); + } + ++DECLARE_RTFIMPORT_TEST(testTdf99498, "tdf99498.rtf") ++{ ++ uno::Reference xTextTablesSupplier(mxComponent, uno::UNO_QUERY); ++ uno::Reference xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); ++ ++ // Table width should be 7056 ++ CPPUNIT_ASSERT_EQUAL(sal_Int32(7056), getProperty(xTables->getByIndex(0), "Width")); ++} ++ ++ + DECLARE_RTFIMPORT_TEST(testTdf87034, "tdf87034.rtf") + { + // This was A1BC34D, i.e. the first "super" text portion was mis-imported, +diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx +index 799186d..f292e9d 100644 +--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx ++++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx +@@ -1368,10 +1368,14 @@ void RTFDocumentImpl::prepareProperties( + } + + // Table width. +- auto pUnitValue = std::make_shared(3); +- lcl_putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pUnitValue); +- auto pWValue = std::make_shared(nCurrentCellX); +- lcl_putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pWValue); ++ RTFValue::Pointer_t const pTableWidthProps = rState.aTableRowSprms.find(NS_ooxml::LN_CT_TblPrBase_tblW); ++ if (!pTableWidthProps.get()) ++ { ++ auto pUnitValue = std::make_shared(3); ++ lcl_putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pUnitValue); ++ auto pWValue = std::make_shared(nCurrentCellX); ++ lcl_putNestedAttribute(rState.aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pWValue); ++ } + + auto pRowValue = std::make_shared(1); + if (nCells > 0) +@@ -4783,6 +4787,12 @@ RTFError RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) + lcl_putNestedSprm(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblCellMar, NS_ooxml::LN_CT_TblCellMar_right, std::make_shared(aAttributes)); + } + break; ++ case RTF_TRFTSWIDTH: ++ lcl_putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_type, pIntValue); ++ break; ++ case RTF_TRWWIDTH: ++ lcl_putNestedAttribute(m_aStates.top().aTableRowSprms, NS_ooxml::LN_CT_TblPrBase_tblW, NS_ooxml::LN_CT_TblWidth_w, pIntValue); ++ break; + default: + { + SAL_INFO("writerfilter", "TODO handle value '" << lcl_RtfToString(nKeyword) << "'"); +-- +2.7.3 + diff --git a/SOURCES/0001-Resolves-tdf-99604-ungrab-modal-dialogs.patch b/SOURCES/0001-Resolves-tdf-99604-ungrab-modal-dialogs.patch new file mode 100644 index 0000000..0433c6a --- /dev/null +++ b/SOURCES/0001-Resolves-tdf-99604-ungrab-modal-dialogs.patch @@ -0,0 +1,31 @@ +From c0d8f3643a634c062f094e97ea1a4d60e5e64916 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 19 Jan 2016 13:22:10 +0000 +Subject: [PATCH] Resolves: tdf#99604 ungrab modal dialogs + +Change-Id: I6735913c371968745da3ad6bf61e6ae3287c19a6 +--- + vcl/unx/gtk3/gtk3gtkframe.cxx | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index 6012f58..803542d 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -2367,6 +2367,13 @@ void GtkSalFrame::SetModal(bool bModal) + if (!m_pWindow) + return; + gtk_window_set_modal(GTK_WINDOW(m_pWindow), bModal); ++ if (bModal) ++ { ++ //gtk_window_set_modal bTrue adds a grab, so ungrab here. Quite ++ //possibly we should alternatively call grab_add grab_ungrab on ++ //show/hide of menus ? ++ gtk_grab_remove(m_pWindow); ++ } + } + + gboolean GtkSalFrame::signalTooltipQuery(GtkWidget*, gint /*x*/, gint /*y*/, +-- +2.5.0 + diff --git a/SOURCES/0001-Resolves_rhbz-1437537-fix-csv-a11y.patch b/SOURCES/0001-Resolves_rhbz-1437537-fix-csv-a11y.patch new file mode 100644 index 0000000..e18c10f --- /dev/null +++ b/SOURCES/0001-Resolves_rhbz-1437537-fix-csv-a11y.patch @@ -0,0 +1,130 @@ +From dade1c7a39363610e5f04bf8cd99c9aaf3a33aab Mon Sep 17 00:00:00 2001 +From: rpmbuild +Date: Fri, 31 Mar 2017 17:10:46 +0100 +Subject: [PATCH] Resolves: rhbz#1437537 fix csv a11y + +--- + .../ui/Accessibility/AccessibleCsvControl.cxx | 33 +++++++++++++++++++--- + sc/source/ui/inc/AccessibleCsvControl.hxx | 9 ++++++ + 3 files changed, 49 insertions(+), 18 deletions(-) + mode change 100644 => 100755 config.sub + +diff --git a/sc/source/ui/Accessibility/AccessibleCsvControl.cxx b/sc/source/ui/Accessibility/AccessibleCsvControl.cxx +index bb924f2..4bc75f3 100644 +--- a/sc/source/ui/Accessibility/AccessibleCsvControl.cxx ++++ b/sc/source/ui/Accessibility/AccessibleCsvControl.cxx +@@ -865,6 +865,15 @@ ScAccessibleCsvGrid::~ScAccessibleCsvGrid() + implDispose(); + } + ++void ScAccessibleCsvGrid::disposing() ++{ ++ SolarMutexGuard aGuard; ++ for (XAccessibleSet::iterator aI = maAccessibleChildren.begin(); aI != maAccessibleChildren.end(); ++aI) ++ aI->second->dispose(); ++ maAccessibleChildren.clear(); ++ ScAccessibleCsvControl::disposing(); ++} ++ + // XAccessibleComponent ------------------------------------------------------- + + Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( const AwtPoint& rPoint ) +@@ -882,7 +891,7 @@ Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleAtPoint( con + lcl_GetApiColumn( rGrid.GetColumnFromX( rPoint.X ) ) : 0; + sal_Int32 nRow = (rPoint.Y >= rGrid.GetHdrHeight()) ? + (rGrid.GetLineFromY( rPoint.Y ) - rGrid.GetFirstVisLine() + 1) : 0; +- xRet = implCreateCellObj( nRow, nColumn ); ++ xRet = getAccessibleCell(nRow, nColumn); + } + return xRet; + } +@@ -912,13 +921,30 @@ sal_Int32 SAL_CALL ScAccessibleCsvGrid::getAccessibleChildCount() throw( Runtime + return implGetCellCount(); + } + ++Reference ScAccessibleCsvGrid::getAccessibleCell(sal_Int32 nRow, sal_Int32 nColumn) ++{ ++ sal_Int32 nIndex = implGetIndex(nRow, nColumn); ++ ++ XAccessibleSet::iterator aI = maAccessibleChildren.lower_bound(nIndex); ++ if (aI != maAccessibleChildren.end() && !(maAccessibleChildren.key_comp()(nIndex, aI->first))) ++ { ++ // key already exists ++ return Reference(aI->second.get()); ++ } ++ // key does not exist ++ rtl::Reference xNew = implCreateCellObj(nRow, nColumn); ++ maAccessibleChildren.insert(aI, XAccessibleSet::value_type(nIndex, xNew)); ++ return Reference(xNew.get()); ++} ++ + Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleChild( sal_Int32 nIndex ) + throw( IndexOutOfBoundsException, RuntimeException, std::exception ) + { + SolarMutexGuard aGuard; + ensureAlive(); + ensureValidIndex( nIndex ); +- return implCreateCellObj( implGetRow( nIndex ), implGetColumn( nIndex ) ); ++ ++ return getAccessibleCell(implGetRow(nIndex), implGetColumn(nIndex)); + } + + Reference< XAccessibleRelationSet > SAL_CALL ScAccessibleCsvGrid::getAccessibleRelationSet() +@@ -1066,7 +1092,7 @@ Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCellAt( sal_ + SolarMutexGuard aGuard; + ensureAlive(); + ensureValidPosition( nRow, nColumn ); +- return implCreateCellObj( nRow, nColumn ); ++ return getAccessibleCell(nRow, nColumn); + } + + Reference< XAccessible > SAL_CALL ScAccessibleCsvGrid::getAccessibleCaption() +@@ -1235,7 +1261,6 @@ Sequence< sal_Int8 > SAL_CALL ScAccessibleCsvGrid::getImplementationId() throw( + void ScAccessibleCsvGrid::SendFocusEvent( bool bFocused ) + { + ScAccessibleCsvControl::SendFocusEvent( bFocused ); +- + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::ACTIVE_DESCENDANT_CHANGED; + aEvent.Source = Reference< XAccessible >( this ); +diff --git a/sc/source/ui/inc/AccessibleCsvControl.hxx b/sc/source/ui/inc/AccessibleCsvControl.hxx +index a181c24..870cb3c 100644 +--- a/sc/source/ui/inc/AccessibleCsvControl.hxx ++++ b/sc/source/ui/inc/AccessibleCsvControl.hxx +@@ -31,6 +31,7 @@ + #include + #include + #include "AccessibleContextBase.hxx" ++#include + + class ScCsvControl; + namespace utl { class AccessibleStateSetHelper; } +@@ -304,10 +305,16 @@ class ScAccessibleCsvGrid : public ScAccessibleCsvControl, public ScAccessibleCs + protected: + typedef ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessibleTable > XAccessibleTableRef; ++ typedef std::map< sal_Int32, rtl::Reference > XAccessibleSet; ++ ++private: ++ XAccessibleSet maAccessibleChildren; + + public: + explicit ScAccessibleCsvGrid( ScCsvGrid& rGrid ); + virtual ~ScAccessibleCsvGrid(); ++ using ScAccessibleContextBase::disposing; ++ virtual void SAL_CALL disposing() override; + + // XAccessibleComponent --------------------------------------------------- + +@@ -531,6 +538,8 @@ private: + OUString implGetCellText( sal_Int32 nRow, sal_Int32 nColumn ) const; + /** Creates a new accessible object of the specified cell. Indexes must be valid. */ + ScAccessibleCsvControl* implCreateCellObj( sal_Int32 nRow, sal_Int32 nColumn ) const; ++ ++ css::uno::Reference getAccessibleCell(sal_Int32 nRow, sal_Int32 nColumn); + }; + + /** Accessible class representing a cell of the CSV grid control. */ +-- +1.8.3.1 + diff --git a/SOURCES/0001-Revert-upload-libwps-0.4.0.patch b/SOURCES/0001-Revert-upload-libwps-0.4.0.patch new file mode 100644 index 0000000..1303c6d --- /dev/null +++ b/SOURCES/0001-Revert-upload-libwps-0.4.0.patch @@ -0,0 +1,1064 @@ +From 97a27e85e1e4ec766dd5b528b6c7fba3b2910248 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 1 Mar 2016 07:23:54 +0100 +Subject: [PATCH] Revert "upload libwps 0.4.0" + +This reverts commit f9568335a653f72732f9c8ebf007cf8850021ff9. + +Change-Id: Iffbbc6fd409b807848a34c2e5cc4ac4c4e930a49 +--- + RepositoryExternal.mk | 2 +- + configure.ac | 2 +- + download.lst | 5 +- + ...parser-correct-a-mistake-when-reading-neg.patch | 26 --- + ...01-error-C2065-M_PI-undeclared-identifier.patch | 35 ---- + external/libwps/ExternalPackage_libwps.mk | 6 +- + external/libwps/ExternalProject_libwps.mk | 2 +- + external/libwps/Library_wps.mk | 8 - + external/libwps/UnpackedTarball_libwps.mk | 2 - + filter/Configuration_filter.mk | 4 - + .../config/fragments/filters/WPS_Lotus_Calc.xcu | 30 ---- + .../config/fragments/filters/WPS_QPro_Calc.xcu | 30 ---- + .../fragments/types/calc_WPS_Lotus_Document.xcu | 29 ---- + .../fragments/types/calc_WPS_QPro_Document.xcu | 29 ---- + scp2/source/ooo/file_ooo.scp | 1 - + scp2/source/ooo/module_ooo.scp | 1 - + writerperfect/Library_wpftcalc.mk | 2 - + writerperfect/Library_wpftdraw.mk | 2 - + writerperfect/Library_wpftimpress.mk | 2 - + writerperfect/Library_wpftwriter.mk | 2 - + writerperfect/Library_writerperfect.mk | 3 - + writerperfect/Module_writerperfect.mk | 4 - + writerperfect/UIConfig_writerperfect.mk | 26 --- + writerperfect/inc/WPFTEncodingDialog.hxx | 58 ------- + .../source/calc/MSWorksCalcImportFilter.cxx | 72 +-------- + writerperfect/source/common/WPFTEncodingDialog.cxx | 180 --------------------- + .../source/writer/MSWorksImportFilter.cxx | 34 +--- + writerperfect/uiconfig/ui/wpftencodingdialog.ui | 90 ----------- + 28 files changed, 15 insertions(+), 672 deletions(-) + delete mode 100644 external/libwps/0001-QuattroPro-parser-correct-a-mistake-when-reading-neg.patch + delete mode 100644 external/libwps/0001-error-C2065-M_PI-undeclared-identifier.patch + delete mode 100644 filter/source/config/fragments/filters/WPS_Lotus_Calc.xcu + delete mode 100644 filter/source/config/fragments/filters/WPS_QPro_Calc.xcu + delete mode 100644 filter/source/config/fragments/types/calc_WPS_Lotus_Document.xcu + delete mode 100644 filter/source/config/fragments/types/calc_WPS_QPro_Document.xcu + delete mode 100644 writerperfect/UIConfig_writerperfect.mk + delete mode 100644 writerperfect/inc/WPFTEncodingDialog.hxx + delete mode 100644 writerperfect/source/common/WPFTEncodingDialog.cxx + delete mode 100644 writerperfect/uiconfig/ui/wpftencodingdialog.ui + +diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk +index 20de676..3df6d6a 100644 +--- a/RepositoryExternal.mk ++++ b/RepositoryExternal.mk +@@ -2192,7 +2192,7 @@ $(call gb_LinkTarget_set_include,$(1),\ + $$(INCLUDE) \ + ) + $(call gb_LinkTarget_add_libs,$(1),\ +- -L$(call gb_UnpackedTarball_get_dir,libwps)/src/lib/.libs -lwps-0.4 \ ++ -L$(call gb_UnpackedTarball_get_dir,libwps)/src/lib/.libs -lwps-0.3 \ + ) + + endef +diff --git a/configure.ac b/configure.ac +index cc77ee9..6a99034 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -7713,7 +7713,7 @@ libo_CHECK_SYSTEM_MODULE([libabw],[ABW],[libabw-0.1]) + dnl =================================================================== + dnl Check for system libwps + dnl =================================================================== +-libo_CHECK_SYSTEM_MODULE([libwps],[WPS],[libwps-0.4]) ++libo_CHECK_SYSTEM_MODULE([libwps],[WPS],[libwps-0.3]) + + dnl =================================================================== + dnl Check for system libwpg +diff --git a/download.lst b/download.lst +index 9e16272..dc9aaea 100644 +--- a/download.lst ++++ b/download.lst +@@ -146,9 +146,8 @@ export WPD_MD5SUM := 0773d79a1f240ef9f4f20242b13c5bb7 + export WPD_TARBALL := libwpd-0.10.0.tar.bz2 + export WPG_MD5SUM := 17da9770cb8b317b7633f9807b32b71a + export WPG_TARBALL := libwpg-0.3.0.tar.bz2 +-export WPS_MD5SUM := e9162d2566421d9d71b3ad2377a68fd5 +-export WPS_VERSION_MICRO := 0 +-export WPS_TARBALL := libwps-0.4.$(WPS_VERSION_MICRO).tar.bz2 ++export WPS_MD5SUM := a111d9ef5a0dab564e9aec0f2cf8d218 ++export WPS_TARBALL := libwps-0.3.1.tar.bz2 + export XSLTML_TARBALL := a7983f859eafb2677d7ff386a023bc40-xsltml_2.1.2.zip + export ZLIB_MD5SUM := 44d667c142d7cda120332623eab69f40 + export ZLIB_TARBALL := zlib-1.2.8.tar.gz +diff --git a/external/libwps/0001-QuattroPro-parser-correct-a-mistake-when-reading-neg.patch b/external/libwps/0001-QuattroPro-parser-correct-a-mistake-when-reading-neg.patch +deleted file mode 100644 +index d5a6f54..0000000 +--- a/external/libwps/0001-QuattroPro-parser-correct-a-mistake-when-reading-neg.patch ++++ /dev/null +@@ -1,26 +0,0 @@ +-From 45a3dd5393e07340d5a63d8a8735789d73a61b17 Mon Sep 17 00:00:00 2001 +-From: osnola +-Date: Mon, 18 May 2015 08:27:59 +0200 +-Subject: [PATCH] QuattroPro parser: correct a mistake when reading negative +- cell's position +- +---- +- src/lib/QuattroSpreadsheet.cpp | 2 +- +- 1 file changed, 1 insertion(+), 1 deletion(-) +- +-diff --git a/src/lib/QuattroSpreadsheet.cpp b/src/lib/QuattroSpreadsheet.cpp +-index cb0f4f5..ce5e20a 100644 +---- a/src/lib/QuattroSpreadsheet.cpp +-+++ b/src/lib/QuattroSpreadsheet.cpp +-@@ -1668,7 +1668,7 @@ bool QuattroSpreadsheet::readCell +- else +- { +- val &= 0x3FFF; +-- if (val & 0x2000) val = val - 0x4000; +-+ if (val>0x1000) val = val - 0x2000; +- } +- if (dim==2) +- val += sheetId; +--- +-2.3.2 (Apple Git-55) +- +diff --git a/external/libwps/0001-error-C2065-M_PI-undeclared-identifier.patch b/external/libwps/0001-error-C2065-M_PI-undeclared-identifier.patch +deleted file mode 100644 +index 01109dc..0000000 +--- a/external/libwps/0001-error-C2065-M_PI-undeclared-identifier.patch ++++ /dev/null +@@ -1,35 +0,0 @@ +-From 94af34d42129bad72fd7ce50dc6901287509703e Mon Sep 17 00:00:00 2001 +-From: David Tardon +-Date: Mon, 18 May 2015 18:50:25 +0200 +-Subject: [PATCH] error C2065: M_PI : undeclared identifier +- +---- +- src/lib/libwps_internal.h | 5 +++++ +- 1 file changed, 5 insertions(+) +- +-diff --git a/src/lib/libwps_internal.h b/src/lib/libwps_internal.h +-index fb9016d..02a87bc 100644 +---- a/src/lib/libwps_internal.h +-+++ b/src/lib/libwps_internal.h +-@@ -28,6 +28,7 @@ +- #include +- #endif +- +-+#include +- #include +- #include +- #include +-@@ -36,6 +37,10 @@ +- #include +- #include +- +-+#ifndef M_PI +-+#define M_PI 3.14159265358979323846 +-+#endif +-+ +- #if defined(_MSC_VER) || defined(__DJGPP__) +- typedef signed char int8_t; +- typedef unsigned char uint8_t; +--- +-2.4.0 +- +diff --git a/external/libwps/ExternalPackage_libwps.mk b/external/libwps/ExternalPackage_libwps.mk +index 24b00c6..3e0f79b 100644 +--- a/external/libwps/ExternalPackage_libwps.mk ++++ b/external/libwps/ExternalPackage_libwps.mk +@@ -12,11 +12,11 @@ $(eval $(call gb_ExternalPackage_ExternalPackage,libwps,libwps)) + $(eval $(call gb_ExternalPackage_use_external_project,libwps,libwps)) + + ifeq ($(OS),MACOSX) +-$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.4.4.dylib,src/lib/.libs/libwps-0.4.4.dylib)) ++$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.3.3.dylib,src/lib/.libs/libwps-0.3.3.dylib)) + else ifeq ($(OS),WNT) +-$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.4.dll,src/lib/.libs/libwps-0.4.dll)) ++$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.3.dll,src/lib/.libs/libwps-0.3.dll)) + else ifeq ($(filter IOS ANDROID,$(OS)),) +-$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.4-lo.so.4,src/lib/.libs/libwps-0.4-lo.so.4.0.$(WPS_VERSION_MICRO))) ++$(eval $(call gb_ExternalPackage_add_file,libwps,$(LIBO_LIB_FOLDER)/libwps-0.3.so.3,src/lib/.libs/libwps-0.3.so.3.0.1)) + endif + + # vim: set noet sw=4 ts=4: +diff --git a/external/libwps/ExternalProject_libwps.mk b/external/libwps/ExternalProject_libwps.mk +index 10b39b3..8cd2138 100644 +--- a/external/libwps/ExternalProject_libwps.mk ++++ b/external/libwps/ExternalProject_libwps.mk +@@ -44,7 +44,7 @@ $(call gb_ExternalProject_get_state_target,libwps,build) : + && $(MAKE) \ + $(if $(filter MACOSX,$(OS)),\ + && $(PERL) $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \ +- $(EXTERNAL_WORKDIR)/src/lib/.libs/libwps-0.4.4.dylib \ ++ $(EXTERNAL_WORKDIR)/src/lib/.libs/libwps-0.3.3.dylib \ + ) \ + ) + +diff --git a/external/libwps/Library_wps.mk b/external/libwps/Library_wps.mk +index ef323ce..be9f3c6 100644 +--- a/external/libwps/Library_wps.mk ++++ b/external/libwps/Library_wps.mk +@@ -33,12 +33,6 @@ $(eval $(call gb_Library_add_defs,wps,\ + $(eval $(call gb_Library_set_generated_cxx_suffix,wps,cpp)) + + $(eval $(call gb_Library_add_generated_exception_objects,wps,\ +- UnpackedTarball/libwps/src/lib/Lotus \ +- UnpackedTarball/libwps/src/lib/LotusGraph \ +- UnpackedTarball/libwps/src/lib/LotusSpreadsheet \ +- UnpackedTarball/libwps/src/lib/LotusStyleManager \ +- UnpackedTarball/libwps/src/lib/Quattro \ +- UnpackedTarball/libwps/src/lib/QuattroSpreadsheet \ + UnpackedTarball/libwps/src/lib/WKS4 \ + UnpackedTarball/libwps/src/lib/WKS4Spreadsheet \ + UnpackedTarball/libwps/src/lib/WKSContentListener \ +@@ -58,8 +52,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,wps,\ + UnpackedTarball/libwps/src/lib/WPSDebug \ + UnpackedTarball/libwps/src/lib/WPSDocument \ + UnpackedTarball/libwps/src/lib/WPSFont \ +- UnpackedTarball/libwps/src/lib/WPSGraphicShape \ +- UnpackedTarball/libwps/src/lib/WPSGraphicStyle \ + UnpackedTarball/libwps/src/lib/WPSHeader \ + UnpackedTarball/libwps/src/lib/WPSList \ + UnpackedTarball/libwps/src/lib/WPSOLEParser \ +diff --git a/external/libwps/UnpackedTarball_libwps.mk b/external/libwps/UnpackedTarball_libwps.mk +index 52d9ab3..fd5953e 100644 +--- a/external/libwps/UnpackedTarball_libwps.mk ++++ b/external/libwps/UnpackedTarball_libwps.mk +@@ -14,8 +14,6 @@ $(eval $(call gb_UnpackedTarball_set_tarball,libwps,$(WPS_TARBALL))) + $(eval $(call gb_UnpackedTarball_set_patchlevel,libwps,1)) + + $(eval $(call gb_UnpackedTarball_add_patches,libwps,\ +- external/libwps/0001-QuattroPro-parser-correct-a-mistake-when-reading-neg.patch \ +- external/libwps/0001-error-C2065-M_PI-undeclared-identifier.patch \ + $(if $(SYSTEM_REVENGE),,external/libwps/rpath.patch.0) \ + )) + +diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk +index 213e981..576536e 100644 +--- a/filter/Configuration_filter.mk ++++ b/filter/Configuration_filter.mk +@@ -496,8 +496,6 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_calc_types.xcu,f + calc_OOXML \ + calc_OOXML_Template \ + calc_MS_Works_Document \ +- calc_WPS_Lotus_Document \ +- calc_WPS_QPro_Document \ + calc_Beagle_Works \ + calc_ClarisWorks \ + calc_Claris_Resolve \ +@@ -537,8 +535,6 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_calc_filters.x + calc_OOXML \ + calc_OOXML_Template \ + MS_Works_Calc \ +- WPS_Lotus_Calc \ +- WPS_QPro_Calc \ + Beagle_Works_Calc \ + ClarisWorks_Calc \ + Claris_Resolve_Calc \ +diff --git a/filter/source/config/fragments/filters/WPS_Lotus_Calc.xcu b/filter/source/config/fragments/filters/WPS_Lotus_Calc.xcu +deleted file mode 100644 +index 721e68f..0000000 +--- a/filter/source/config/fragments/filters/WPS_Lotus_Calc.xcu ++++ /dev/null +@@ -1,30 +0,0 @@ +- +- +- IMPORT ALIEN USESOPTIONS 3RDPARTYFILTER +- +- com.sun.star.comp.Calc.MSWorksCalcImportFilter +- +- +- Lotus Document +- +- 0 +- calc_WPS_Lotus_Document +- +- com.sun.star.sheet.SpreadsheetDocument +- +diff --git a/filter/source/config/fragments/filters/WPS_QPro_Calc.xcu b/filter/source/config/fragments/filters/WPS_QPro_Calc.xcu +deleted file mode 100644 +index 77c7b45..0000000 +--- a/filter/source/config/fragments/filters/WPS_QPro_Calc.xcu ++++ /dev/null +@@ -1,30 +0,0 @@ +- +- +- IMPORT ALIEN USESOPTIONS 3RDPARTYFILTER +- +- com.sun.star.comp.Calc.MSWorksCalcImportFilter +- +- +- QuattroPro Document +- +- 0 +- calc_WPS_QPro_Document +- +- com.sun.star.sheet.SpreadsheetDocument +- +diff --git a/filter/source/config/fragments/types/calc_WPS_Lotus_Document.xcu b/filter/source/config/fragments/types/calc_WPS_Lotus_Document.xcu +deleted file mode 100644 +index 0ecc711..0000000 +--- a/filter/source/config/fragments/types/calc_WPS_Lotus_Document.xcu ++++ /dev/null +@@ -1,29 +0,0 @@ +- +- +- com.sun.star.comp.Calc.MSWorksCalcImportFilter +- +- wk1 wk3 +- +- true +- WPS_Lotus_Calc +- +- Lotus Wk1-Wk3 +- +- +- +diff --git a/filter/source/config/fragments/types/calc_WPS_QPro_Document.xcu b/filter/source/config/fragments/types/calc_WPS_QPro_Document.xcu +deleted file mode 100644 +index a335004..0000000 +--- a/filter/source/config/fragments/types/calc_WPS_QPro_Document.xcu ++++ /dev/null +@@ -1,29 +0,0 @@ +- +- +- com.sun.star.comp.Calc.MSWorksCalcImportFilter +- +- wq1 wq2 +- +- true +- WPS_QPro_Calc +- +- QuattroPro Document +- +- +- +diff --git a/scp2/source/ooo/file_ooo.scp b/scp2/source/ooo/file_ooo.scp +index b0f3382..2405fb3 100644 +--- a/scp2/source/ooo/file_ooo.scp ++++ b/scp2/source/ooo/file_ooo.scp +@@ -290,7 +290,6 @@ UI_FILELIST(tubes, "UIConfig/tubes.filelist") + #endif + UI_FILELIST(uui, "UIConfig/uui.filelist") + UI_FILELIST(vcl, "UIConfig/vcl.filelist") +-UI_FILELIST(writerperfect, "UIConfig/writerperfect.filelist") + UI_FILELIST(xmlsec, "UIConfig/xmlsec.filelist") + + UI_FILELIST_ALL_LANG(basicide, modules/BasicIDE) +diff --git a/scp2/source/ooo/module_ooo.scp b/scp2/source/ooo/module_ooo.scp +index 9acfbe8..7cd2514 100644 +--- a/scp2/source/ooo/module_ooo.scp ++++ b/scp2/source/ooo/module_ooo.scp +@@ -126,7 +126,6 @@ Module gid_Module_Root + #endif + gid_File_Share_Config_Sofficecfg_uiconfig_uui, + gid_File_Share_Config_Sofficecfg_uiconfig_vcl, +- gid_File_Share_Config_Sofficecfg_uiconfig_writerperfect, + gid_File_Share_Config_Sofficecfg_uiconfig_xmlsec, + gid_File_Share_Registry_Main_Xcd, + gid_File_Share_Registry_Forcedefault_Xcd, +diff --git a/writerperfect/Library_wpftcalc.mk b/writerperfect/Library_wpftcalc.mk +index 18cc378..86c0fea 100644 +--- a/writerperfect/Library_wpftcalc.mk ++++ b/writerperfect/Library_wpftcalc.mk +@@ -34,10 +34,8 @@ $(eval $(call gb_Library_use_libraries,wpftcalc,\ + cppuhelper \ + sal \ + sot \ +- svx \ + tl \ + utl \ +- vcl \ + writerperfect \ + xo \ + $(gb_UWINAPI) \ +diff --git a/writerperfect/Library_wpftdraw.mk b/writerperfect/Library_wpftdraw.mk +index 1e57fcd..29409c1 100644 +--- a/writerperfect/Library_wpftdraw.mk ++++ b/writerperfect/Library_wpftdraw.mk +@@ -34,10 +34,8 @@ $(eval $(call gb_Library_use_libraries,wpftdraw,\ + cppuhelper \ + sal \ + sot \ +- svx \ + tl \ + utl \ +- vcl \ + writerperfect \ + xo \ + $(gb_UWINAPI) \ +diff --git a/writerperfect/Library_wpftimpress.mk b/writerperfect/Library_wpftimpress.mk +index 3d35aa7..eac71cb 100644 +--- a/writerperfect/Library_wpftimpress.mk ++++ b/writerperfect/Library_wpftimpress.mk +@@ -34,11 +34,9 @@ $(eval $(call gb_Library_use_libraries,wpftimpress,\ + cppuhelper \ + sal \ + sot \ +- svx \ + tl \ + ucbhelper \ + utl \ +- vcl \ + writerperfect \ + xo \ + $(gb_UWINAPI) \ +diff --git a/writerperfect/Library_wpftwriter.mk b/writerperfect/Library_wpftwriter.mk +index 288c929..60ff3b6 100644 +--- a/writerperfect/Library_wpftwriter.mk ++++ b/writerperfect/Library_wpftwriter.mk +@@ -36,11 +36,9 @@ $(eval $(call gb_Library_use_libraries,wpftwriter,\ + sal \ + sfx \ + sot \ +- svx \ + tl \ + ucbhelper \ + utl \ +- vcl \ + writerperfect \ + xo \ + $(gb_UWINAPI) \ +diff --git a/writerperfect/Library_writerperfect.mk b/writerperfect/Library_writerperfect.mk +index 165a7a0..1b8494b 100644 +--- a/writerperfect/Library_writerperfect.mk ++++ b/writerperfect/Library_writerperfect.mk +@@ -42,11 +42,9 @@ $(eval $(call gb_Library_use_libraries,writerperfect,\ + cppuhelper \ + sal \ + sot \ +- svx \ + tl \ + ucbhelper \ + utl \ +- vcl \ + xo \ + $(gb_UWINAPI) \ + )) +@@ -54,7 +52,6 @@ $(eval $(call gb_Library_use_libraries,writerperfect,\ + $(eval $(call gb_Library_add_exception_objects,writerperfect,\ + writerperfect/source/common/DirectoryStream \ + writerperfect/source/common/DocumentHandler \ +- writerperfect/source/common/WPFTEncodingDialog \ + writerperfect/source/common/WPXSvInputStream \ + )) + +diff --git a/writerperfect/Module_writerperfect.mk b/writerperfect/Module_writerperfect.mk +index e787043..9c30697 100644 +--- a/writerperfect/Module_writerperfect.mk ++++ b/writerperfect/Module_writerperfect.mk +@@ -27,10 +27,6 @@ $(eval $(call gb_Module_add_targets,writerperfect,\ + Library_writerperfect \ + )) + +-$(eval $(call gb_Module_add_l10n_targets,writerperfect,\ +- UIConfig_writerperfect \ +-)) +- + $(eval $(call gb_Module_add_check_targets,writerperfect,\ + CppunitTest_writerperfect_stream \ + )) +diff --git a/writerperfect/UIConfig_writerperfect.mk b/writerperfect/UIConfig_writerperfect.mk +deleted file mode 100644 +index d0d8ef5..0000000 +--- a/writerperfect/UIConfig_writerperfect.mk ++++ /dev/null +@@ -1,26 +0,0 @@ +-# -*- 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/. +-# +-# This file incorporates work covered by the following license notice: +-# +-# Licensed to the Apache Software Foundation (ASF) under one or more +-# contributor license agreements. See the NOTICE file distributed +-# with this work for additional information regarding copyright +-# ownership. The ASF licenses this file to you under the Apache +-# License, Version 2.0 (the "License"); you may not use this file +-# except in compliance with the License. You may obtain a copy of +-# the License at http://www.apache.org/licenses/LICENSE-2.0 . +-# +- +-$(eval $(call gb_UIConfig_UIConfig,writerperfect)) +- +-$(eval $(call gb_UIConfig_add_uifiles,writerperfect,\ +- writerperfect/uiconfig/ui/wpftencodingdialog \ +-)) +- +-# vim: set noet sw=4 ts=4: +diff --git a/writerperfect/inc/WPFTEncodingDialog.hxx b/writerperfect/inc/WPFTEncodingDialog.hxx +deleted file mode 100644 +index 2d3a63a..0000000 +--- a/writerperfect/inc/WPFTEncodingDialog.hxx ++++ /dev/null +@@ -1,58 +0,0 @@ +-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +-/* MSWorksImportFilter: Sets up the filter, and calls DocumentCollector +- * to do the actual filtering +- * +- * 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/. +- */ +- +-#ifndef INCLUDED_WRITERPERFECT_WPFTENCODINGDIALOG_HXX +-#define INCLUDED_WRITERPERFECT_WPFTENCODINGDIALOG_HXX +- +-#include +- +-#include +-#include +-#include +- +-#include +- +-namespace writerperfect +-{ +- +-class WRITERPERFECT_DLLPUBLIC WPFTEncodingDialog : public ModalDialog +-{ +-public: +- WPFTEncodingDialog(const OUString &title, const OUString &defEncoding); +- +- virtual ~WPFTEncodingDialog(); +- +- OUString GetEncoding() const; +- bool hasUserCalledCancel() const +- { +- return m_userHasCancelled; +- } +-private: +- VclPtr m_pLbCharset; +- VclPtr m_pBtnOk; +- VclPtr m_pBtnCancel; +- +- bool m_userHasCancelled; +-private: +- DECL_LINK(DoubleClickHdl, ListBox *); +- DECL_LINK(CancelHdl, void *); +- +- void dispose() SAL_OVERRIDE; +- +- WPFTEncodingDialog(WPFTEncodingDialog const &) SAL_DELETED_FUNCTION; +- WPFTEncodingDialog &operator=(WPFTEncodingDialog const &) SAL_DELETED_FUNCTION; +-}; +- +-} +- +-#endif +- +-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/writerperfect/source/calc/MSWorksCalcImportFilter.cxx b/writerperfect/source/calc/MSWorksCalcImportFilter.cxx +index 3ccf2db..d897638 100644 +--- a/writerperfect/source/calc/MSWorksCalcImportFilter.cxx ++++ b/writerperfect/source/calc/MSWorksCalcImportFilter.cxx +@@ -14,7 +14,6 @@ + + #include + +-#include "WPFTEncodingDialog.hxx" + #include "MSWorksCalcImportFilter.hxx" + + using com::sun::star::uno::Sequence; +@@ -27,79 +26,18 @@ using com::sun::star::uno::XComponentContext; + + bool MSWorksCalcImportFilter::doImportDocument(librevenge::RVNGInputStream &rInput, OdsGenerator &rGenerator, utl::MediaDescriptor &) + { +- libwps::WPSKind kind = libwps::WPS_TEXT; +- libwps::WPSCreator creator; +- bool needEncoding; +- const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding); +- +- std::string fileEncoding(""); +- if ((kind == libwps::WPS_SPREADSHEET || kind == libwps::WPS_DATABASE) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT) && needEncoding) +- { +- OUString title, encoding; +- if (creator == libwps::WPS_MSWORKS) +- { +- title="Import MsWorks files(libwps)"; +- encoding="CP850"; +- } +- else if (creator == libwps::WPS_LOTUS) +- { +- title="Import Lotus files(libwps)"; +- encoding="CP437"; +- } +- else if (creator == libwps::WPS_SYMPHONY) +- { +- title="Import Symphony files(libwps)"; +- encoding="CP437"; +- } +- else +- { +- title="Import Quattro Pro files(libwps)"; +- encoding="CP437"; +- } +- try +- { +- const ScopedVclPtrInstance pDlg(title, encoding); +- if (pDlg->Execute() == RET_OK) +- { +- if (!pDlg->GetEncoding().isEmpty()) +- fileEncoding=pDlg->GetEncoding().toUtf8().getStr(); +- } +- // we can fail because we are in headless mode, the user has cancelled conversion, ... +- else if (pDlg->hasUserCalledCancel()) +- return false; +- } +- catch (css::uno::Exception &e) +- { +- SAL_WARN("writerperfect", "ignoring Exception " << e.Message); +- } +- } +- return libwps::WPS_OK == libwps::WPSDocument::parse(&rInput, &rGenerator, "", fileEncoding.c_str()); ++ return libwps::WPS_OK == libwps::WPSDocument::parse(&rInput, &rGenerator); + } + + bool MSWorksCalcImportFilter::doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName) + { + libwps::WPSKind kind = libwps::WPS_TEXT; +- libwps::WPSCreator creator; +- bool needEncoding; +- const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding); ++ const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind); + +- if ((kind == libwps::WPS_SPREADSHEET || kind == libwps::WPS_DATABASE) && confidence == libwps::WPS_CONFIDENCE_EXCELLENT) ++ if ((kind == libwps::WPS_SPREADSHEET || kind == libwps::WPS_DATABASE) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT)) + { +- if (creator == libwps::WPS_MSWORKS) +- { +- rTypeName = "calc_MS_Works_Document"; +- return true; +- } +- if (creator == libwps::WPS_LOTUS || creator == libwps::WPS_SYMPHONY) +- { +- rTypeName = "calc_WPS_Lotus_Document"; +- return true; +- } +- if (creator == libwps::WPS_QUATTRO_PRO) +- { +- rTypeName = "calc_WPS_QPro_Document"; +- return true; +- } ++ rTypeName = "calc_MS_Works_Document"; ++ return true; + } + + return false; +diff --git a/writerperfect/source/common/WPFTEncodingDialog.cxx b/writerperfect/source/common/WPFTEncodingDialog.cxx +deleted file mode 100644 +index dec775b..0000000 +--- a/writerperfect/source/common/WPFTEncodingDialog.cxx ++++ /dev/null +@@ -1,180 +0,0 @@ +-/* -*- 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/. +- * +- * This file incorporates work covered by the following license notice: +- * +- * Licensed to the Apache Software Foundation (ASF) under one or more +- * contributor license agreements. See the NOTICE file distributed +- * with this work for additional information regarding copyright +- * ownership. The ASF licenses this file to you under the Apache +- * License, Version 2.0 (the "License"); you may not use this file +- * except in compliance with the License. You may obtain a copy of +- * the License at http://www.apache.org/licenses/LICENSE-2.0 . +- */ +- +-#include +- +-namespace writerperfect +-{ +- +-namespace +-{ +- +-struct EncodingImplementation +-{ +- +- static OUString const(s_encodings[]); +- +- static int numEncodings(); +- static void insertEncodings(ListBox *box); +- static void selectEncoding(ListBox *box, const OUString &encoding); +- static OUString getEncoding(ListBox *box); +-}; +- +-OUString const(EncodingImplementation::s_encodings[])= +-{ +- OUString("MacArabic"), OUString("Arabic (Apple Macintosh)"), +- OUString("CP864"), OUString("Arabic (DOS/OS2-864)"), +- OUString("CP1006"), OUString("Arabic (IBM-1006)"), +- OUString("CP1256"), OUString("Arabic (Windows-1256)"), +- OUString("CP775"), OUString("Baltic (DOS/OS2-775)"), +- OUString("CP1257"), OUString("Baltic (Windows-1257)"), +- OUString("MacCeltic"), OUString("Celtic (Apple Macintosh)"), +- OUString("MacCyrillic"), OUString("Cyrillic (Apple Macintosh)"), +- OUString("CP855"), OUString("Cyrillic (DOS/OS2-855)"), +- OUString("CP866"), OUString("Cyrillic (DOS/OS2-866/Russian)"), +- OUString("CP1251"), OUString("Cyrillic (Windows-1251)"), +- OUString("MacCEurope"), OUString("Eastern Europe (Apple Macintosh)"), +- OUString("MacCroatian"), OUString("Eastern Europe (Apple Macintosh/Croatian)"), +- OUString("MacRomanian"), OUString("Eastern Europe (Apple Macintosh/Romanian)"), +- OUString("CP852"), OUString("Eastern Europe (DOS/OS2-852)"), +- OUString("CP1250"), OUString("Eastern Europe (Windows-1250/WinLatin 2)"), +- OUString("MacGreek"), OUString("Greek (Apple Macintosh)"), +- OUString("CP737"), OUString("Greek (DOS/OS2-737)"), +- OUString("CP869"), OUString("Greek (DOS/OS2-869/Greek-2)"), +- OUString("CP875"), OUString("Greek (DOS/OS2-875)"), +- OUString("CP1253"), OUString("Greek (Windows-1253)"), +- OUString("MacHebrew"), OUString("Hebrew (Apple Macintosh)"), +- OUString("CP424"), OUString("Hebrew (DOS/OS2-424)"), +- OUString("CP856"), OUString("Hebrew (DOS/OS2-856)"), +- OUString("CP862"), OUString("Hebrew (DOS/OS2-862)"), +- OUString("CP1255"), OUString("Hebrew (Windows-1255)"), +- OUString("CP500"), OUString("International (DOS/OS2-500)"), +- OUString("MacThai"), OUString("Thai (Apple Macintosh)"), +- OUString("CP874"), OUString("Thai (DOS/OS2-874)"), +- OUString("MacTurkish"), OUString("Turkish (Apple Macintosh)"), +- OUString("CP857"), OUString("Turkish (DOS/OS2-857)"), +- OUString("CP1026"), OUString("Turkish (DOS/OS2-1026)"), +- OUString("CP1254"), OUString("Turkish (Windows-1254)"), +- OUString("CP1258"), OUString("Vietnamese (Windows-1258)"), +- OUString("MacRoman"), OUString("Western Europe (Apple Macintosh)"), +- OUString("MacIceland"), OUString("Western Europe (Apple Macintosh/Icelandic)"), +- OUString("CP037"), OUString("Western Europe (DOS/OS2-037/US-Canada)"), +- OUString("CP437"), OUString("Western Europe (DOS/OS2-437/US)"), +- OUString("CP850"), OUString("Western Europe (DOS/OS2-850)"), +- OUString("CP860"), OUString("Western Europe (DOS/OS2-860/Portuguese)"), +- OUString("CP861"), OUString("Western Europe (DOS/OS2-861/Icelandic)"), +- OUString("CP863"), OUString("Western Europe (DOS/OS2-863/French)"), +- OUString("CP865"), OUString("Western Europe (DOS/OS2-865/Nordic)"), +- OUString("CP1252"), OUString("Western Europe (Windows-1252/WinLatin 1)") +-}; +- +-int EncodingImplementation::numEncodings() +-{ +- return int(sizeof(s_encodings)/(2*sizeof(const OUString *))); +-} +- +-void EncodingImplementation::insertEncodings(ListBox *box) +-{ +- sal_IntPtr num=sal_IntPtr(numEncodings()); +- for (sal_IntPtr i=0; iInsertEntry(s_encodings[2*i+1]); +- box->SetEntryData(nAt, reinterpret_cast(i)); +- } +-} +- +-void EncodingImplementation::selectEncoding(ListBox *box, const OUString &encoding) +-{ +- sal_IntPtr num=sal_IntPtr(numEncodings()); +- for (sal_IntPtr i=0; iSelectEntryPos(i); +- return; +- } +-} +- +-OUString EncodingImplementation::getEncoding(ListBox *box) +-{ +- sal_IntPtr pos = reinterpret_cast(box->GetSelectEntryData()); +- if (pos<0||pos>=numEncodings()) +- return OUString(); +- return s_encodings[2*pos]; +-} +- +-} +- +-WPFTEncodingDialog::WPFTEncodingDialog( +- const OUString &title, const OUString &encoding) +- : ModalDialog(nullptr, "WPFTEncodingDialog", "writerperfect/ui/wpftencodingdialog.ui"), +- m_pLbCharset(), m_pBtnOk(), m_pBtnCancel(), m_userHasCancelled(false) +-{ +- get(m_pLbCharset, "comboboxtext"); +- get(m_pBtnOk, "ok"); +- get(m_pBtnCancel, "cancel"); +- +- m_pBtnCancel->SetClickHdl(LINK(this, WPFTEncodingDialog, CancelHdl)); +- +- EncodingImplementation::insertEncodings(m_pLbCharset); +- m_pLbCharset->SetStyle(m_pLbCharset->GetStyle() | WB_SORT); +- // m_pLbCharset->set_height_request(6 * m_pLbCharset->GetTextHeight()); +- m_pLbCharset->SetDoubleClickHdl(LINK(this, WPFTEncodingDialog, DoubleClickHdl)); +- EncodingImplementation::selectEncoding(m_pLbCharset, encoding); +- m_pLbCharset->Show(); +- +- SetText(title); +-} +- +-WPFTEncodingDialog::~WPFTEncodingDialog() +-{ +- disposeOnce(); +-} +- +-OUString WPFTEncodingDialog::GetEncoding() const +-{ +- return EncodingImplementation::getEncoding(m_pLbCharset); +-} +- +-IMPL_LINK_NOARG(WPFTEncodingDialog, CancelHdl) +-{ +- m_userHasCancelled=true; +- Close(); +- return 0; +-} +- +-IMPL_LINK(WPFTEncodingDialog, DoubleClickHdl, ListBox *, pLb) +-{ +- if (pLb == m_pLbCharset) +- { +- m_pBtnOk->Click(); +- } +- return 0; +-} +- +-void WPFTEncodingDialog::dispose() +-{ +- m_pLbCharset.disposeAndClear(); +- m_pBtnOk.disposeAndClear(); +- m_pBtnCancel.disposeAndClear(); +- ModalDialog::dispose(); +-} +- +-} +- +-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/writerperfect/source/writer/MSWorksImportFilter.cxx b/writerperfect/source/writer/MSWorksImportFilter.cxx +index 018f790..61c54f5 100644 +--- a/writerperfect/source/writer/MSWorksImportFilter.cxx ++++ b/writerperfect/source/writer/MSWorksImportFilter.cxx +@@ -9,13 +9,11 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +-#include + #include + #include + + #include + +-#include "WPFTEncodingDialog.hxx" + #include "MSWorksImportFilter.hxx" + + using com::sun::star::uno::Sequence; +@@ -35,41 +33,13 @@ static bool handleEmbeddedWKSObject(const librevenge::RVNGBinaryData &data, OdfD + + bool MSWorksImportFilter::doImportDocument(librevenge::RVNGInputStream &rInput, OdtGenerator &rGenerator, utl::MediaDescriptor &) + { +- libwps::WPSKind kind = libwps::WPS_TEXT; +- libwps::WPSCreator creator; +- bool needEncoding; +- const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding); +- +- std::string fileEncoding(""); +- try +- { +- if ((kind == libwps::WPS_TEXT) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT) && needEncoding) +- { +- const ScopedVclPtrInstance pDlg( +- "Import MsWorks files(libwps)", "CP850"); +- if (pDlg->Execute() == RET_OK) +- { +- if (!pDlg->GetEncoding().isEmpty()) +- fileEncoding=pDlg->GetEncoding().toUtf8().getStr(); +- } +- // we can fail because we are in headless mode, the user has cancelled conversion, ... +- else if (pDlg->hasUserCalledCancel()) +- return false; +- } +- } +- catch (css::uno::Exception &e) +- { +- SAL_WARN("writerperfect", "ignoring Exception " << e.Message); +- } +- return libwps::WPS_OK == libwps::WPSDocument::parse(&rInput, &rGenerator, "", fileEncoding.c_str()); ++ return libwps::WPS_OK == libwps::WPSDocument::parse(&rInput, &rGenerator); + } + + bool MSWorksImportFilter::doDetectFormat(librevenge::RVNGInputStream &rInput, OUString &rTypeName) + { + libwps::WPSKind kind = libwps::WPS_TEXT; +- libwps::WPSCreator creator; +- bool needEncoding; +- const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind, creator, needEncoding); ++ const libwps::WPSConfidence confidence = libwps::WPSDocument::isFileFormatSupported(&rInput, kind); + + if ((kind == libwps::WPS_TEXT) && (confidence == libwps::WPS_CONFIDENCE_EXCELLENT)) + { +diff --git a/writerperfect/uiconfig/ui/wpftencodingdialog.ui b/writerperfect/uiconfig/ui/wpftencodingdialog.ui +deleted file mode 100644 +index 40d2652..0000000 +--- a/writerperfect/uiconfig/ui/wpftencodingdialog.ui ++++ /dev/null +@@ -1,90 +0,0 @@ +- +- +- +- +- +- False +- 6 +- False +- True +- -1 +- dialog +- +- +- False +- vertical +- 6 +- +- +- False +- end +- +- +- gtk-ok +- True +- True +- True +- True +- True +- 0.62000000476837158 +- +- +- True +- True +- 0 +- +- +- +- +- gtk-cancel +- True +- True +- True +- True +- +- +- True +- True +- 1 +- +- +- +- +- False +- False +- 2 +- +- +- +- +- True +- False +- start +- _Character set: +- True +- comboboxtext +- +- +- False +- True +- 0 +- +- +- +- +- False +- +- +- False +- True +- 1 +- +- +- +- +- +- ok +- cancel +- +- +- +-- +2.5.0 + diff --git a/SOURCES/0001-add-X-TryExec-entries-to-desktop-files.patch b/SOURCES/0001-add-X-TryExec-entries-to-desktop-files.patch new file mode 100644 index 0000000..43e8ceb --- /dev/null +++ b/SOURCES/0001-add-X-TryExec-entries-to-desktop-files.patch @@ -0,0 +1,90 @@ +From 5c6b12167e070e2713640e0756f40efa2fd7494c Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 28 Apr 2014 09:59:10 +0200 +Subject: [PATCH] add X-TryExec entries to desktop files + +Change-Id: Ic3626f79fa8b0b6e0d6696799445eaea8b0ab47f +--- + sysui/desktop/menus/base.desktop | 1 + + sysui/desktop/menus/calc.desktop | 1 + + sysui/desktop/menus/draw.desktop | 1 + + sysui/desktop/menus/impress.desktop | 1 + + sysui/desktop/menus/math.desktop | 1 + + sysui/desktop/menus/writer.desktop | 1 + + 6 files changed, 6 insertions(+) + +diff --git a/sysui/desktop/menus/base.desktop b/sysui/desktop/menus/base.desktop +index 26f1c6a..2861dfe 100644 +--- a/sysui/desktop/menus/base.desktop ++++ b/sysui/desktop/menus/base.desktop +@@ -32,6 +32,7 @@ Keywords=Data;SQL; + InitialPreference=5 + StartupWMClass=libreoffice-base + X-KDE-Protocols=file,http,ftp,webdav ++X-TryExec=oobase + + Actions=NewDocument; + [Desktop Action NewDocument] +diff --git a/sysui/desktop/menus/calc.desktop b/sysui/desktop/menus/calc.desktop +index fc5e241..c50f380 100644 +--- a/sysui/desktop/menus/calc.desktop ++++ b/sysui/desktop/menus/calc.desktop +@@ -32,6 +32,7 @@ Keywords=Accounting;Stats;OpenDocument Spreadsheet;Chart;Microsoft Excel;Microso + InitialPreference=5 + StartupWMClass=libreoffice-calc + X-KDE-Protocols=file,http,ftp,webdav ++X-TryExec=oocalc + + Actions=NewDocument; + [Desktop Action NewDocument] +diff --git a/sysui/desktop/menus/draw.desktop b/sysui/desktop/menus/draw.desktop +index b5d58ce..274275f 100644 +--- a/sysui/desktop/menus/draw.desktop ++++ b/sysui/desktop/menus/draw.desktop +@@ -32,6 +32,7 @@ Keywords=Vector;Schema;Diagram;Layout;OpenDocument Graphics;Microsoft Publisher; + InitialPreference=5 + StartupWMClass=libreoffice-draw + X-KDE-Protocols=file,http,ftp,webdav ++X-TryExec=oodraw + + Actions=NewDocument; + [Desktop Action NewDocument] +diff --git a/sysui/desktop/menus/impress.desktop b/sysui/desktop/menus/impress.desktop +index c1f6231..7e70bfb 100644 +--- a/sysui/desktop/menus/impress.desktop ++++ b/sysui/desktop/menus/impress.desktop +@@ -32,6 +32,7 @@ Keywords=Slideshow;Slides;OpenDocument Presentation;Microsoft PowerPoint;Microso + InitialPreference=5 + StartupWMClass=libreoffice-impress + X-KDE-Protocols=file,http,ftp,webdav ++X-TryExec=ooimpress + + Actions=NewDocument; + [Desktop Action NewDocument] +diff --git a/sysui/desktop/menus/math.desktop b/sysui/desktop/menus/math.desktop +index b6981f5..4d7bd3c 100644 +--- a/sysui/desktop/menus/math.desktop ++++ b/sysui/desktop/menus/math.desktop +@@ -33,6 +33,7 @@ Keywords=Equation;OpenDocument Formula;Formula;odf;MathML; + InitialPreference=5 + StartupWMClass=libreoffice-math + X-KDE-Protocols=file,http,ftp,webdav ++X-TryExec=oomath + + Actions=NewDocument; + [Desktop Action NewDocument] +diff --git a/sysui/desktop/menus/writer.desktop b/sysui/desktop/menus/writer.desktop +index c4cea12..6d943a9 100644 +--- a/sysui/desktop/menus/writer.desktop ++++ b/sysui/desktop/menus/writer.desktop +@@ -32,6 +32,7 @@ Keywords=Text;Letter;Fax;Document;OpenDocument Text;Microsoft Word;Microsoft Wor + InitialPreference=5 + StartupWMClass=libreoffice-writer + X-KDE-Protocols=file,http,ftp,webdav ++X-TryExec=oowriter + + Actions=NewDocument; + [Desktop Action NewDocument] +-- +1.9.0 + diff --git a/SOURCES/0001-allow-slide-design-to-affect-multiple-standard-pages.patch b/SOURCES/0001-allow-slide-design-to-affect-multiple-standard-pages.patch new file mode 100644 index 0000000..bbb8019 --- /dev/null +++ b/SOURCES/0001-allow-slide-design-to-affect-multiple-standard-pages.patch @@ -0,0 +1,178 @@ +From f7ed8b99b628625851fb28ec1a3dead710c8871c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 23 Jun 2015 16:54:52 +0100 +Subject: [PATCH] allow slide design to affect multiple standard pages + +modify this minimally and select all standard pages +selected in the slidesorted, unselect them afterwards +and loop over the selected ones. + +This looks like it could do with a rework to disentangle +the master/standard pages stuff, but leave it as is in +this commit + +Change-Id: Ifd01fe21c91e5e6b07b2d8bba0d85facadc25998 +--- + sd/source/ui/func/fuprlout.cxx | 94 +++++++++++++++++++++++++++++------------- + 1 file changed, 66 insertions(+), 28 deletions(-) + +diff --git a/sd/source/ui/func/fuprlout.cxx b/sd/source/ui/func/fuprlout.cxx +index 6ce661f..f087ad9 100644 +--- a/sd/source/ui/func/fuprlout.cxx ++++ b/sd/source/ui/func/fuprlout.cxx +@@ -42,6 +42,7 @@ + #include "strmname.h" + #include "app.hrc" + #include "DrawDocShell.hxx" ++#include "SlideSorterViewShell.hxx" + #include "unprlout.hxx" + #include "unchss.hxx" + #include "unmovss.hxx" +@@ -89,24 +90,6 @@ void FuPresentationLayout::DoExecute( SfxRequest& rReq ) + + bool bError = false; + +- // determine the active page +- sal_uInt16 nSelectedPage = SDRPAGE_NOTFOUND; +- for (sal_uInt16 nPage = 0; nPage < mpDoc->GetSdPageCount(PK_STANDARD); nPage++) +- { +- if (mpDoc->GetSdPage(nPage, PK_STANDARD)->IsSelected()) +- { +- nSelectedPage = nPage; +- break; +- } +- } +- +- DBG_ASSERT(nSelectedPage != SDRPAGE_NOTFOUND, "no selected page"); +- SdPage* pSelectedPage = mpDoc->GetSdPage(nSelectedPage, PK_STANDARD); +- OUString aOldLayoutName(pSelectedPage->GetLayoutName()); +- sal_Int32 nPos = aOldLayoutName.indexOf(SD_LT_SEPARATOR); +- if (nPos != -1) +- aOldLayoutName = aOldLayoutName.copy(0, nPos); +- + /* if we are on a master page, the changes apply for all pages and notes- + pages who are using the relevant layout */ + bool bOnMaster = false; +@@ -117,6 +100,51 @@ void FuPresentationLayout::DoExecute( SfxRequest& rReq ) + if (eEditMode == EM_MASTERPAGE) + bOnMaster = true; + } ++ ++ std::vector aUnselect; ++ if (!bOnMaster) ++ { ++ //We later rely on IsSelected, so transfer the selection here ++ //into the document ++ slidesorter::SlideSorterViewShell* pSlideSorterViewShell ++ = slidesorter::SlideSorterViewShell::GetSlideSorter(mpViewShell->GetViewShellBase()); ++ if (pSlideSorterViewShell) ++ { ++ boost::shared_ptr xSelection( ++ pSlideSorterViewShell->GetPageSelection()); ++ if (xSelection) ++ { ++ for (auto it = xSelection->begin(); it != xSelection->end(); ++it) ++ { ++ SdPage *pPage = *it; ++ if (pPage->IsSelected() || pPage->GetPageKind() != PK_STANDARD) ++ continue; ++ mpDoc->SetSelected(pPage, true); ++ aUnselect.push_back(pPage); ++ } ++ } ++ } ++ } ++ ++ std::vector aSelectedPages; ++ std::vector aSelectedPageNums; ++ // determine the active pages ++ for (sal_uInt16 nPage = 0; nPage < mpDoc->GetSdPageCount(PK_STANDARD); nPage++) ++ { ++ SdPage* pPage = mpDoc->GetSdPage(nPage, PK_STANDARD); ++ if (pPage->IsSelected()) ++ { ++ aSelectedPages.push_back(pPage); ++ aSelectedPageNums.push_back(nPage); ++ } ++ } ++ ++ assert(!aSelectedPages.empty() && "no selected page"); ++ OUString aOldLayoutName(aSelectedPages.back()->GetLayoutName()); ++ sal_Int32 nPos = aOldLayoutName.indexOf(SD_LT_SEPARATOR); ++ if (nPos != -1) ++ aOldLayoutName = aOldLayoutName.copy(0, nPos); ++ + bool bMasterPage = bOnMaster; + bool bCheckMasters = false; + +@@ -196,14 +224,15 @@ void FuPresentationLayout::DoExecute( SfxRequest& rReq ) + OUString aLayoutName; + if( pTempDoc ) + aLayoutName = aFile.getToken(1, DOCUMENT_TOKEN); +- +- mpDoc->SetMasterPage(nSelectedPage, aLayoutName, pTempDoc, bMasterPage, bCheckMasters); ++ for (auto nSelectedPage : aSelectedPageNums) ++ mpDoc->SetMasterPage(nSelectedPage, aLayoutName, pTempDoc, bMasterPage, bCheckMasters); + mpDoc->CloseBookmarkDoc(); + } + else + { + // use master page with the layout name aFile from current Doc +- mpDoc->SetMasterPage(nSelectedPage, aFile, mpDoc, bMasterPage, bCheckMasters); ++ for (auto nSelectedPage : aSelectedPageNums) ++ mpDoc->SetMasterPage(nSelectedPage, aFile, mpDoc, bMasterPage, bCheckMasters); + } + + // remove blocking +@@ -211,7 +240,7 @@ void FuPresentationLayout::DoExecute( SfxRequest& rReq ) + static_cast(mpView)->BlockPageOrderChangedHint(false); + + // if the master page was visible, show it again +- if (!bError && nSelectedPage != SDRPAGE_NOTFOUND) ++ if (!bError) + { + if (bOnMaster) + { +@@ -219,13 +248,16 @@ void FuPresentationLayout::DoExecute( SfxRequest& rReq ) + { + ::sd::View* pView = + static_cast(mpViewShell)->GetView(); +- sal_uInt16 nPgNum = pSelectedPage->TRG_GetMasterPage().GetPageNum(); ++ for (auto pSelectedPage : aSelectedPages) ++ { ++ sal_uInt16 nPgNum = pSelectedPage->TRG_GetMasterPage().GetPageNum(); + +- if (static_cast(mpViewShell)->GetPageKind() == PK_NOTES) +- nPgNum++; ++ if (static_cast(mpViewShell)->GetPageKind() == PK_NOTES) ++ nPgNum++; + +- pView->HideSdrPage(); +- pView->ShowSdrPage(pView->GetModel()->GetMasterPage(nPgNum)); ++ pView->HideSdrPage(); ++ pView->ShowSdrPage(pView->GetModel()->GetMasterPage(nPgNum)); ++ } + } + + // force update of TabBar +@@ -233,10 +265,16 @@ void FuPresentationLayout::DoExecute( SfxRequest& rReq ) + } + else + { +- pSelectedPage->SetAutoLayout(pSelectedPage->GetAutoLayout()); ++ for (auto pSelectedPage : aSelectedPages) ++ pSelectedPage->SetAutoLayout(pSelectedPage->GetAutoLayout()); + } + } + ++ //Undo transfer to document selection ++ for (auto pPage : aUnselect) ++ mpDoc->SetSelected(pPage, false); ++ ++ + // fake a mode change to repaint the page tab bar + if( mpViewShell && mpViewShell->ISA( DrawViewShell ) ) + { +-- +2.4.0 + diff --git a/SOURCES/0001-backport-5-1-idle-timers-loop-to-5-0.patch b/SOURCES/0001-backport-5-1-idle-timers-loop-to-5-0.patch new file mode 100644 index 0000000..60e2040 --- /dev/null +++ b/SOURCES/0001-backport-5-1-idle-timers-loop-to-5-0.patch @@ -0,0 +1,1811 @@ +From de66d2e73cf44d2691d7e2e4ca8df98b46b26c10 Mon Sep 17 00:00:00 2001 +From: Michael Meeks +Date: Fri, 13 Nov 2015 09:56:53 +0000 +Subject: [PATCH] backport 5-1 idle/timers loop to 5-0 + +slideshow: cleanup main-loop usage, post-yield listeners, etc. + + This removes several attempts at reducing jitter in slideshow +animations. Now we have high-resolution (ie. not clamped to 10ms) +timers on Windows and a cleaner and simpler main-loop, we should +be able to use generic timer code-paths for all of this. + + This also allows us to further cleanup and simplify the main-loop +removing the now redundent post-yield handler concept. If there is a +short enough timeout, we will take just 1ms of delay before executing +a short timer anyway. + + Also removed some lingering comments from an old attempt to boost +priorities which broken audio playback. + + Tested: tdf#32861 - still works, audio still plays, no new jitter + in animations that I tested. + +Reviewed-on: https://gerrit.libreoffice.org/19947 +Tested-by: Jenkins +Reviewed-by: Michael Meeks +(cherry picked from commit 12dcf5e6e770b1933252a1f919663ba45ded4cdf) + +Change-Id: Iadc5e2a48828a18a599a86a8df14cb2b75dd425e +--- + .../source/primitive2d/textlayoutdevice.cxx | 5 +- + framework/source/services/autorecovery.cxx | 1 + + include/sal/log-areas.dox | 1 + + include/vcl/idle.hxx | 5 +- + include/vcl/scheduler.hxx | 48 +++--- + include/vcl/svapp.hxx | 74 +--------- + include/vcl/timer.hxx | 9 +- + sd/source/ui/slideshow/slideshowimpl.cxx | 47 +----- + sd/source/ui/slideshow/slideshowimpl.hxx | 3 +- + toolkit/source/awt/vclxtoolkit.cxx | 2 +- + vcl/headless/svpinst.cxx | 7 +- + vcl/inc/headless/svpinst.hxx | 2 +- + vcl/inc/osx/salinst.h | 2 +- + vcl/inc/salinst.hxx | 13 +- + vcl/inc/saltimer.hxx | 17 +++ + vcl/inc/svdata.hxx | 4 - + vcl/inc/unx/gtk/gtkdata.hxx | 2 +- + vcl/inc/unx/gtk/gtkinst.hxx | 2 +- + vcl/inc/unx/saldisp.hxx | 4 +- + vcl/inc/unx/salinst.h | 2 +- + vcl/inc/win/salinst.h | 2 +- + vcl/osx/salinst.cxx | 13 +- + vcl/qa/cppunit/timer.cxx | 2 +- + vcl/source/app/idle.cxx | 26 ++-- + vcl/source/app/scheduler.cxx | 164 +++++++++++++++------ + vcl/source/app/svapp.cxx | 99 +++++++------ + vcl/source/app/svmain.cxx | 5 - + vcl/source/app/timer.cxx | 84 ++++------- + vcl/unx/generic/app/saldata.cxx | 13 +- + vcl/unx/generic/app/saldisp.cxx | 9 +- + vcl/unx/generic/app/salinst.cxx | 6 +- + vcl/unx/gtk/a11y/atkwrapper.cxx | 2 +- + vcl/unx/gtk/app/gtkdata.cxx | 14 +- + vcl/unx/gtk/app/gtkinst.cxx | 6 +- + vcl/unx/kde4/KDESalDisplay.cxx | 9 +- + vcl/unx/kde4/KDESalDisplay.hxx | 2 +- + vcl/unx/kde4/KDEXLib.cxx | 16 +- + vcl/unx/kde4/KDEXLib.hxx | 4 +- + vcl/win/source/app/salinst.cxx | 19 ++- + 39 files changed, 390 insertions(+), 355 deletions(-) + +diff --git a/drawinglayer/source/primitive2d/textlayoutdevice.cxx b/drawinglayer/source/primitive2d/textlayoutdevice.cxx +index 2eefc3f..99dad74 100644 +--- a/drawinglayer/source/primitive2d/textlayoutdevice.cxx ++++ b/drawinglayer/source/primitive2d/textlayoutdevice.cxx +@@ -72,8 +72,9 @@ namespace + }; + + ImpTimedRefDev::ImpTimedRefDev(scoped_timed_RefDev& rOwnerOfMe) +- : mrOwnerOfMe(rOwnerOfMe), +- mpVirDev(0L), ++ : Timer( "Timer to destroy drawinglayer reference device" ), ++ mrOwnerOfMe(rOwnerOfMe), ++ mpVirDev(nullptr), + mnUseCount(0L) + { + SetTimeout(3L * 60L * 1000L); // three minutes +diff --git a/framework/source/services/autorecovery.cxx b/framework/source/services/autorecovery.cxx +index 8b75271..36adb9b 100644 +--- a/framework/source/services/autorecovery.cxx ++++ b/framework/source/services/autorecovery.cxx +@@ -1261,6 +1261,7 @@ AutoRecovery::AutoRecovery(const css::uno::Reference< css::uno::XComponentContex + , m_bListenForConfigChanges (false ) + , m_nAutoSaveTimeIntervall (0 ) + , m_eJob (AutoRecovery::E_NO_JOB ) ++ , m_aTimer ( "Auto save timer" ) + , m_aAsyncDispatcher ( LINK( this, AutoRecovery, implts_asyncDispatch ) ) + , m_eTimerType (E_DONT_START_TIMER ) + , m_nIdPool (0 ) +diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox +index d734876..6cb1348 100644 +--- a/include/sal/log-areas.dox ++++ b/include/sal/log-areas.dox +@@ -403,6 +403,7 @@ certain functionality. + @li @c vcl.osx + @li @c vcl.osx.print + @li @c vcl.quartz ++@li @c vcl.schedule - scheduler / main-loop information + @li @c vcl.scrollbar - Scroll Bars + @li @c vcl.sm - Session Manager + @li @c vcl.unity +diff --git a/include/vcl/idle.hxx b/include/vcl/idle.hxx +index 2e853b7..ba892a9 100644 +--- a/include/vcl/idle.hxx ++++ b/include/vcl/idle.hxx +@@ -39,8 +39,9 @@ public: + void SetIdleHdl( const Link& rLink ) { maIdleHdl = rLink; } + const Link& GetIdleHdl() const { return maIdleHdl; } + virtual void Invoke() SAL_OVERRIDE; +- virtual bool ReadyForSchedule( bool bTimer ) SAL_OVERRIDE; +- virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) SAL_OVERRIDE; ++ virtual bool ReadyForSchedule( bool bTimerOnly, sal_uInt64 nTimeNow ) const SAL_OVERRIDE; ++ virtual bool IsIdle() const SAL_OVERRIDE; ++ virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const SAL_OVERRIDE; + Idle& operator=( const Idle& rIdle ); + }; + +diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx +index 973565b..d9a8678 100644 +--- a/include/vcl/scheduler.hxx ++++ b/include/vcl/scheduler.hxx +@@ -22,21 +22,9 @@ + + #include + +-struct ImplSVData; + class Scheduler; +-struct ImplSchedulerData +-{ +- ImplSchedulerData* mpNext; // Pointer to the next element in list +- Scheduler* mpScheduler; // Pointer to VCL Scheduler instance +- bool mbDelete; // Destroy this scheduler? +- bool mbInScheduler; // Scheduler currently processed? +- sal_uInt64 mnUpdateTime; // Last Update Time +- sal_uInt32 mnUpdateStack; // Update Stack +- +- void Invoke(); +- +- static ImplSchedulerData *GetMostImportantTask( bool bTimer ); +-}; ++struct ImplSVData; ++struct ImplSchedulerData; + + enum class SchedulerPriority { + HIGHEST = 0, +@@ -51,23 +39,39 @@ enum class SchedulerPriority { + + class VCL_DLLPUBLIC Scheduler + { ++private: ++ static void InitSystemTimer(ImplSVData* pSVData); ++ + protected: + ImplSchedulerData* mpSchedulerData; /// Pointer to element in scheduler list + const sal_Char *mpDebugName; /// Useful for debugging + SchedulerPriority mePriority; /// Scheduler priority + bool mbActive; /// Currently in the scheduler + ++ // These should be constexpr static, when supported. ++ static const sal_uInt64 ImmediateTimeoutMs = 1; ++ static const sal_uInt64 MaximumTimeoutMs = 1000 * 60; // 1 minute ++ ++ static void ImplStartTimer(sal_uInt64 nMS, bool bForce = false); ++ + friend struct ImplSchedulerData; + virtual void SetDeletionFlags(); +- virtual bool ReadyForSchedule( bool bTimer ) = 0; +- virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) = 0; ++ /// Is this item ready to be dispatched at @nTimeNow ++ virtual bool ReadyForSchedule( bool bTimerOnly, sal_uInt64 nTimeNow ) const = 0; ++ /// Schedule only when other timers and events are processed ++ virtual bool IsIdle() const = 0; ++ /** ++ * Adjust @nMinPeriod downwards if we want to be notified before ++ * then, @nTimeNow is the current time. ++ */ ++ virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTimeNow ) const = 0; + + public: + Scheduler( const sal_Char *pDebugName = NULL ); + Scheduler( const Scheduler& rScheduler ); + virtual ~Scheduler(); + +- void SetPriority( SchedulerPriority ePriority ); ++ void SetPriority(SchedulerPriority ePriority) { mePriority = ePriority; } + SchedulerPriority GetPriority() const { return mePriority; } + + void SetDebugName( const sal_Char *pDebugName ) { mpDebugName = pDebugName; } +@@ -82,13 +86,17 @@ public: + bool IsActive() const { return mbActive; } + void SetInActive() { mbActive = false; } + +- Scheduler& operator=( const Scheduler& rScheduler ); ++ Scheduler& operator=( const Scheduler& rScheduler ); + static void ImplDeInitScheduler(); + + // Process one pending Timer with highhest priority + static void CallbackTaskScheduling( bool ignore ); +- /// Process one pending task ahead of time with highhest priority. +- static void ProcessTaskScheduling( bool bTimer ); ++ /// Calculate minimum timeout - and return its value. ++ static sal_uInt64 CalculateMinimumTimeout( bool &bHasActiveIdles ); ++ /// Process one pending task ahead of time with highest priority. ++ static bool ProcessTaskScheduling( bool bTimerOnly ); ++ /// Process all events until we are idle ++ static void ProcessEventsToIdle(); + }; + + #endif // INCLUDED_VCL_SCHEDULER_HXX +diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx +index 78f758c..716a987 100644 +--- a/include/vcl/svapp.hxx ++++ b/include/vcl/svapp.hxx +@@ -459,8 +459,6 @@ public: + + @see Quit, Reschedule, Yield, EndYield, GetSolarMutex, + GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static void Execute(); + +@@ -468,8 +466,6 @@ public: + + @see Execute, Reschedule, Yield, EndYield, GetSolarMutex, + GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static void Quit(); + +@@ -481,8 +477,6 @@ public: + + @see Execute, Quit, Yield, EndYield, GetSolarMutex, + GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static void Reschedule( bool bAllEvents = false ); + +@@ -490,8 +484,6 @@ public: + + @see Execute, Quit, Reschedule, EndYield, GetSolarMutex, + GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static void Yield(); + +@@ -499,11 +491,15 @@ public: + + @see Execute, Quit, Reschedule, Yield, GetSolarMutex, + GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static void EndYield(); + ++ /** Acquire SolarMutex after it has been temporarily dropped completely. ++ ++ This will Reschedule() on WNT and just acquire on other platforms. ++ */ ++ static void ReAcquireSolarMutex(sal_uLong nReleased); ++ + /** @brief Get the Solar Mutex for this thread. + + Get the Solar Mutex that prevents other threads from accessing VCL +@@ -513,8 +509,6 @@ public: + + @see Execute, Quit, Reschedule, Yield, EndYield, + GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static comphelper::SolarMutex& GetSolarMutex(); + +@@ -524,8 +518,6 @@ public: + + @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, + ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static oslThreadIdentifier GetMainThreadIdentifier(); + +@@ -538,8 +530,6 @@ public: + + @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, + GetMainThreadIdentifier, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static sal_uLong ReleaseSolarMutex(); + +@@ -550,59 +540,9 @@ public: + + @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, + GetMainThreadIdentifier, ReleaseSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener, +- RemovePostYieldListener + */ + static void AcquireSolarMutex( sal_uLong nCount ); + +- /** @brief Enables "no yield" mode +- +- "No yield" mode prevents Yield() from waiting for events. +- +- @remarks This was originally implemented in OOo bug 98792 to improve +- Impress slideshows. +- +- @see DisableNoYieldMode, Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, +- GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- DisableNoYield, AddPostYieldListener, RemovePostYieldListener +- */ +- static void EnableNoYieldMode(); +- +- /** @brief Disables "no yield" mode +- +- "No yield" mode prevents Yield() from waiting for events. +- +- @remarks This was originally implemented in OOo bug 98792 to improve +- Impress slideshows. +- +- @see EnableNoYieldMode, Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, +- GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYield, AddPostYieldListener, RemovePostYieldListener +- */ +- +- static void DisableNoYieldMode(); +- +- /** Add a listener for yield events +- +- @param i_rListener Listener to add +- +- @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, +- GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- EnableNoYieldMode, DisableNoYieldMode, RemovePostYieldListener +- */ +- static void AddPostYieldListener( const Link<>& i_rListener ); +- +- /** Remove listener for yield events +- +- @param i_rListener Listener to remove +- +- @see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex, +- GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex, +- AddPostYieldListener, EnableNoYieldMode, DisableNoYieldMode +- */ +- static void RemovePostYieldListener( const Link<>& i_rListener ); +- +- + /** Queries whether the application is in "main", i.e. not yet in + the event loop + +@@ -1687,7 +1627,7 @@ public: + + ~SolarMutexReleaser() + { +- Application::AcquireSolarMutex( mnReleased ); ++ Application::ReAcquireSolarMutex(mnReleased); + } + }; + +diff --git a/include/vcl/timer.hxx b/include/vcl/timer.hxx +index 8835291..d3abf1f 100644 +--- a/include/vcl/timer.hxx ++++ b/include/vcl/timer.hxx +@@ -31,11 +31,9 @@ protected: + bool mbAuto; + + virtual void SetDeletionFlags() SAL_OVERRIDE; +- virtual bool ReadyForSchedule( bool bTimer ) SAL_OVERRIDE; +- virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) SAL_OVERRIDE; +- +-private: +- static void InitSystemTimer(); ++ virtual bool ReadyForSchedule( bool bTimerOnly, sal_uInt64 nTimeNow ) const SAL_OVERRIDE; ++ virtual bool IsIdle() const SAL_OVERRIDE; ++ virtual sal_uInt64 UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const SAL_OVERRIDE; + + public: + Timer( const sal_Char *pDebugName = NULL ); +@@ -51,7 +49,6 @@ public: + void Timeout() { Invoke(); } + Timer& operator=( const Timer& rTimer ); + virtual void Start() SAL_OVERRIDE; +- static void ImplStartTimer( ImplSVData* pSVData, sal_uInt64 nMS ); + }; + + /// An auto-timer is a multi-shot timer re-emitting itself at +diff --git a/sd/source/ui/slideshow/slideshowimpl.cxx b/sd/source/ui/slideshow/slideshowimpl.cxx +index bf61d37..c1e1064 100644 +--- a/sd/source/ui/slideshow/slideshowimpl.cxx ++++ b/sd/source/ui/slideshow/slideshowimpl.cxx +@@ -538,6 +538,8 @@ SlideshowImpl::SlideshowImpl( const Reference< XPresentation2 >& xPresentation, + mpOldActiveWindow = mpViewShell->GetActiveWindow(); + + maUpdateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, updateHdl)); ++ // Priority must not be too high or we'll starve input handling etc. ++ maUpdateTimer.SetPriority(SchedulerPriority::REPAINT); + + maDeactivateTimer.SetTimeoutHdl(LINK(this, SlideshowImpl, deactivateHdl)); + maDeactivateTimer.SetTimeout( 20 ); +@@ -746,9 +748,6 @@ void SAL_CALL SlideshowImpl::disposing() + + setActiveXToolbarsVisible( true ); + +- Application::DisableNoYieldMode(); +- Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener)); +- + mbDisposed = true; + } + +@@ -1789,22 +1788,6 @@ IMPL_LINK_NOARG_TYPED(SlideshowImpl, updateHdl, Timer *, void) + updateSlideShow(); + } + +-IMPL_LINK_NOARG(SlideshowImpl, PostYieldListener) +-{ +- // prevent me from deletion when recursing (App::Reschedule does) +- const rtl::Reference this_(this); +- +- Application::DisableNoYieldMode(); +- Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener)); +- Application::Reschedule(true); // fix for fdo#32861 - process +- // *all* outstanding events after +- // yield is done. +- if (mbDisposed) +- return 0; +- Application::Reschedule(true); +- return updateSlideShow(); +-} +- + sal_Int32 SlideshowImpl::updateSlideShow() + { + // prevent me from deletion when recursing (App::EnableYieldMode does) +@@ -1816,26 +1799,13 @@ sal_Int32 SlideshowImpl::updateSlideShow() + + try + { +- // TODO(Q3): Evaluate under various systems and setups, +- // whether this is really necessary. Under WinXP and Matrox +- // G550, the frame rates were much more steadier with this +- // tweak, although. +- +- // currently no solution, because this kills sound (at least on Windows) +- + double fUpdate = 0.0; + if( !xShow->update(fUpdate) ) + fUpdate = -1.0; + + if (mxShow.is() && (fUpdate >= 0.0)) + { +- if (::basegfx::fTools::equalZero(fUpdate)) +- { +- // Use post yield listener for short update intervalls. +- Application::EnableNoYieldMode(); +- Application::AddPostYieldListener(LINK(this, SlideshowImpl, PostYieldListener)); +- } +- else ++ if (!::basegfx::fTools::equalZero(fUpdate)) + { + // Avoid busy loop when the previous call to update() + // returns a small positive number but not 0 (which is +@@ -1852,14 +1822,11 @@ sal_Int32 SlideshowImpl::updateSlideShow() + // too high (only then conversion to milliseconds and long + // integer may lead to zero value.) + OSL_ASSERT(static_cast(fUpdate * 1000.0) > 0); +- +- Application::DisableNoYieldMode(); +- Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener)); +- +- // Use a timer for the asynchronous callback. +- maUpdateTimer.SetTimeout(static_cast(fUpdate * 1000.0)); +- maUpdateTimer.Start(); + } ++ ++ // Use our high resolution timers for the asynchronous callback. ++ maUpdateTimer.SetTimeout(static_cast(fUpdate * 1000.0)); ++ maUpdateTimer.Start(); + } + } + catch( Exception& ) +diff --git a/sd/source/ui/slideshow/slideshowimpl.hxx b/sd/source/ui/slideshow/slideshowimpl.hxx +index 3e8f00f..f75b1b7 100644 +--- a/sd/source/ui/slideshow/slideshowimpl.hxx ++++ b/sd/source/ui/slideshow/slideshowimpl.hxx +@@ -275,7 +275,6 @@ private: + void setActiveXToolbarsVisible( bool bVisible ); + + DECL_LINK_TYPED(updateHdl, Timer *, void); +- DECL_LINK( PostYieldListener, void* ); + DECL_LINK_TYPED(ReadyForNextInputHdl, Timer *, void); + DECL_LINK( endPresentationHdl, void* ); + DECL_LINK( ContextMenuSelectHdl, Menu * ); +@@ -311,7 +310,7 @@ private: + static void setAutoSaveState( bool bOn ); + void gotoPreviousSlide (const bool bSkipAllMainSequenceEffects); + +- /** Called by PostYieldListener and updateHdl handlers this method is ++ /** Called by our maUpdateTimer's updateHdl handler this method is + responsible to call the slideshow update() method and, depending on + its return value, wait for a certain amount of time before another + call to update() is scheduled. +diff --git a/toolkit/source/awt/vclxtoolkit.cxx b/toolkit/source/awt/vclxtoolkit.cxx +index ee1f9b8..f11e167 100644 +--- a/toolkit/source/awt/vclxtoolkit.cxx ++++ b/toolkit/source/awt/vclxtoolkit.cxx +@@ -1892,7 +1892,7 @@ void SAL_CALL VCLXToolkit::processEventsToIdle() + throw (::com::sun::star::uno::RuntimeException, std::exception) + { + SolarMutexGuard aSolarGuard; +- Scheduler::ProcessTaskScheduling(false); ++ Scheduler::ProcessEventsToIdle(); + } + + } +diff --git a/vcl/headless/svpinst.cxx b/vcl/headless/svpinst.cxx +index 7c94f66..39dfe25 100644 +--- a/vcl/headless/svpinst.cxx ++++ b/vcl/headless/svpinst.cxx +@@ -259,8 +259,10 @@ SalBitmap* SvpSalInstance::CreateSalBitmap() + #endif + } + +-void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult SvpSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased) + { ++ (void) nReleased; ++ assert(nReleased == 0); // not implemented + // first, check for already queued events. + + // release yield mutex +@@ -324,6 +326,9 @@ void SvpSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) + + DoReleaseYield(nTimeoutMS); + } ++ ++ return bEvent ? SalYieldResult::EVENT : ++ SalYieldResult::TIMEOUT; + } + + void SvpSalInstance::DoReleaseYield( int nTimeoutMS ) +diff --git a/vcl/inc/headless/svpinst.hxx b/vcl/inc/headless/svpinst.hxx +index 44795d5..0d11b1d 100644 +--- a/vcl/inc/headless/svpinst.hxx ++++ b/vcl/inc/headless/svpinst.hxx +@@ -157,7 +157,7 @@ public: + // wait next event and dispatch + // must returned by UserEvent (SalFrame::PostEvent) + // and timer +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ) SAL_OVERRIDE; ++ virtual SalYieldResult DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) SAL_OVERRIDE; + virtual bool AnyInput( VclInputFlags nType ) SAL_OVERRIDE; + + // may return NULL to disable session management +diff --git a/vcl/inc/osx/salinst.h b/vcl/inc/osx/salinst.h +index b2d6133..9df7d02 100644 +--- a/vcl/inc/osx/salinst.h ++++ b/vcl/inc/osx/salinst.h +@@ -109,7 +109,7 @@ public: + virtual sal_uLong ReleaseYieldMutex() SAL_OVERRIDE; + virtual void AcquireYieldMutex( sal_uLong nCount ) SAL_OVERRIDE; + virtual bool CheckYieldMutex() SAL_OVERRIDE; +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ) SAL_OVERRIDE; ++ virtual +SalYieldResult DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) SAL_OVERRIDE; + virtual bool AnyInput( VclInputFlags nType ) SAL_OVERRIDE; + virtual SalMenu* CreateMenu( bool bMenuBar, Menu* pVCLMenu ) SAL_OVERRIDE; + virtual void DestroyMenu( SalMenu* ) SAL_OVERRIDE; +diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx +index eb53177..f49bb4c 100644 +--- a/vcl/inc/salinst.hxx ++++ b/vcl/inc/salinst.hxx +@@ -58,6 +58,8 @@ struct SystemWindowData; + class Menu; + enum class VclInputFlags; + ++enum SalYieldResult { EVENT, TIMEOUT }; ++ + class VCL_PLUGIN_PUBLIC SalInstance + { + private: +@@ -124,10 +126,13 @@ public: + // return true, if yield mutex is owned by this thread, else false + virtual bool CheckYieldMutex() = 0; + +- // wait next event and dispatch +- // must returned by UserEvent (SalFrame::PostEvent) +- // and timer +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ) = 0; ++ /** ++ * Wait for the next event (if @bWait) and dispatch it, ++ * includes posted events, and timers. ++ * If @bHandleAllCurrentEvents - dispatch multiple posted ++ * user events. Returns true if events needed processing. ++ */ ++ virtual SalYieldResult DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) = 0; + virtual bool AnyInput( VclInputFlags nType ) = 0; + + // menus +diff --git a/vcl/inc/saltimer.hxx b/vcl/inc/saltimer.hxx +index 1e1a941..3907ec1 100644 +--- a/vcl/inc/saltimer.hxx ++++ b/vcl/inc/saltimer.hxx +@@ -54,6 +54,23 @@ public: + } + }; + ++class Scheduler; ++ ++// Internal scheduler record holding intrusive linked list pieces ++struct ImplSchedulerData ++{ ++ ImplSchedulerData* mpNext; // Pointer to the next element in list ++ Scheduler* mpScheduler; // Pointer to VCL Scheduler instance ++ bool mbDelete; // Destroy this scheduler? ++ bool mbInScheduler; // Scheduler currently processed? ++ sal_uInt64 mnUpdateTime; // Last Update Time ++ ++ void Invoke(); ++ ++ const char *GetDebugName() const; ++ static ImplSchedulerData *GetMostImportantTask( bool bTimer ); ++}; ++ + #endif // INCLUDED_VCL_INC_SALTIMER_HXX + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx +index 5e3282a..99cb2e3 100644 +--- a/vcl/inc/svdata.hxx ++++ b/vcl/inc/svdata.hxx +@@ -125,7 +125,6 @@ struct ImplSVAppData + VclPtr mpWheelWindow; // WheelWindow + ImplHotKey* mpFirstHotKey; // HotKey-Verwaltung + ImplEventHook* mpFirstEventHook; // Event-Hooks +- VclEventListeners2* mpPostYieldListeners; // post yield listeners + sal_uInt64 mnLastInputTime; // GetLastInputTime() + sal_uInt16 mnDispatchLevel; // DispatchLevel + sal_uInt16 mnModalMode; // ModalMode Count +@@ -137,8 +136,6 @@ struct ImplSVAppData + bool mbInAppExecute; // is Application::Execute() on stack + bool mbAppQuit; // is Application::Quit() called + bool mbSettingsInit; // true: Settings are initialized +- bool mbNoYield; // Application::Yield will not wait for events if the queue is empty +- // essentially that makes it the same as Application::Reschedule + Application::DialogCancelMode meDialogCancel; // true: All Dialog::Execute() calls will be terminated immediately with return false + + /** Controls whether showing any IME status window is toggled on or off. +@@ -321,7 +318,6 @@ struct ImplSVData + SalSystem* mpSalSystem; // SalSystem interface + ResMgr* mpResMgr; // SV-Resource-Manager + sal_uInt64 mnTimerPeriod; // current timer period +- sal_uInt32 mnUpdateStack; // Scheduler on stack + ImplSVAppData maAppData; // indepen data for class Application + ImplSVGDIData maGDIData; // indepen data for Output classes + ImplSVWinData maWinData; // indepen data for Windows classes +diff --git a/vcl/inc/unx/gtk/gtkdata.hxx b/vcl/inc/unx/gtk/gtkdata.hxx +index 697fece..3a800b3 100644 +--- a/vcl/inc/unx/gtk/gtkdata.hxx ++++ b/vcl/inc/unx/gtk/gtkdata.hxx +@@ -115,7 +115,7 @@ public: + static gboolean userEventFn( gpointer data ); + + void PostUserEvent(); +- void Yield( bool bWait, bool bHandleAllCurrentEvents ); ++ SalYieldResult Yield( bool bWait, bool bHandleAllCurrentEvents ); + inline GdkDisplay *GetGdkDisplay(); + + virtual void ErrorTrapPush() SAL_OVERRIDE; +diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx +index 28bca36..189b6900 100644 +--- a/vcl/inc/unx/gtk/gtkinst.hxx ++++ b/vcl/inc/unx/gtk/gtkinst.hxx +@@ -80,7 +80,7 @@ public: + const SystemGraphicsData* ) SAL_OVERRIDE; + virtual SalBitmap* CreateSalBitmap() SAL_OVERRIDE; + +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ) SAL_OVERRIDE; ++ virtual SalYieldResult DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) SAL_OVERRIDE; + virtual bool AnyInput( VclInputFlags nType ) SAL_OVERRIDE; + + virtual GenPspGraphics *CreatePrintGraphics() SAL_OVERRIDE; +diff --git a/vcl/inc/unx/saldisp.hxx b/vcl/inc/unx/saldisp.hxx +index a304a4b..776cb64 100644 +--- a/vcl/inc/unx/saldisp.hxx ++++ b/vcl/inc/unx/saldisp.hxx +@@ -155,7 +155,7 @@ public: + virtual ~SalXLib(); + virtual void Init(); + +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ); ++ virtual SalYieldResult Yield( bool bWait, bool bHandleAllCurrentEvents ); + virtual void Wakeup(); + virtual void PostUserEvent(); + +@@ -382,7 +382,7 @@ public: + virtual ~SalX11Display(); + + virtual bool Dispatch( XEvent *pEvent ) SAL_OVERRIDE; +- virtual void Yield(); ++ virtual bool Yield(); + virtual void PostUserEvent() SAL_OVERRIDE; + + bool IsEvent(); +diff --git a/vcl/inc/unx/salinst.h b/vcl/inc/unx/salinst.h +index 381ddda..72939e8 100644 +--- a/vcl/inc/unx/salinst.h ++++ b/vcl/inc/unx/salinst.h +@@ -71,7 +71,7 @@ public: + virtual SalBitmap* CreateSalBitmap() SAL_OVERRIDE; + virtual SalSession* CreateSalSession() SAL_OVERRIDE; + +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ) SAL_OVERRIDE; ++ virtual SalYieldResult DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) SAL_OVERRIDE; + virtual bool AnyInput( VclInputFlags nType ) SAL_OVERRIDE; + + virtual void* GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, int& rReturnedBytes ) SAL_OVERRIDE; +diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h +index 450d07c..0c9c759 100644 +--- a/vcl/inc/win/salinst.h ++++ b/vcl/inc/win/salinst.h +@@ -62,7 +62,7 @@ public: + virtual void AcquireYieldMutex( sal_uIntPtr nCount ) SAL_OVERRIDE; + virtual bool CheckYieldMutex() SAL_OVERRIDE; + +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ) SAL_OVERRIDE; ++ virtual SalYieldResult DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong nReleased) SAL_OVERRIDE; + virtual bool AnyInput( VclInputFlags nType ) SAL_OVERRIDE; + virtual SalMenu* CreateMenu( bool bMenuBar, Menu* ) SAL_OVERRIDE; + virtual void DestroyMenu( SalMenu* ) SAL_OVERRIDE; +diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx +index 58a52d5..e20bbdd 100644 +--- a/vcl/osx/salinst.cxx ++++ b/vcl/osx/salinst.cxx +@@ -554,8 +554,11 @@ class ReleasePoolHolder + ~ReleasePoolHolder() { [mpPool release]; } + }; + +-void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult AquaSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased) + { ++ (void) nReleased; ++ assert(nReleased == 0); // not implemented ++ + // ensure that the per thread autorelease pool is top level and + // will therefore not be destroyed by cocoa implicitly + SalData::ensureThreadAutoreleasePool(); +@@ -592,12 +595,13 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) + osl_setCondition( maWaitingYieldCond ); + // return if only one event is asked for + if( ! bHandleAllCurrentEvents ) +- return; ++ return SalYieldResult::EVENT; + } + } + + // handle cocoa event queue +- // cocoa events mye be only handled in the thread the NSApp was created ++ // cocoa events may be only handled in the thread the NSApp was created ++ bool bHadEvent = false; + if( isNSAppThread() && mnActivePrintJobs == 0 ) + { + // we need to be woken up by a cocoa-event +@@ -607,7 +611,6 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) + + // handle available events + NSEvent* pEvent = nil; +- bool bHadEvent = false; + do + { + sal_uLong nCount = ReleaseYieldMutex(); +@@ -702,6 +705,8 @@ void AquaSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) + bInAppEvent = false; + } + } ++ ++ return bHadEvent ? SalYieldResult::EVENT : SalYieldResult::TIMEOUT; + } + + bool AquaSalInstance::AnyInput( VclInputFlags nType ) +diff --git a/vcl/qa/cppunit/timer.cxx b/vcl/qa/cppunit/timer.cxx +index 144d626..bac8a62 100644 +--- a/vcl/qa/cppunit/timer.cxx ++++ b/vcl/qa/cppunit/timer.cxx +@@ -126,7 +126,7 @@ void TimerTest::testIdleMainloop() + // can't test this via Application::Yield since this + // also processes all tasks directly via the scheduler. + pSVData->maAppData.mnDispatchLevel++; +- pSVData->mpDefInst->Yield( true, false ); ++ pSVData->mpDefInst->DoYield(true, false, 0); + pSVData->maAppData.mnDispatchLevel--; + } + CPPUNIT_ASSERT_MESSAGE("mainloop idle triggered", bTriggered); +diff --git a/vcl/source/app/idle.cxx b/vcl/source/app/idle.cxx +index 901c44e..8f475de 100644 +--- a/vcl/source/app/idle.cxx ++++ b/vcl/source/app/idle.cxx +@@ -18,8 +18,7 @@ + */ + + #include +-#include +-#include "svdata.hxx" ++#include "saltimer.hxx" + + void Idle::Invoke() + { +@@ -45,35 +44,36 @@ Idle::Idle( const Idle& rIdle ) : Scheduler(rIdle) + void Idle::Start() + { + Scheduler::Start(); +- ImplSVData* pSVData = ImplGetSVData(); +- Timer::ImplStartTimer( pSVData, 0 ); ++ Scheduler::ImplStartTimer(Scheduler::ImmediateTimeoutMs); + } + +-bool Idle::ReadyForSchedule( bool bTimer ) ++bool Idle::ReadyForSchedule( bool bTimerOnly, sal_uInt64 /* nTimeNow */ ) const + { +- // tdf#91727 - We need to re-work this to allow only UI idle handlers +- // and not timeouts to be processed in some limited scenarios +- (void)bTimer; +- return true; // !bTimer ++ // always ready if not only looking for timers. ++ return !bTimerOnly; + } + +-sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 /* nTime */ ) ++bool Idle::IsIdle() const ++{ ++ return true; ++} ++ ++sal_uInt64 Idle::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 /* nTime */ ) const + { + switch (mePriority) { + case SchedulerPriority::HIGHEST: + case SchedulerPriority::HIGH: + case SchedulerPriority::RESIZE: + case SchedulerPriority::REPAINT: +- nMinPeriod = 1; // don't wait. ++ nMinPeriod = ImmediateTimeoutMs; // don't wait. + break; + default: + // FIXME: tdf#92036 workaround, I should be 1 too - wait 5ms +- if (nMinPeriod > 5) ++ if (nMinPeriod < 5) + nMinPeriod = 5; + break; + } + return nMinPeriod; + } + +- + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx +index c3cea78..dd004fb 100644 +--- a/vcl/source/app/scheduler.cxx ++++ b/vcl/source/app/scheduler.cxx +@@ -20,10 +20,9 @@ + #include + #include + #include +-#include + #include +- +-#define MAX_TIMER_PERIOD SAL_MAX_UINT64 ++#include ++#include + + void ImplSchedulerData::Invoke() + { +@@ -39,15 +38,17 @@ void ImplSchedulerData::Invoke() + mbInScheduler = false; + } + +-ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimer ) ++ImplSchedulerData *ImplSchedulerData::GetMostImportantTask( bool bTimerOnly ) + { + ImplSVData* pSVData = ImplGetSVData(); + ImplSchedulerData *pMostUrgent = NULL; + ++ sal_uInt64 nTimeNow = tools::Time::GetSystemTicks(); + for ( ImplSchedulerData *pSchedulerData = pSVData->mpFirstSchedulerData; pSchedulerData; pSchedulerData = pSchedulerData->mpNext ) + { +- if ( !pSchedulerData->mpScheduler || pSchedulerData->mbDelete || pSchedulerData->mnUpdateStack >= pSVData->mnUpdateStack +- || !pSchedulerData->mpScheduler->ReadyForSchedule( bTimer ) || !pSchedulerData->mpScheduler->IsActive()) ++ if ( !pSchedulerData->mpScheduler || pSchedulerData->mbDelete || ++ !pSchedulerData->mpScheduler->ReadyForSchedule( bTimerOnly, nTimeNow ) || ++ !pSchedulerData->mpScheduler->IsActive()) + continue; + if (!pMostUrgent) + pMostUrgent = pSchedulerData; +@@ -94,22 +95,88 @@ void Scheduler::ImplDeInitScheduler() + } + while ( pSchedulerData ); + +- pSVData->mpFirstSchedulerData = NULL; +- pSVData->mnTimerPeriod = 0; ++ pSVData->mpFirstSchedulerData = NULL; ++ pSVData->mnTimerPeriod = 0; + } + + delete pSVData->mpSalTimer; + pSVData->mpSalTimer = 0; + } + ++/** ++ * Start a new timer if we need to for @nMS duration. ++ * ++ * if this is longer than the existing duration we're ++ * waiting for, do nothing - unless @bForce - which means ++ * to reset the minimum period; used by the scheduled itself. ++ */ ++void Scheduler::ImplStartTimer(sal_uInt64 nMS, bool bForce) ++{ ++ ImplSVData* pSVData = ImplGetSVData(); ++ InitSystemTimer(pSVData); ++ ++ // only if smaller timeout, to avoid skipping. ++ if (bForce || nMS < pSVData->mnTimerPeriod) ++ { ++ pSVData->mnTimerPeriod = nMS; ++ pSVData->mpSalTimer->Start(nMS); ++ } ++} ++ ++/** ++* Initialize the platform specific timer on which all the ++* platform independent timers are built ++*/ ++void Scheduler::InitSystemTimer(ImplSVData* pSVData) ++{ ++ assert(pSVData != nullptr); ++ if (!pSVData->mpSalTimer) ++ { ++ pSVData->mnTimerPeriod = MaximumTimeoutMs; ++ pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer(); ++ pSVData->mpSalTimer->SetCallback(CallbackTaskScheduling); ++ } ++} ++ + void Scheduler::CallbackTaskScheduling(bool ignore) + { + // this function is for the saltimer callback + (void)ignore; +- Scheduler::ProcessTaskScheduling( true ); ++ Scheduler::ProcessTaskScheduling( false ); ++} ++ ++bool Scheduler::ProcessTaskScheduling( bool bTimerOnly ) ++{ ++ ImplSchedulerData* pSchedulerData; ++ ++ // tdf#91727 - NB. bTimerOnly is ultimately not used ++ if ((pSchedulerData = ImplSchedulerData::GetMostImportantTask(bTimerOnly))) ++ { ++ SAL_INFO("vcl.schedule", "Invoke task " << pSchedulerData->GetDebugName()); ++ ++ pSchedulerData->mnUpdateTime = tools::Time::GetSystemTicks(); ++ pSchedulerData->Invoke(); ++ return true; ++ } ++ else ++ return false; ++} ++ ++void Scheduler::ProcessEventsToIdle() ++{ ++ // FIXME: really we should process incoming OS events too ... ++ int nSanity = 1000; ++ while (Scheduler::ProcessTaskScheduling(false)) ++ { ++ if (nSanity-- < 0) ++ { ++ SAL_WARN("vcl.schedule", "Unexpected volume of events to process"); ++ break; ++ } ++ } + } + +-void Scheduler::ProcessTaskScheduling( bool bTimer ) ++sal_uInt64 Scheduler::CalculateMinimumTimeout( bool &bHasActiveIdles ) + { + // process all pending Tasks + // if bTimer True, only handle timer +@@ -117,63 +184,70 @@ void Scheduler::ProcessTaskScheduling( bool bTimer ) + ImplSchedulerData* pPrevSchedulerData = NULL; + ImplSVData* pSVData = ImplGetSVData(); + sal_uInt64 nTime = tools::Time::GetSystemTicks(); +- sal_uInt64 nMinPeriod = MAX_TIMER_PERIOD; +- pSVData->mnUpdateStack++; +- +- // tdf#91727 - NB. bTimer is ultimately not used +- if ((pSchedulerData = ImplSchedulerData::GetMostImportantTask(bTimer))) +- { +- pSchedulerData->mnUpdateTime = nTime; +- pSchedulerData->Invoke(); +- } ++ sal_uInt64 nMinPeriod = MaximumTimeoutMs; + ++ SAL_INFO("vcl.schedule", "Calculating minimum timeout:"); + pSchedulerData = pSVData->mpFirstSchedulerData; + while ( pSchedulerData ) + { +- if( pSchedulerData->mbInScheduler ) +- { +- pPrevSchedulerData = pSchedulerData; +- pSchedulerData = pSchedulerData->mpNext; +- } ++ ImplSchedulerData *pNext = pSchedulerData->mpNext; ++ + // Should Task be released from scheduling? +- else if ( pSchedulerData->mbDelete ) ++ if ( !pSchedulerData->mbInScheduler && ++ pSchedulerData->mbDelete ) + { + if ( pPrevSchedulerData ) + pPrevSchedulerData->mpNext = pSchedulerData->mpNext; + else + pSVData->mpFirstSchedulerData = pSchedulerData->mpNext; + if ( pSchedulerData->mpScheduler ) +- pSchedulerData->mpScheduler->mpSchedulerData = NULL; +- ImplSchedulerData* pTempSchedulerData = pSchedulerData; +- pSchedulerData = pSchedulerData->mpNext; +- delete pTempSchedulerData; ++ pSchedulerData->mpScheduler->mpSchedulerData = nullptr; ++ pNext = pSchedulerData->mpNext; ++ delete pSchedulerData; + } + else + { +- pSchedulerData->mnUpdateStack = 0; +- nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( nMinPeriod, nTime ); ++ if (!pSchedulerData->mbInScheduler) ++ { ++ if ( !pSchedulerData->mpScheduler->IsIdle() ) ++ { ++ sal_uInt64 nOldMinPeriod = nMinPeriod; ++ nMinPeriod = pSchedulerData->mpScheduler->UpdateMinPeriod( ++ nOldMinPeriod, nTime ); ++ SAL_INFO("vcl.schedule", "Have active timer " << ++ pSchedulerData->GetDebugName() << ++ "update min period from " << nOldMinPeriod << ++ " to " << nMinPeriod); ++ } ++ else ++ { ++ SAL_INFO("vcl.schedule", "Have active idle " << ++ pSchedulerData->GetDebugName()); ++ bHasActiveIdles = true; ++ } ++ } + pPrevSchedulerData = pSchedulerData; +- pSchedulerData = pSchedulerData->mpNext; + } ++ pSchedulerData = pNext; + } + +- // delete clock if no more timers available ++ // delete clock if no more timers available, + if ( !pSVData->mpFirstSchedulerData ) + { + if ( pSVData->mpSalTimer ) + pSVData->mpSalTimer->Stop(); +- pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; ++ nMinPeriod = MaximumTimeoutMs; ++ pSVData->mnTimerPeriod = nMinPeriod; ++ SAL_INFO("vcl.schedule", "Unusual - no more timers available - stop timer"); + } + else + { +- Timer::ImplStartTimer( pSVData, nMinPeriod ); ++ Scheduler::ImplStartTimer(nMinPeriod, true); ++ SAL_INFO("vcl.schedule", "Calculated minimum timeout as " << nMinPeriod << " and " << ++ (const char *)(bHasActiveIdles ? "has active idles" : "no idles")); + } +- pSVData->mnUpdateStack--; +-} + +-void Scheduler::SetPriority( SchedulerPriority ePriority ) +-{ +- mePriority = ePriority; ++ return nMinPeriod; + } + + void Scheduler::Start() +@@ -205,7 +279,6 @@ void Scheduler::Start() + } + mpSchedulerData->mbDelete = false; + mpSchedulerData->mnUpdateTime = tools::Time::GetSystemTicks(); +- mpSchedulerData->mnUpdateStack = pSVData->mnUpdateStack; + } + + void Scheduler::Stop() +@@ -221,7 +294,7 @@ Scheduler& Scheduler::operator=( const Scheduler& rScheduler ) + if ( IsActive() ) + Stop(); + +- mbActive = false; ++ mbActive = false; + mePriority = rScheduler.mePriority; + + if ( rScheduler.IsActive() ) +@@ -257,3 +330,10 @@ Scheduler::~Scheduler() + } + } + ++const char *ImplSchedulerData::GetDebugName() const ++{ ++ return mpScheduler && mpScheduler->GetDebugName() ? ++ mpScheduler->GetDebugName() : "unknown"; ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx +index c261a37..302c4a7 100644 +--- a/vcl/source/app/svapp.cxx ++++ b/vcl/source/app/svapp.cxx +@@ -338,48 +338,86 @@ void Application::Execute() + pSVData->maAppData.mbInAppExecute = false; + } + +-inline void ImplYield( bool i_bWait, bool i_bAllEvents ) ++inline void ImplYield(bool i_bWait, bool i_bAllEvents, sal_uLong const nReleased) + { + ImplSVData* pSVData = ImplGetSVData(); + +- //Process all Tasks +- Scheduler::ProcessTaskScheduling(false); ++ SAL_INFO("vcl.schedule", "Enter ImplYield: " << (i_bWait ? "wait" : "no wait") << ++ ": " << (i_bAllEvents ? "all events" : "one event") << ": " << nReleased); + ++ bool bHasActiveIdles = false; ++ sal_uInt64 nMinTimeout = 0; ++ if (nReleased == 0) // else thread doesn't have SolarMutex so avoid race ++ nMinTimeout = Scheduler::CalculateMinimumTimeout(bHasActiveIdles); ++ ++ // FIXME: should use returned value as param to DoYield ++ (void)nMinTimeout; ++ ++ // If we have idles, don't wait for the timeout; check for events ++ // and come back as quick as possible. ++ if (bHasActiveIdles) ++ i_bWait = false; ++ ++ // TODO: there's a data race here on WNT only because ImplYield may be ++ // called without SolarMutex; if we can get rid of LazyDelete (with VclPtr) ++ // then the only remaining use of mnDispatchLevel is in OSX specific code ++ // so that would effectively eliminate the race on WNT + pSVData->maAppData.mnDispatchLevel++; ++ + // do not wait for events if application was already quit; in that + // case only dispatch events already available + // do not wait for events either if the app decided that it is too busy for timers + // (feature added for the slideshow) +- pSVData->mpDefInst->Yield( i_bWait && !pSVData->maAppData.mbAppQuit && !pSVData->maAppData.mbNoYield, i_bAllEvents ); ++ SalYieldResult eResult = ++ pSVData->mpDefInst->DoYield( ++ i_bWait && !pSVData->maAppData.mbAppQuit, ++ i_bAllEvents, nReleased); ++ ++ SAL_INFO("vcl.schedule", "DoYield with " << (bHasActiveIdles ? "active idles" : "no ides") << ++ " returns: " << (eResult == SalYieldResult::EVENT ? "processed event" : "timeout")); ++ + pSVData->maAppData.mnDispatchLevel--; + + DBG_TESTSOLARMUTEX(); // must be locked on return from Yield + ++ // Process all Tasks ++ Scheduler::ProcessTaskScheduling(eResult == SalYieldResult::EVENT); ++ + // flush lazy deleted objects + if( pSVData->maAppData.mnDispatchLevel == 0 ) + vcl::LazyDelete::flush(); + +- // the system timer events will not necessarily come in non waiting mode +- // e.g. on OS X; need to trigger timer checks manually +- if( pSVData->maAppData.mbNoYield ) +- { +- //Process all timers +- Scheduler::ProcessTaskScheduling(true); +- } +- +- // call post yield listeners +- if( pSVData->maAppData.mpPostYieldListeners ) +- pSVData->maAppData.mpPostYieldListeners->callListeners( NULL ); ++ SAL_INFO("vcl.schedule", "Leave ImplYield"); + } + + void Application::Reschedule( bool i_bAllEvents ) + { +- ImplYield( false, i_bAllEvents ); ++ ImplYield(false, i_bAllEvents, 0); + } + + void Application::Yield() + { +- ImplYield( true, false ); ++ ImplYield(true, false, 0); ++} ++ ++void Application::ReAcquireSolarMutex(sal_uLong const nReleased) ++{ ++ // 0 would mean that events/timers will be handled without locking ++ // SolarMutex (racy) ++ assert(nReleased != 0); ++#ifdef WNT ++ if (ImplGetSVData()->mbDeInit) // do not Yield in DeInitVCL ++ AcquireSolarMutex(nReleased); ++ else ++ ImplYield(false, false, nReleased); ++#else ++ // a) Yield is not needed on non-WNT platforms ++ // b) some Yield implementations for X11 (e.g. kde4) make it non-obvious ++ // how to use nReleased ++ // c) would require a review of what all Yield implementations do ++ // currently _before_ releasing SolarMutex that would run without lock ++ AcquireSolarMutex(nReleased); ++#endif + } + + IMPL_STATIC_LINK_NOARG( ImplSVAppData, ImplQuitMsg ) +@@ -965,33 +1003,6 @@ void Application::RemoveIdleHdl( const Link<>& rLink ) + pSVData->maAppData.mpIdleMgr->RemoveIdleHdl( rLink ); + } + +-void Application::EnableNoYieldMode() +-{ +- ImplSVData* pSVData = ImplGetSVData(); +- pSVData->maAppData.mbNoYield = true; +-} +- +-void Application::DisableNoYieldMode() +-{ +- ImplSVData* pSVData = ImplGetSVData(); +- pSVData->maAppData.mbNoYield = false; +-} +- +-void Application::AddPostYieldListener( const Link<>& i_rListener ) +-{ +- ImplSVData* pSVData = ImplGetSVData(); +- if( ! pSVData->maAppData.mpPostYieldListeners ) +- pSVData->maAppData.mpPostYieldListeners = new VclEventListeners2(); +- pSVData->maAppData.mpPostYieldListeners->addListener( i_rListener ); +-} +- +-void Application::RemovePostYieldListener( const Link<>& i_rListener ) +-{ +- ImplSVData* pSVData = ImplGetSVData(); +- if( pSVData->maAppData.mpPostYieldListeners ) +- pSVData->maAppData.mpPostYieldListeners->removeListener( i_rListener ); +-} +- + WorkWindow* Application::GetAppWindow() + { + return ImplGetSVData()->maWinData.mpAppWin; +diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx +index 72881a6..23757e8 100644 +--- a/vcl/source/app/svmain.cxx ++++ b/vcl/source/app/svmain.cxx +@@ -508,11 +508,6 @@ void DeInitVCL() + delete pSVData->maAppData.mpKeyListeners; + pSVData->maAppData.mpKeyListeners = NULL; + } +- if ( pSVData->maAppData.mpPostYieldListeners ) +- { +- delete pSVData->maAppData.mpPostYieldListeners; +- pSVData->maAppData.mpPostYieldListeners = NULL; +- } + + if ( pSVData->maAppData.mpFirstHotKey ) + ImplFreeHotKeyData(); +diff --git a/vcl/source/app/timer.cxx b/vcl/source/app/timer.cxx +index 7d92283..1766d7f 100644 +--- a/vcl/source/app/timer.cxx ++++ b/vcl/source/app/timer.cxx +@@ -19,46 +19,30 @@ + + #include + #include +-#include +-#include +-#include ++#include "saltimer.hxx" + +-#define MAX_TIMER_PERIOD SAL_MAX_UINT64 +- +-void Timer::ImplStartTimer( ImplSVData* pSVData, sal_uInt64 nMS ) ++void Timer::SetDeletionFlags() + { +- InitSystemTimer(); +- +- if ( !nMS ) +- nMS = 1; +- +- // Assume underlying timers are recurring timers, if same period - just wait. +- if ( nMS != pSVData->mnTimerPeriod ) ++ // If no AutoTimer, then stop. ++ if ( !mbAuto ) + { +- pSVData->mnTimerPeriod = nMS; +- pSVData->mpSalTimer->Start( nMS ); ++ mpSchedulerData->mbDelete = true; ++ mbActive = false; + } + } + +-void Timer::SetDeletionFlags() ++bool Timer::ReadyForSchedule( bool /* bTimerOnly */, sal_uInt64 nTimeNow ) const + { +- // if no AutoTimer than stop +- if ( !mbAuto ) +- { +- mpSchedulerData->mbDelete = true; +- mbActive = false; +- } ++ return (mpSchedulerData->mnUpdateTime + mnTimeout) <= nTimeNow; + } + +-bool Timer::ReadyForSchedule( bool bTimer ) ++bool Timer::IsIdle() const + { +- (void)bTimer; +- return (mpSchedulerData->mnUpdateTime + mnTimeout) <= tools::Time::GetSystemTicks(); ++ return false; + } + +-sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) ++sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) const + { +- sal_uInt64 nNewTime = tools::Time::GetSystemTicks(); + sal_uInt64 nDeltaTime; + //determine smallest time slot + if( mpSchedulerData->mnUpdateTime == nTime ) +@@ -70,11 +54,11 @@ sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) + else + { + nDeltaTime = mpSchedulerData->mnUpdateTime + mnTimeout; +- if( nDeltaTime < nNewTime ) +- nMinPeriod = 1; ++ if( nDeltaTime < nTime ) ++ nMinPeriod = ImmediateTimeoutMs; + else + { +- nDeltaTime -= nNewTime; ++ nDeltaTime -= nTime; + if( nDeltaTime < nMinPeriod ) + nMinPeriod = nDeltaTime; + } +@@ -83,32 +67,19 @@ sal_uInt64 Timer::UpdateMinPeriod( sal_uInt64 nMinPeriod, sal_uInt64 nTime ) + return nMinPeriod; + } + +-/** +- * Initialize the platform specific timer on which all the +- * platform independent timers are built +- */ +-void Timer::InitSystemTimer() +-{ +- ImplSVData* pSVData = ImplGetSVData(); +- if( ! pSVData->mpSalTimer ) +- { +- pSVData->mnTimerPeriod = MAX_TIMER_PERIOD; +- pSVData->mpSalTimer = pSVData->mpDefInst->CreateSalTimer(); +- pSVData->mpSalTimer->SetCallback( CallbackTaskScheduling ); +- } +-} +- +-Timer::Timer(const sal_Char *pDebugName) : Scheduler(pDebugName) ++Timer::Timer(const sal_Char *pDebugName) : ++ Scheduler(pDebugName), ++ mnTimeout(ImmediateTimeoutMs), ++ mbAuto(false) + { +- mnTimeout = 1; +- mbAuto = false; + mePriority = SchedulerPriority::HIGHEST; + } + +-Timer::Timer( const Timer& rTimer ) : Scheduler(rTimer) ++Timer::Timer( const Timer& rTimer ) : ++ Scheduler(rTimer), ++ mnTimeout(rTimer.mnTimeout), ++ mbAuto(rTimer.mbAuto) + { +- mnTimeout = rTimer.mnTimeout; +- mbAuto = rTimer.mbAuto; + maTimeoutHdl = rTimer.maTimeoutHdl; + } + +@@ -120,21 +91,16 @@ void Timer::Invoke() + void Timer::Start() + { + Scheduler::Start(); +- +- ImplSVData* pSVData = ImplGetSVData(); +- if ( mnTimeout < pSVData->mnTimerPeriod ) +- Timer::ImplStartTimer( pSVData, mnTimeout ); ++ Scheduler::ImplStartTimer(mnTimeout); + } + + void Timer::SetTimeout( sal_uInt64 nNewTimeout ) + { + mnTimeout = nNewTimeout; +- // if timer is active then renew clock ++ // If timer is active, then renew clock. + if ( mbActive ) + { +- ImplSVData* pSVData = ImplGetSVData(); +- if ( !pSVData->mnUpdateStack && (mnTimeout < pSVData->mnTimerPeriod) ) +- Timer::ImplStartTimer( pSVData, mnTimeout ); ++ Scheduler::ImplStartTimer(mnTimeout); + } + } + +diff --git a/vcl/unx/generic/app/saldata.cxx b/vcl/unx/generic/app/saldata.cxx +index b2212a4..ac872b7 100644 +--- a/vcl/unx/generic/app/saldata.cxx ++++ b/vcl/unx/generic/app/saldata.cxx +@@ -619,7 +619,8 @@ bool SalXLib::CheckTimeout( bool bExecuteTimers ) + return bRet; + } + +-void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult ++SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + { + blockIdleTimeout = !bWait; + // check for timeouts here if you want to make screenshots +@@ -642,7 +643,7 @@ void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + if( ! bHandleAllCurrentEvents ) + { + blockIdleTimeout = false; +- return; ++ return SalYieldResult::EVENT; + } + } + } +@@ -657,6 +658,8 @@ void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + timeval Timeout = noyield__; + timeval *pTimeout = &Timeout; + ++ bool bHandledEvent = false; ++ + if (bWait) + { + pTimeout = 0; +@@ -717,7 +720,7 @@ void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + if (nFound == 0) + { + blockIdleTimeout = false; +- return; ++ return SalYieldResult::TIMEOUT; + } + + for ( int nFD = 0; nFD < nFDs_; nFD++ ) +@@ -736,6 +739,7 @@ void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + for( int i = 0; pEntry->IsEventQueued() && i < nMaxEvents; i++ ) + { + pEntry->HandleNextEvent(); ++ bHandledEvent = true; + // if a recursive call has done the job + // so abort here + } +@@ -745,6 +749,9 @@ void SalXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + } + } + blockIdleTimeout = false; ++ ++ return bHandledEvent ? SalYieldResult::EVENT ++ : SalYieldResult::TIMEOUT; + } + + void SalXLib::Wakeup() +diff --git a/vcl/unx/generic/app/saldisp.cxx b/vcl/unx/generic/app/saldisp.cxx +index ff71bc6..c039ee2 100644 +--- a/vcl/unx/generic/app/saldisp.cxx ++++ b/vcl/unx/generic/app/saldisp.cxx +@@ -1878,10 +1878,10 @@ bool SalX11Display::IsEvent() + return false; + } + +-void SalX11Display::Yield() ++bool SalX11Display::Yield() + { + if( DispatchInternalEvent() ) +- return; ++ return true; + + XEvent aEvent; + DBG_ASSERT( static_cast(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() == +@@ -1890,7 +1890,8 @@ void SalX11Display::Yield() + + XNextEvent( pDisp_, &aEvent ); + +- Dispatch( &aEvent ); ++ // FIXME: under-convinced by Dispatch boolean return value vs. salframe. ++ bool bProcessedEvent = Dispatch( &aEvent ); + + #ifdef DBG_UTIL + if( GetX11SalData()->HasXErrorOccurred() ) +@@ -1900,6 +1901,8 @@ void SalX11Display::Yield() + } + #endif + GetX11SalData()->ResetXErrorOccurred(); ++ ++ return bProcessedEvent; + } + + bool SalX11Display::Dispatch( XEvent *pEvent ) +diff --git a/vcl/unx/generic/app/salinst.cxx b/vcl/unx/generic/app/salinst.cxx +index 9c00f6d..7ac0789 100644 +--- a/vcl/unx/generic/app/salinst.cxx ++++ b/vcl/unx/generic/app/salinst.cxx +@@ -151,9 +151,11 @@ bool X11SalInstance::AnyInput(VclInputFlags nType) + return bRet; + } + +-void X11SalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult X11SalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased) + { +- mpXLib->Yield( bWait, bHandleAllCurrentEvents ); ++ (void) nReleased; ++ assert(nReleased == 0); // not implemented ++ return mpXLib->Yield( bWait, bHandleAllCurrentEvents ); + } + + void* X11SalInstance::GetConnectionIdentifier( ConnectionIdentifierType& rReturnedType, +diff --git a/vcl/unx/gtk/a11y/atkwrapper.cxx b/vcl/unx/gtk/a11y/atkwrapper.cxx +index 30cfa9c..006df49 100644 +--- a/vcl/unx/gtk/a11y/atkwrapper.cxx ++++ b/vcl/unx/gtk/a11y/atkwrapper.cxx +@@ -872,7 +872,7 @@ atk_object_wrapper_new( const ::com::sun::star::uno::Reference< ::com::sun::star + uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY); + if( xBroadcaster.is() ) + xBroadcaster->addAccessibleEventListener( static_cast< accessibility::XAccessibleEventListener * > ( new AtkListener(pWrap) ) ); +- else ++ else + OSL_ASSERT( false ); + } + +diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx +index 2d8e26c..b59b962 100644 +--- a/vcl/unx/gtk/app/gtkdata.cxx ++++ b/vcl/unx/gtk/app/gtkdata.cxx +@@ -566,9 +566,11 @@ void GtkData::Dispose() + deInitNWF(); + } + +-void GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++/// Allows events to be processed, returns true if we processed an event. ++SalYieldResult GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents ) + { + blockIdleTimeout = !bWait; ++ + /* #i33212# only enter g_main_context_iteration in one thread at any one + * time, else one of them potentially will never end as long as there is + * another thread in there. Having only one yieldin thread actually dispatch +@@ -584,7 +586,7 @@ void GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents ) + else if( ! bWait ) + { + blockIdleTimeout = false; +- return; // someone else is waiting already, return ++ return SalYieldResult::TIMEOUT; // someone else is waiting already, return + } + + if( bDispatchThread ) +@@ -618,6 +620,9 @@ void GtkData::Yield( bool bWait, bool bHandleAllCurrentEvents ) + osl_setCondition( m_aDispatchCondition ); // trigger non dispatch thread yields + } + blockIdleTimeout = false; ++ ++ return bWasEvent ? SalYieldResult::EVENT ++ : SalYieldResult::TIMEOUT; + } + + void GtkData::Init() +@@ -885,6 +890,9 @@ create_sal_gtk_timeout( GtkSalTimer *pTimer ) + /* unused dummy */ g_idle_remove_by_data, + NULL, NULL ); + g_source_attach( pSource, g_main_context_default() ); ++#ifdef DBG_UTIL ++ g_source_set_name( pSource, "VCL timeout source" ); ++#endif + + sal_gtk_timeout_defer( pTSource ); + +@@ -917,6 +925,8 @@ bool GtkSalTimer::Expired() + + void GtkSalTimer::Start( sal_uLong nMS ) + { ++ // glib is not 64bit safe in this regard. ++ assert( nMS <= G_MAXINT ); + m_nTimeoutMS = nMS; // for restarting + Stop(); // FIXME: ideally re-use an existing m_pTimeout + m_pTimeout = create_sal_gtk_timeout( this ); +diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx +index 601fd21..9242b88 100644 +--- a/vcl/unx/gtk/app/gtkinst.cxx ++++ b/vcl/unx/gtk/app/gtkinst.cxx +@@ -401,10 +401,12 @@ void GtkInstance::RemoveTimer (SalTimer *pTimer) + m_aTimers.erase( it ); + } + +-void GtkInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult GtkInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased) + { ++ (void) nReleased; ++ assert(nReleased == 0); // not implemented + EnsureInit(); +- GetGtkSalData()->Yield( bWait, bHandleAllCurrentEvents ); ++ return GetGtkSalData()->Yield( bWait, bHandleAllCurrentEvents ); + } + + bool GtkInstance::IsTimerExpired() +diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx +index 06e7b6d..42f8ebc 100644 +--- a/vcl/unx/kde4/KDESalDisplay.cxx ++++ b/vcl/unx/kde4/KDESalDisplay.cxx +@@ -46,14 +46,14 @@ SalKDEDisplay::~SalKDEDisplay() + pDisp_ = NULL; + } + +-void SalKDEDisplay::Yield() ++bool SalKDEDisplay::Yield() + { + if( DispatchInternalEvent() ) +- return; ++ return true; + + // Prevent blocking from Drag'n'Drop events, which may have already have processed the event + if (XEventsQueued( pDisp_, QueuedAfterReading ) == 0) +- return; ++ return false; + + DBG_ASSERT( static_cast(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() == + osl::Thread::getCurrentIdentifier(), +@@ -62,8 +62,9 @@ void SalKDEDisplay::Yield() + XEvent event; + XNextEvent( pDisp_, &event ); + if( checkDirectInputEvent( &event )) +- return; ++ return true; + qApp->x11ProcessEvent( &event ); ++ return true; + } + + // HACK: When using Qt event loop, input methods (japanese, etc.) will get broken because +diff --git a/vcl/unx/kde4/KDESalDisplay.hxx b/vcl/unx/kde4/KDESalDisplay.hxx +index f4a4146..3e027fd 100644 +--- a/vcl/unx/kde4/KDESalDisplay.hxx ++++ b/vcl/unx/kde4/KDESalDisplay.hxx +@@ -27,7 +27,7 @@ class SalKDEDisplay : public SalX11Display + SalKDEDisplay( Display* pDisp ); + virtual ~SalKDEDisplay(); + static SalKDEDisplay* self(); +- virtual void Yield() SAL_OVERRIDE; ++ virtual bool Yield() SAL_OVERRIDE; + bool checkDirectInputEvent( XEvent* ev ); + private: + Atom xim_protocol; +diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx +index 3101d37..c758e18 100644 +--- a/vcl/unx/kde4/KDEXLib.cxx ++++ b/vcl/unx/kde4/KDEXLib.cxx +@@ -281,22 +281,25 @@ void KDEXLib::socketNotifierActivated( int fd ) + sdata.handle( fd, sdata.data ); + } + +-void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + { + if( !m_isGlibEventLoopType ) + { ++ bool wasEvent = false; + if( qApp->thread() == QThread::currentThread()) + { + // even if we use the LO event loop, still process Qt's events, + // otherwise they can remain unhandled for quite a long while +- processYield( false, bHandleAllCurrentEvents ); ++ wasEvent = processYield( false, bHandleAllCurrentEvents ); + } +- return SalXLib::Yield( bWait, bHandleAllCurrentEvents ); ++ SalYieldResult aResult = SalXLib::Yield(bWait, bHandleAllCurrentEvents); ++ return (aResult == SalYieldResult::EVENT || wasEvent) ? ++ SalYieldResult::EVENT : SalYieldResult::TIMEOUT; + } + // if we are the main thread (which is where the event processing is done), + // good, just do it + if( qApp->thread() == QThread::currentThread()) +- processYield( bWait, bHandleAllCurrentEvents ); ++ return processYield( bWait, bHandleAllCurrentEvents ); + else + { + // we were called from another thread; +@@ -305,10 +308,11 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) + // temporarily do it while checking for new events) + SalYieldMutexReleaser aReleaser; + Q_EMIT processYieldSignal( bWait, bHandleAllCurrentEvents ); ++ return SalYieldResult::TIMEOUT; + } + } + +-void KDEXLib::processYield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult KDEXLib::processYield( bool bWait, bool bHandleAllCurrentEvents ) + { + blockIdleTimeout = !bWait; + QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance( qApp->thread()); +@@ -324,6 +328,8 @@ void KDEXLib::processYield( bool bWait, bool bHandleAllCurrentEvents ) + if( bWait && !wasEvent ) + dispatcher->processEvents( QEventLoop::WaitForMoreEvents ); + blockIdleTimeout = false; ++ return wasEvent ? SalYieldResult::EVENT ++ : SalYieldResult::TIMEOUT; + } + + void KDEXLib::StartTimer( sal_uLong nMS ) +diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx +index 0a1aec3..7e432e5 100644 +--- a/vcl/unx/kde4/KDEXLib.hxx ++++ b/vcl/unx/kde4/KDEXLib.hxx +@@ -65,7 +65,7 @@ class KDEXLib : public QObject, public SalXLib + void userEventActivated(); + void startTimeoutTimer(); + void startUserEventTimer(); +- void processYield( bool bWait, bool bHandleAllCurrentEvents ); ++ SalYieldResult processYield( bool bWait, bool bHandleAllCurrentEvents ); + Q_SIGNALS: + void startTimeoutTimerSignal(); + void startUserEventTimerSignal(); +@@ -80,7 +80,7 @@ class KDEXLib : public QObject, public SalXLib + virtual ~KDEXLib(); + + virtual void Init() SAL_OVERRIDE; +- virtual void Yield( bool bWait, bool bHandleAllCurrentEvents ) SAL_OVERRIDE; ++ virtual SalYieldResult Yield( bool bWait, bool bHandleAllCurrentEvents ) SAL_OVERRIDE; + virtual void Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, YieldFunc handle ) SAL_OVERRIDE; + virtual void Remove( int fd ) SAL_OVERRIDE; + virtual void StartTimer( sal_uLong nMS ) SAL_OVERRIDE; +diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx +index 1c21246..d61060f 100644 +--- a/vcl/win/source/app/salinst.cxx ++++ b/vcl/win/source/app/salinst.cxx +@@ -602,7 +602,8 @@ static void ImplSalDispatchMessage( MSG* pMsg ) + ImplSalPostDispatchMsg( pMsg, lResult ); + } + +-void ImplSalYield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult ++ImplSalYield( bool bWait, bool bHandleAllCurrentEvents ) + { + MSG aMsg; + bool bWasMsg = false, bOneEvent = false; +@@ -629,15 +630,22 @@ void ImplSalYield( bool bWait, bool bHandleAllCurrentEvents ) + ImplSalDispatchMessage( &aMsg ); + } + } ++ return bWasMsg ? SalYieldResult::EVENT : ++ SalYieldResult::TIMEOUT; + } + +-void WinSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) ++SalYieldResult WinSalInstance::DoYield(bool bWait, bool bHandleAllCurrentEvents, sal_uLong const nReleased) + { ++ SalYieldResult eDidWork = SalYieldResult::TIMEOUT; ++ // NOTE: if nReleased != 0 this will be called without SolarMutex ++ // so don't do anything dangerous before releasing it here + SalYieldMutex* pYieldMutex = mpSalYieldMutex; + SalData* pSalData = GetSalData(); + DWORD nCurThreadId = GetCurrentThreadId(); +- sal_uLong nCount = pYieldMutex->GetAcquireCount( nCurThreadId ); +- sal_uLong n = nCount; ++ sal_uLong const nCount = (nReleased != 0) ++ ? nReleased ++ : pYieldMutex->GetAcquireCount(nCurThreadId); ++ sal_uLong n = (nReleased != 0) ? 0 : nCount; + while ( n ) + { + pYieldMutex->release(); +@@ -669,7 +677,7 @@ void WinSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) + } + else + { +- ImplSalYield( bWait, bHandleAllCurrentEvents ); ++ eDidWork = ImplSalYield( bWait, bHandleAllCurrentEvents ); + + n = nCount; + while ( n ) +@@ -678,6 +686,7 @@ void WinSalInstance::Yield( bool bWait, bool bHandleAllCurrentEvents ) + n--; + } + } ++ return eDidWork; + } + + LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef ) +-- +2.5.0 + diff --git a/SOURCES/0001-but-only-for-dialog.patch b/SOURCES/0001-but-only-for-dialog.patch new file mode 100644 index 0000000..2a6460e --- /dev/null +++ b/SOURCES/0001-but-only-for-dialog.patch @@ -0,0 +1,26 @@ +From bba3f7bf8f831bf7f51de6441b3f15ed667e56fd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 16 Dec 2015 11:02:27 +0000 +Subject: [PATCH] but only for dialog + +Change-Id: I7e4f5c075ca4844f81a59071bed475ea1da4bf91 +--- + vcl/source/window/syswin.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx +index 3f2cde1..057b51b 100644 +--- a/vcl/source/window/syswin.cxx ++++ b/vcl/source/window/syswin.cxx +@@ -1135,7 +1135,7 @@ void SystemWindow::DoInitialLayout() + mbIsCalculatingInitialLayoutSize = false; + mbInitialLayoutDone = true; + } +- else if (!(GetStyle() & WB_SIZEABLE)) ++ else if (IsDialog() && !(GetStyle() & WB_SIZEABLE)) + { + SetMinOutputSizePixel(GetSizePixel()); + } +-- +2.5.0 + diff --git a/SOURCES/0001-default-to-as-character-caption-contents.patch b/SOURCES/0001-default-to-as-character-caption-contents.patch new file mode 100644 index 0000000..3df8ebe --- /dev/null +++ b/SOURCES/0001-default-to-as-character-caption-contents.patch @@ -0,0 +1,817 @@ +From 91739f2ca569b30383fe2f1cef8816fa8bf0554a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 10 Sep 2015 11:07:55 +0100 +Subject: [PATCH] default to as-character caption contents + +this FindFlyFrm variant returns the Selected FlyFrm + +the other one actively searches for the FlyFrm that +matches the XEmbeddedObject argument + +Change-Id: I2f9271c01337b4a32d7b644f82d16d85c2dc5b51 +(cherry picked from commit d9729bc06d676a36120f3da252d1a4fa39d103d8) + +GetCurrFlyFrm just forwards to GetSelectedFlyFrm + +Change-Id: Ia0b83a3aad71a72ae2135c5d7f6ddb6d9644b10b +(cherry picked from commit 8df51f799bb830db52c7be2d04b575b0443b76ec) + +bundle duplicate pattern into a GetCurrFlyFrm method + +Change-Id: Ib12b825ef9cc6e2b57e9320d435e3863d319cf0f +(cherry picked from commit 7473aacc73f8572e20f6f2a3a1d10001c5cc477d) + +GetSelectedFlyFrm+GetCurrFlyFrm -> GetSelectedOrCurrFlyFrm + +Change-Id: I4348c4cf54dcd5504c52cf8ab550572257eef50b +(cherry picked from commit a5aab0cce45309afae81b3ec0be8ace1ca0ca17d) + +GetCurFrameFormat->GetSelectedFrameFormat + +Change-Id: I2f1eb4567b6e073991d95dbcecdc79b24010f2c1 +(cherry picked from commit 4e6194fe8357efc5afa8d094e209ea94335b5923) + +split out useful code as standalone makeItemSetFromFormatAnchor + +Change-Id: I385549b4841dfc715aa984bcc257d78c9f1c3ed4 +(cherry picked from commit d961c9273104f552a8207e63c33e33f1e265565d) + +Related: tdf#93676 default to as-char inside captions + +This will (hopefull) improve round-tripping to doc[x] for new documents because +word can only have as-char elements inside frames so we get a like-for-like +conversion if the defaults are used. + +Change-Id: I3913b9b624dd5ba57ed07140bced8e3dca289cf5 +(cherry picked from commit 93ab0ff24cb71c36c9e7958046e96d7472b5af90) +--- + sw/inc/fesh.hxx | 14 +++- + sw/source/core/access/accframebase.cxx | 2 +- + sw/source/core/access/accmap.cxx | 2 +- + sw/source/core/access/accselectionhelper.cxx | 10 +-- + sw/source/core/frmedt/fecopy.cxx | 8 +- + sw/source/core/frmedt/fefly1.cxx | 118 ++++++++++++--------------- + sw/source/core/frmedt/feflyole.cxx | 2 +- + sw/source/core/frmedt/feshview.cxx | 6 +- + sw/source/core/frmedt/fews.cxx | 60 +++++++++++--- + sw/source/core/inc/UndoInsert.hxx | 1 + + sw/source/core/undo/unins.cxx | 16 +++- + sw/source/uibase/app/docst.cxx | 8 +- + sw/source/uibase/ribbar/drawbase.cxx | 2 +- + sw/source/uibase/shells/basesh.cxx | 18 ++-- + sw/source/uibase/shells/frmsh.cxx | 8 +- + sw/source/uibase/shells/grfsh.cxx | 2 +- + sw/source/uibase/wrtsh/wrtsh1.cxx | 2 +- + 17 files changed, 159 insertions(+), 120 deletions(-) + +diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx +index b3bbfcd..efc9b3d 100644 +--- a/sw/inc/fesh.hxx ++++ b/sw/inc/fesh.hxx +@@ -187,7 +187,6 @@ private: + std::unique_ptr m_pChainFrom; + bool m_bCheckForOLEInCaption; + +- SAL_DLLPRIVATE SwFlyFrm *FindFlyFrm() const; + SAL_DLLPRIVATE SwFlyFrm *FindFlyFrm( const ::com::sun::star::uno::Reference < ::com::sun::star::embed::XEmbeddedObject >& ) const; + + /// Terminate actions for all shells and call ChangeLink. +@@ -362,6 +361,7 @@ public: + bool IsFrmSelected() const; + bool GetFlyFrmAttr( SfxItemSet &rSet ) const; + bool SetFlyFrmAttr( SfxItemSet &rSet ); ++ SfxItemSet makeItemSetFromFormatAnchor(SfxItemPool& rPool, const SwFormatAnchor &rAnchor) const; + bool ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet = 0 ); + const SwFrameFormat *NewFlyFrm( const SfxItemSet &rSet, bool bAnchValid = false, + SwFrameFormat *pParent = 0 ); +@@ -373,9 +373,17 @@ public: + - add output parameter */ + bool IsFrmVertical(const bool bEnvironment, bool& bRightToLeft, bool& bVertL2R) const; + +- SwFrameFormat* GetCurFrameFormat() const; ///< If frame then frame style, else 0. ++ SwFrameFormat* GetSelectedFrameFormat() const; ///< If frame then frame style, else 0. + void SetFrameFormat( SwFrameFormat *pFormat, bool bKeepOrient = false, Point* pDocPos = 0 ); ///< If frame then set frame style. +- const SwFlyFrm *GetCurrFlyFrm() const { return FindFlyFrm(); } ++ ++ // Get selected fly ++ SwFlyFrm* GetSelectedFlyFrm() const; ++ ++ // Get current fly in which the cursor is positioned ++ SwFlyFrm* GetCurrFlyFrm(const bool bCalcFrm = true) const; ++ ++ // Get selected fly, but if none Get current fly in which the cursor is positioned ++ SwFlyFrm* GetSelectedOrCurrFlyFrm(const bool bCalcFrm = true) const; + + /// Find/delete fly containing the cursor. + SwFrameFormat* WizzardGetFly(); +diff --git a/sw/source/core/access/accframebase.cxx b/sw/source/core/access/accframebase.cxx +index bfffd2d..bfe07b4 100644 +--- a/sw/source/core/access/accframebase.cxx ++++ b/sw/source/core/access/accframebase.cxx +@@ -53,7 +53,7 @@ bool SwAccessibleFrameBase::IsSelected() + if( pVSh->ISA( SwFEShell ) ) + { + const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh ); +- const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm(); ++ const SwFrm *pFlyFrm = pFESh->GetSelectedFlyFrm(); + if( pFlyFrm == GetFrm() ) + bRet = true; + } +diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx +index 7e47ad3..18d9ce5 100644 +--- a/sw/source/core/access/accmap.cxx ++++ b/sw/source/core/access/accmap.cxx +@@ -2598,7 +2598,7 @@ void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm ) + else if( pVSh->ISA( SwFEShell ) ) + { + const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh ); +- const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm(); ++ const SwFrm *pFlyFrm = pFESh->GetSelectedFlyFrm(); + if( pFlyFrm ) + { + OSL_ENSURE( !pFrm || pFrm->FindFlyFrm() == pFlyFrm, +diff --git a/sw/source/core/access/accselectionhelper.cxx b/sw/source/core/access/accselectionhelper.cxx +index cec0612..5269503 100644 +--- a/sw/source/core/access/accselectionhelper.cxx ++++ b/sw/source/core/access/accselectionhelper.cxx +@@ -156,12 +156,12 @@ bool SwAccessibleSelectionHelper::isAccessibleChildSelected( + + // ... and compare to the currently selected frame + bool bRet = false; +- SwFEShell* pFEShell = GetFEShell(); ++ const SwFEShell* pFEShell = GetFEShell(); + if( pFEShell ) + { + if ( aChild.GetSwFrm() != 0 ) + { +- bRet = (pFEShell->GetCurrFlyFrm() == aChild.GetSwFrm()); ++ bRet = (pFEShell->GetSelectedFlyFrm() == aChild.GetSwFrm()); + } + else if ( aChild.GetDrawObject() ) + { +@@ -218,10 +218,10 @@ sal_Int32 SwAccessibleSelectionHelper::getSelectedAccessibleChildCount( ) + sal_Int32 nCount = 0; + // Only one frame can be selected at a time, and we only frames + // for selectable children. +- SwFEShell* pFEShell = GetFEShell(); ++ const SwFEShell* pFEShell = GetFEShell(); + if( pFEShell != 0 ) + { +- const SwFlyFrm* pFlyFrm = pFEShell->GetCurrFlyFrm(); ++ const SwFlyFrm* pFlyFrm = pFEShell->GetSelectedFlyFrm(); + if( pFlyFrm ) + { + nCount = 1; +@@ -290,7 +290,7 @@ Reference SwAccessibleSelectionHelper::getSelectedAccessibleChild( + throwIndexOutOfBoundsException(); + + SwAccessibleChild aChild; +- const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm(); ++ const SwFlyFrm *pFlyFrm = pFEShell->GetSelectedFlyFrm(); + if( pFlyFrm ) + { + if( 0 == nSelectedChildIndex ) +diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx +index 987625d..ab55d84 100644 +--- a/sw/source/core/frmedt/fecopy.cxx ++++ b/sw/source/core/frmedt/fecopy.cxx +@@ -126,7 +126,7 @@ bool SwFEShell::Copy( SwDoc* pClpDoc, const OUString* pNewClpText ) + if( IsFrmSelected() ) + { + // get the FlyFormat +- SwFlyFrm* pFly = FindFlyFrm(); ++ SwFlyFrm* pFly = GetSelectedFlyFrm(); + SwFrameFormat* pFlyFormat = pFly->GetFormat(); + SwFormatAnchor aAnchor( pFlyFormat->GetAnchor() ); + +@@ -467,7 +467,7 @@ bool SwFEShell::Copy( SwFEShell* pDestShell, const Point& rSttPt, + + if( IsFrmSelected() ) + { +- SwFlyFrm* pFly = FindFlyFrm(); ++ SwFlyFrm* pFly = GetSelectedFlyFrm(); + SwFrameFormat* pFlyFormat = pFly->GetFormat(); + SwFormatAnchor aAnchor( pFlyFormat->GetAnchor() ); + bRet = true; +@@ -1264,10 +1264,10 @@ bool SwFEShell::GetDrawObjGraphic( SotClipboardFormatId nFormat, Graphic& rGrf ) + } + else + { +- // fix(23806): not the origial size, but the current one. ++ // Not the original size, but the current one. + // Otherwise it could happen that for vector graphics + // many MB's of memory are allocated. +- const Size aSz( FindFlyFrm()->Prt().SSize() ); ++ const Size aSz( GetSelectedFlyFrm()->Prt().SSize() ); + ScopedVclPtrInstance< VirtualDevice > pVirtDev(*GetWin()); + + MapMode aTmp( MAP_TWIP ); +diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx +index 2937f04..e35b98e 100644 +--- a/sw/source/core/frmedt/fefly1.cxx ++++ b/sw/source/core/frmedt/fefly1.cxx +@@ -236,7 +236,7 @@ void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, bool bNew ) + OSL_ENSURE( rFrm.IsFlyFrm(), "SelectFlyFrm will einen Fly" ); + + // nothing to be done if the Fly already was selected +- if ( FindFlyFrm() == &rFrm ) ++ if (GetSelectedFlyFrm() == &rFrm) + return; + + // assure the anchor is drawn +@@ -254,8 +254,8 @@ void SwFEShell::SelectFlyFrm( SwFlyFrm& rFrm, bool bNew ) + } + } + +-// returns a Fly if one is selected +-SwFlyFrm *SwFEShell::FindFlyFrm() const ++// Get selected fly ++SwFlyFrm* SwFEShell::GetSelectedFlyFrm() const + { + if ( Imp()->HasDrawView() ) + { +@@ -270,6 +270,22 @@ SwFlyFrm *SwFEShell::FindFlyFrm() const + return 0; + } + ++// Get current fly in which the cursor is positioned ++SwFlyFrm* SwFEShell::GetCurrFlyFrm(const bool bCalcFrm) const ++{ ++ SwContentFrm *pContent = GetCurrFrm(bCalcFrm); ++ return pContent ? pContent->FindFlyFrm() : 0; ++} ++ ++// Get selected fly, but if none Get current fly in which the cursor is positioned ++SwFlyFrm* SwFEShell::GetSelectedOrCurrFlyFrm(const bool bCalcFrm) const ++{ ++ SwFlyFrm *pFly = GetSelectedFlyFrm(); ++ if (pFly) ++ return pFly; ++ return GetCurrFlyFrm(bCalcFrm); ++} ++ + // Returns non-null pointer, if the current Fly could be anchored to another one (so it is inside) + const SwFrameFormat* SwFEShell::IsFlyInFly() + { +@@ -281,11 +297,8 @@ const SwFrameFormat* SwFEShell::IsFlyInFly() + const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); + if ( !rMrkList.GetMarkCount() ) + { +- SwContentFrm *pContent = GetCurrFrm( false ); +- if( !pContent ) +- return NULL; +- SwFlyFrm *pFly = pContent->FindFlyFrm(); +- if ( !pFly ) ++ SwFlyFrm *pFly = GetCurrFlyFrm(false); ++ if (!pFly) + return NULL; + return pFly->GetFormat(); + } +@@ -332,11 +345,8 @@ void SwFEShell::SetFlyPos( const Point& rAbsPos ) + SET_CURR_SHELL( this ); + + // Determine reference point in document coordinates +- SwContentFrm *pContent = GetCurrFrm( false ); +- if( !pContent ) +- return; +- SwFlyFrm *pFly = pContent->FindFlyFrm(); +- if ( !pFly ) ++ SwFlyFrm *pFly = GetCurrFlyFrm(false); ++ if (!pFly) + return; + + //SwSaveHdl aSaveX( Imp() ); +@@ -968,21 +978,11 @@ void SwFEShell::SetPageObjsNewPage( std::vector& rFillArr, int n + // wrong place or which are ambiguous (multiple selections) will be removed. + bool SwFEShell::GetFlyFrmAttr( SfxItemSet &rSet ) const + { +- SwFlyFrm *pFly = FindFlyFrm(); +- if ( !pFly ) ++ SwFlyFrm *pFly = GetSelectedOrCurrFlyFrm(); ++ if (!pFly) + { +- SwFrm* pCurrFrm( GetCurrFrm() ); +- if ( !pCurrFrm ) +- { +- OSL_FAIL( " - missing current frame. This is a serious defect, please inform OD." ); +- return false; +- } +- pFly = GetCurrFrm()->FindFlyFrm(); +- if ( !pFly ) +- { +- OSL_ENSURE( false, "GetFlyFrmAttr, no Fly selected." ); +- return false; +- } ++ OSL_ENSURE( false, "GetFlyFrmAttr, no Fly selected." ); ++ return false; + } + + SET_CURR_SHELL( (SwViewShell*)this ); +@@ -1026,13 +1026,8 @@ bool SwFEShell::SetFlyFrmAttr( SfxItemSet& rSet ) + + if( rSet.Count() ) + { +- SwFlyFrm *pFly = FindFlyFrm(); +- if( !pFly ) +- { +- OSL_ENSURE( GetCurrFrm(), "Crsr in parking zone" ); +- pFly = GetCurrFrm()->FindFlyFrm(); +- OSL_ENSURE( pFly, "SetFlyFrmAttr, no Fly selected." ); +- } ++ SwFlyFrm *pFly = GetSelectedOrCurrFlyFrm(); ++ OSL_ENSURE( pFly, "SetFlyFrmAttr, no Fly selected." ); + if( pFly ) + { + StartAllAction(); +@@ -1058,6 +1053,16 @@ bool SwFEShell::SetFlyFrmAttr( SfxItemSet& rSet ) + return bRet; + } + ++SfxItemSet SwFEShell::makeItemSetFromFormatAnchor(SfxItemPool& rPool, const SwFormatAnchor &rAnchor) const ++{ ++ // The set also includes VERT/HORI_ORIENT, because the align ++ // shall be changed in FEShell::SetFlyFrmAttr/SetFlyFrmAnchor, ++ // possibly as a result of the anchor change. ++ SfxItemSet aSet(rPool, RES_VERT_ORIENT, RES_ANCHOR); ++ aSet.Put(rAnchor); ++ return aSet; ++} ++ + bool SwFEShell::SetDrawingAttr( SfxItemSet& rSet ) + { + bool bRet = false; +@@ -1106,14 +1111,8 @@ bool SwFEShell::ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet ) + { + SET_CURR_SHELL( this ); + +- SwFlyFrm *pFly = FindFlyFrm(); +- if( !pFly ) +- { +- OSL_ENSURE( GetCurrFrm(), "Crsr in parking zone" ); +- pFly = GetCurrFrm()->FindFlyFrm(); +- OSL_ENSURE( pFly, "SetFlyFrmAttr, no Fly selected." ); +- } +- ++ SwFlyFrm *pFly = GetSelectedOrCurrFlyFrm(); ++ OSL_ENSURE( pFly, "SetFlyFrmAttr, no Fly selected." ); + if( pFly ) + { + StartAllAction(); +@@ -1143,10 +1142,10 @@ bool SwFEShell::ResetFlyFrmAttr( sal_uInt16 nWhich, const SfxItemSet* pSet ) + } + + // Returns frame-format if frame, otherwise 0 +-SwFrameFormat* SwFEShell::GetCurFrameFormat() const ++SwFrameFormat* SwFEShell::GetSelectedFrameFormat() const + { + SwFrameFormat* pRet = 0; +- SwLayoutFrm *pFly = FindFlyFrm(); ++ SwLayoutFrm *pFly = GetSelectedFlyFrm(); + if( pFly && ( pRet = static_cast(pFly->GetFormat()->DerivedFrom()) ) == + GetDoc()->GetDfltFrameFormat() ) + pRet = 0; +@@ -1164,7 +1163,7 @@ void SwFEShell::SetFrameFormat( SwFrameFormat *pNewFormat, bool bKeepOrient, Poi + pFly = static_cast(pFormat)->GetFrm(); + } + else +- pFly = FindFlyFrm(); ++ pFly = GetSelectedFlyFrm(); + OSL_ENSURE( pFly, "SetFrameFormat: no frame" ); + if( pFly ) + { +@@ -1200,35 +1199,24 @@ void SwFEShell::SetFrameFormat( SwFrameFormat *pNewFormat, bool bKeepOrient, Poi + + const SwFrameFormat* SwFEShell::GetFlyFrameFormat() const + { +- const SwFlyFrm* pFly = FindFlyFrm(); +- if ( !pFly ) +- { +- SwFrm* pCurrFrm = GetCurrFrm(); +- pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0; +- } +- if( pFly ) ++ const SwFlyFrm* pFly = GetSelectedOrCurrFlyFrm(); ++ if (pFly) + return pFly->GetFormat(); + return 0; + } + + SwFrameFormat* SwFEShell::GetFlyFrameFormat() + { +- SwFlyFrm* pFly = FindFlyFrm(); +- if ( !pFly ) +- { +- SwFrm* pCurrFrm = GetCurrFrm(); +- pFly = pCurrFrm ? pCurrFrm->FindFlyFrm() : 0; +- } +- if( pFly ) ++ SwFlyFrm* pFly = GetSelectedOrCurrFlyFrm(); ++ if (pFly) + return pFly->GetFormat(); + return 0; + } + + SwRect SwFEShell::GetFlyRect() const + { +- SwContentFrm *pContent = GetCurrFrm( false ); +- SwFlyFrm *pFly = pContent ? pContent->FindFlyFrm() : 0; +- if ( !pFly ) ++ SwFlyFrm *pFly = GetCurrFlyFrm(false); ++ if (!pFly) + { + SwRect aRect; + return aRect; +@@ -1416,7 +1404,7 @@ SwFrameFormat* SwFEShell::WizzardGetFly() + + void SwFEShell::SetFlyName( const OUString& rName ) + { +- SwLayoutFrm *pFly = FindFlyFrm(); ++ SwLayoutFrm *pFly = GetSelectedFlyFrm(); + if( pFly ) + GetDoc()->SetFlyName( *static_cast(pFly->GetFormat()), rName ); + else { +@@ -1426,7 +1414,7 @@ void SwFEShell::SetFlyName( const OUString& rName ) + + OUString SwFEShell::GetFlyName() const + { +- SwLayoutFrm *pFly = FindFlyFrm(); ++ SwLayoutFrm *pFly = GetSelectedFlyFrm(); + if( pFly ) + return pFly->GetFormat()->GetName(); + +@@ -1437,7 +1425,7 @@ OUString SwFEShell::GetFlyName() const + const uno::Reference < embed::XEmbeddedObject > SwFEShell::GetOleRef() const + { + uno::Reference < embed::XEmbeddedObject > xObj; +- SwFlyFrm * pFly = FindFlyFrm(); ++ SwFlyFrm * pFly = GetSelectedFlyFrm(); + if (pFly && pFly->Lower() && pFly->Lower()->IsNoTextFrm()) + { + SwOLENode *pNd = static_cast(pFly->Lower())->GetNode()->GetOLENode(); +diff --git a/sw/source/core/frmedt/feflyole.cxx b/sw/source/core/frmedt/feflyole.cxx +index cd9804a..4d17b2a 100644 +--- a/sw/source/core/frmedt/feflyole.cxx ++++ b/sw/source/core/frmedt/feflyole.cxx +@@ -43,7 +43,7 @@ using namespace com::sun::star; + + SwFlyFrm *SwFEShell::FindFlyFrm( const uno::Reference < embed::XEmbeddedObject >& xObj ) const + { +- SwFlyFrm *pFly = FindFlyFrm(); ++ SwFlyFrm *pFly = GetSelectedFlyFrm(); + if ( pFly && pFly->Lower() && pFly->Lower()->IsNoTextFrm() ) + { + SwOLENode *pNd = static_cast(pFly->Lower())->GetNode()->GetOLENode(); +diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx +index fe38a22..54d79fb 100644 +--- a/sw/source/core/frmedt/feshview.cxx ++++ b/sw/source/core/frmedt/feshview.cxx +@@ -1772,7 +1772,7 @@ bool SwFEShell::ImpEndCreate() + SwFlyFrm* pFlyFrm; + if( NewFlyFrm( aSet, true ) && + ::GetHtmlMode( GetDoc()->GetDocShell() ) && +- 0 != ( pFlyFrm = FindFlyFrm() )) ++ 0 != ( pFlyFrm = GetSelectedFlyFrm() )) + { + SfxItemSet aHtmlSet( GetDoc()->GetAttrPool(), RES_VERT_ORIENT, RES_HORI_ORIENT ); + // horizontal orientation: +@@ -2083,7 +2083,7 @@ Point SwFEShell::GetAnchorObjDiff() const + + if ( IsFrmSelected() ) + { +- SwFlyFrm *pFly = FindFlyFrm(); ++ SwFlyFrm *pFly = GetSelectedFlyFrm(); + aRet -= pFly->GetAnchorFrm()->Frm().Pos(); + } + else +@@ -2631,7 +2631,7 @@ void SwFEShell::SetChainMarker() + bDelTo = true; + if ( IsFrmSelected() ) + { +- SwFlyFrm *pFly = FindFlyFrm(); ++ SwFlyFrm *pFly = GetSelectedFlyFrm(); + + if ( pFly->GetPrevLink() ) + { +diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx +index db791c8..a850f62 100644 +--- a/sw/source/core/frmedt/fews.cxx ++++ b/sw/source/core/frmedt/fews.cxx +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + using namespace com::sun::star; + +@@ -395,14 +396,18 @@ void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, con + if( LTYPE_DRAW==eType || pCnt ) + { + StartAllAction(); ++ SwRewriter aRewriter(SwUndoInsertLabel::CreateRewriter(rText)); ++ StartUndo(UNDO_INSERTLABEL, &aRewriter); + + sal_uLong nIdx = 0; ++ bool bInnerCntIsFly = false; + SwFlyFrameFormat* pFlyFormat = 0; + switch( eType ) + { + case LTYPE_OBJECT: + case LTYPE_FLY: +- if( pCnt->IsInFly() ) ++ bInnerCntIsFly = pCnt->IsInFly(); ++ if (bInnerCntIsFly) + { + // pass down index to the startnode for flys + nIdx = pCnt->FindFlyFrm()-> +@@ -423,7 +428,6 @@ void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, con + { + SwDrawView *pDView = Imp()->GetDrawView(); + const SdrMarkList& rMrkList = pDView->GetMarkedObjectList(); +- StartUndo(); + + // copy marked drawing objects to + // local list to perform the corresponding action for each object +@@ -452,7 +456,6 @@ void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, con + aDrawObjs.pop_back(); + } + +- EndUndo(); + } + break; + default: +@@ -460,14 +463,49 @@ void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, con + } + + if( nIdx ) +- pFlyFormat = GetDoc()->InsertLabel( eType, rText, rSeparator, rNumberSeparator, bBefore, nId, +- nIdx, rCharacterStyle, bCpyBrd ); ++ { ++ pFlyFormat = GetDoc()->InsertLabel(eType, rText, rSeparator, ++ rNumberSeparator, bBefore, nId, ++ nIdx, rCharacterStyle, bCpyBrd); ++ ++ //if we succeeded in putting a caption on the content, and the ++ //content was a frame/graphic, then set the contained element ++ //to as-char anchoring because that's all msword is able to ++ //do when inside a frame, and in writer for freshly captioned ++ //elements it's largely irrelevent what the anchor of the contained ++ //type is but making it as-char by default results in very ++ //good roundtripping ++ if (pFlyFormat && bInnerCntIsFly) ++ { ++ SwNodeIndex aAnchIdx(*pFlyFormat->GetContent().GetContentIdx(), 1); ++ SwTextNode *pTxtNode = aAnchIdx.GetNode().GetTextNode(); ++ ++ SwFormatAnchor aAnc(FLY_AS_CHAR); ++ sal_Int32 nInsertPos = bBefore ? pTxtNode->Len() : 0; ++ SwPosition aPos(*pTxtNode, nInsertPos); ++ ++ aAnc.SetAnchor(&aPos); ++ ++ SfxItemSet aSet(makeItemSetFromFormatAnchor(GetDoc()->GetAttrPool(), aAnc)); + +- SwFlyFrm* pFrm; +- const Point aPt( GetCrsrDocPos() ); +- if( pFlyFormat && 0 != ( pFrm = pFlyFormat->GetFrm( &aPt ))) +- SelectFlyFrm( *pFrm, true ); ++ SwFlyFrm *pFly = GetSelectedOrCurrFlyFrm(); ++ SwFlyFrameFormat* pInnerFlyFormat = pFly->GetFormat(); ++ GetDoc()->SetFlyFrmAttr(*pInnerFlyFormat, aSet); + ++ //put a hard-break after the graphic to keep it separated ++ //from the caption text if the outer frame is resized ++ SwIndex aIdx(pTxtNode, bBefore ? nInsertPos : 1); ++ pTxtNode->InsertText(OUString("\n"), aIdx); ++ } ++ } ++ ++ if (pFlyFormat) ++ { ++ const Point aPt(GetCrsrDocPos()); ++ if (SwFlyFrm* pFrm = pFlyFormat->GetFrm(&aPt)) ++ SelectFlyFrm(*pFrm, true); ++ } ++ EndUndo(); + EndAllActionAndCall(); + } + } +@@ -649,7 +687,7 @@ void SwFEShell::CalcBoundRect( SwRect& _orRect, + } + else + { +- pFly = FindFlyFrm(); ++ pFly = GetSelectedFlyFrm(); + pFrm = pFly ? pFly->GetAnchorFrm() : GetCurrFrm(); + } + +@@ -1167,7 +1205,7 @@ void SwFEShell::CalcBoundRect( SwRect& _orRect, + Size SwFEShell::GetGraphicDefaultSize() const + { + Size aRet; +- SwFlyFrm *pFly = FindFlyFrm(); ++ SwFlyFrm *pFly = GetSelectedFlyFrm(); + if ( pFly ) + { + // #i32951# - due to issue #i28701# no format of a +diff --git a/sw/source/core/inc/UndoInsert.hxx b/sw/source/core/inc/UndoInsert.hxx +index 8ef9263..f99783a 100644 +--- a/sw/source/core/inc/UndoInsert.hxx ++++ b/sw/source/core/inc/UndoInsert.hxx +@@ -203,6 +203,7 @@ public: + @return the rewriter of this undo object + */ + virtual SwRewriter GetRewriter() const SAL_OVERRIDE; ++ static SwRewriter CreateRewriter(const OUString &rStr); + + void SetNodePos( sal_uLong nNd ) + { if( LTYPE_OBJECT != eType ) NODE.nNode = nNd; } +diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx +index 58bdcf4..64541bd 100644 +--- a/sw/source/core/undo/unins.cxx ++++ b/sw/source/core/undo/unins.cxx +@@ -1014,14 +1014,22 @@ void SwUndoInsertLabel::RepeatImpl(::sw::RepeatContext & rContext) + // #111827# + SwRewriter SwUndoInsertLabel::GetRewriter() const + { ++ return CreateRewriter(sText); ++} ++ ++SwRewriter SwUndoInsertLabel::CreateRewriter(const OUString &rStr) ++{ + SwRewriter aRewriter; + + OUString aTmpStr; + +- aTmpStr += SW_RES(STR_START_QUOTE); +- aTmpStr += ShortenString(sText, nUndoStringLength, +- OUString(SW_RES(STR_LDOTS))); +- aTmpStr += SW_RES(STR_END_QUOTE); ++ if (!rStr.isEmpty()) ++ { ++ aTmpStr += SW_RES(STR_START_QUOTE); ++ aTmpStr += ShortenString(rStr, nUndoStringLength, ++ OUString(SW_RES(STR_LDOTS))); ++ aTmpStr += SW_RES(STR_END_QUOTE); ++ } + + aRewriter.AddRule(UndoArg1, aTmpStr); + +diff --git a/sw/source/uibase/app/docst.cxx b/sw/source/uibase/app/docst.cxx +index 77e79af..381fe8b 100644 +--- a/sw/source/uibase/app/docst.cxx ++++ b/sw/source/uibase/app/docst.cxx +@@ -129,7 +129,7 @@ void SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh) + // so that this family is being showed + if(pShell->IsFrmSelected()) + { +- SwFrameFormat* pFormat = pShell->GetCurFrameFormat(); ++ SwFrameFormat* pFormat = pShell->GetSelectedFrameFormat(); + if( pFormat ) + aName = pFormat->GetName(); + } +@@ -195,7 +195,7 @@ void SwDocShell::StateStyleSheet(SfxItemSet& rSet, SwWrtShell* pSh) + rSet.DisableItem( nWhich ); + else + { +- SwFrameFormat* pFormat = pShell->GetCurFrameFormat(); ++ SwFrameFormat* pFormat = pShell->GetSelectedFrameFormat(); + if(pFormat && pShell->IsFrmSelected()) + { + aName = pFormat->GetName(); +@@ -429,7 +429,7 @@ void SwDocShell::ExecStyleSheet( SfxRequest& rReq ) + break; + case SFX_STYLE_FAMILY_FRAME: + { +- SwFrameFormat* pFrm = m_pWrtShell->GetCurFrameFormat(); ++ SwFrameFormat* pFrm = m_pWrtShell->GetSelectedFrameFormat(); + if( pFrm ) + aParam = pFrm->GetName(); + } +@@ -1177,7 +1177,7 @@ sal_uInt16 SwDocShell::MakeByExample( const OUString &rName, sal_uInt16 nFamily, + SfxItemSet aSet(GetPool(), aFrameFormatSetRange ); + pCurrWrtShell->GetFlyFrmAttr( aSet ); + +- SwFrameFormat* pFFormat = pCurrWrtShell->GetCurFrameFormat(); ++ SwFrameFormat* pFFormat = pCurrWrtShell->GetSelectedFrameFormat(); + pFrm->SetDerivedFrom( pFFormat ); + + pFrm->SetFormatAttr( aSet ); +diff --git a/sw/source/uibase/ribbar/drawbase.cxx b/sw/source/uibase/ribbar/drawbase.cxx +index 0cbea13..55b6d44 100644 +--- a/sw/source/uibase/ribbar/drawbase.cxx ++++ b/sw/source/uibase/ribbar/drawbase.cxx +@@ -287,7 +287,7 @@ bool SwDrawBase::MouseButtonUp(const MouseEvent& rMEvt) + aCol.Init(m_pWin->GetFrmColCount(), aCol.GetGutterWidth(), aCol.GetWishWidth()); + aSet.Put(aCol); + // Template AutoUpdate +- SwFrameFormat* pFormat = m_pSh->GetCurFrameFormat(); ++ SwFrameFormat* pFormat = m_pSh->GetSelectedFrameFormat(); + if(pFormat && pFormat->IsAutoUpdateFormat()) + m_pSh->AutoUpdateFrame(pFormat, aSet); + else +diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx +index 0a9c64f..360d7c3 100644 +--- a/sw/source/uibase/shells/basesh.cxx ++++ b/sw/source/uibase/shells/basesh.cxx +@@ -1008,16 +1008,12 @@ void SwBaseShell::Execute(SfxRequest &rReq) + ? FLY_AS_CHAR + : FLY_AT_CHAR; + rSh.StartUndo(); +- if( rSh.IsObjSelected() ) +- rSh.ChgAnchor( eSet ); +- else if( rSh.IsFrmSelected() ) +- { +- // The set also includes VERT/HORI_ORIENT, because the align +- // shall be changed in FEShell::SetFlyFrmAttr/SetFlyFrmAnchor, +- // possibly as a result of the anchor change. +- SfxItemSet aSet( GetPool(), RES_VERT_ORIENT, RES_ANCHOR ); +- SwFormatAnchor aAnc( eSet, rSh.GetPhyPageNum() ); +- aSet.Put( aAnc ); ++ if (rSh.IsObjSelected()) ++ rSh.ChgAnchor(eSet); ++ else if (rSh.IsFrmSelected()) ++ { ++ SwFormatAnchor aAnc(eSet, rSh.GetPhyPageNum()); ++ SfxItemSet aSet(rSh.makeItemSetFromFormatAnchor(GetPool(), aAnc)); + rSh.SetFlyFrmAttr(aSet); + } + // if new anchor is 'as char' and it is a Math object and the usual +@@ -2284,7 +2280,7 @@ void SwBaseShell::ExecBckCol(SfxRequest& rReq) + if((nsSelectionType::SEL_FRM & nSelType) || (nsSelectionType::SEL_GRF & nSelType)) + { + // Template autoupdate +- SwFrameFormat* pFormat = rSh.GetCurFrameFormat(); ++ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); + + if(pFormat && pFormat->IsAutoUpdateFormat()) + { +diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx +index 4868fdf..3a4e956 100644 +--- a/sw/source/uibase/shells/frmsh.cxx ++++ b/sw/source/uibase/shells/frmsh.cxx +@@ -176,7 +176,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) + aCol.Init(nCols, nGutterWidth, aCol.GetWishWidth()); + aSet.Put(aCol); + // Template AutoUpdate +- SwFrameFormat* pFormat = rSh.GetCurFrameFormat(); ++ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); + if(pFormat && pFormat->IsAutoUpdateFormat()) + { + rSh.AutoUpdateFrame(pFormat, aSet); +@@ -498,7 +498,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) + rSh.SetObjTitle(static_cast(pItem)->GetValue()); + } + // Template AutoUpdate +- SwFrameFormat* pFormat = rSh.GetCurFrameFormat(); ++ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); + if(pFormat && pFormat->IsAutoUpdateFormat()) + { + rSh.AutoUpdateFrame(pFormat, *pOutSet); +@@ -644,7 +644,7 @@ void SwFrameShell::Execute(SfxRequest &rReq) + } + if ( bUpdateMgr ) + { +- SwFrameFormat* pFormat = rSh.GetCurFrameFormat(); ++ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); + if ( bCopyToFormat && pFormat && pFormat->IsAutoUpdateFormat() ) + { + rSh.AutoUpdateFrame(pFormat, aMgr.GetAttrSet()); +@@ -1111,7 +1111,7 @@ void SwFrameShell::ExecFrameStyle(SfxRequest& rReq) + } + aFrameSet.Put( aBoxItem ); + // Template AutoUpdate +- SwFrameFormat* pFormat = rSh.GetCurFrameFormat(); ++ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); + if(pFormat && pFormat->IsAutoUpdateFormat()) + { + rSh.AutoUpdateFrame(pFormat, aFrameSet); +diff --git a/sw/source/uibase/shells/grfsh.cxx b/sw/source/uibase/shells/grfsh.cxx +index 39e18fd..60e95f3 100644 +--- a/sw/source/uibase/shells/grfsh.cxx ++++ b/sw/source/uibase/shells/grfsh.cxx +@@ -381,7 +381,7 @@ void SwGrfShell::Execute(SfxRequest &rReq) + } + + // Templates AutoUpdate +- SwFrameFormat* pFormat = rSh.GetCurFrameFormat(); ++ SwFrameFormat* pFormat = rSh.GetSelectedFrameFormat(); + if(pFormat && pFormat->IsAutoUpdateFormat()) + { + pFormat->SetFormatAttr(*pSet); +diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx +index 37f0553..ead7e47 100644 +--- a/sw/source/uibase/wrtsh/wrtsh1.cxx ++++ b/sw/source/uibase/wrtsh/wrtsh1.cxx +@@ -1709,7 +1709,7 @@ OUString SwWrtShell::GetSelDescr() const + break; + case nsSelectionType::SEL_FRM: + { +- const SwFrameFormat * pFrameFormat = GetCurFrameFormat(); ++ const SwFrameFormat * pFrameFormat = GetSelectedFrameFormat(); + + if (pFrameFormat) + aResult = pFrameFormat->GetDescription(); +-- +2.4.0 + diff --git a/SOURCES/0001-delete-hidden-pages-before-deleting-unused-masters.patch b/SOURCES/0001-delete-hidden-pages-before-deleting-unused-masters.patch new file mode 100644 index 0000000..b28b133 --- /dev/null +++ b/SOURCES/0001-delete-hidden-pages-before-deleting-unused-masters.patch @@ -0,0 +1,52 @@ +From 0f0cea28c75a6565c7803b54536d4a8720ead160 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 22 Mar 2016 09:03:56 +0100 +Subject: [PATCH] delete hidden pages before deleting unused masters + +Change-Id: I40b624c0e6e6cff2c88815f7d16e862f09d79d5c +--- + sdext/source/minimizer/impoptimizer.cxx | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/sdext/source/minimizer/impoptimizer.cxx b/sdext/source/minimizer/impoptimizer.cxx +index 03ba917..53600ed 100644 +--- a/sdext/source/minimizer/impoptimizer.cxx ++++ b/sdext/source/minimizer/impoptimizer.cxx +@@ -518,27 +518,27 @@ bool ImpOptimizer::Optimize() + if ( !maCustomShowName.isEmpty() ) + ImpExtractCustomShow( mxModel, maCustomShowName ); + +- if ( mbDeleteUnusedMasterPages ) ++ if ( mbDeleteHiddenSlides ) + { + SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) ); + SetStatusValue( TK_Status, Any( OUString("STR_DELETING_SLIDES") ) ); + DispatchStatus(); +- ImpDeleteUnusedMasterPages( mxModel ); ++ ImpDeleteHiddenSlides( mxModel ); + } + +- if ( mbDeleteHiddenSlides ) ++ if ( mbDeleteNotesPages ) + { +- SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) ); + SetStatusValue( TK_Status, Any( OUString("STR_DELETING_SLIDES") ) ); + DispatchStatus(); +- ImpDeleteHiddenSlides( mxModel ); ++ ImpDeleteNotesPages( mxModel ); + } + +- if ( mbDeleteNotesPages ) ++ if ( mbDeleteUnusedMasterPages ) + { ++ SetStatusValue( TK_Progress, Any( static_cast< sal_Int32 >( 40 ) ) ); + SetStatusValue( TK_Status, Any( OUString("STR_DELETING_SLIDES") ) ); + DispatchStatus(); +- ImpDeleteNotesPages( mxModel ); ++ ImpDeleteUnusedMasterPages( mxModel ); + } + + if ( mbOLEOptimization ) +-- +2.5.0 + diff --git a/SOURCES/0001-disable-PSD-import-test-which-deadlocks-on-ARM.patch b/SOURCES/0001-disable-PSD-import-test-which-deadlocks-on-ARM.patch new file mode 100644 index 0000000..173eeee --- /dev/null +++ b/SOURCES/0001-disable-PSD-import-test-which-deadlocks-on-ARM.patch @@ -0,0 +1,24 @@ +From adbd9c70d4326e2577c4b5eff486f1809777fa90 Mon Sep 17 00:00:00 2001 +From: rpmbuild +Date: Mon, 26 May 2014 10:01:33 +0200 +Subject: [PATCH] disable PSD import test which deadlocks on ARM + +--- + filter/Module_filter.mk | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/filter/Module_filter.mk b/filter/Module_filter.mk +index 3558f44..3f3301f 100644 +--- a/filter/Module_filter.mk ++++ b/filter/Module_filter.mk +@@ -87,7 +87,6 @@ $(eval $(call gb_Module_add_check_targets,filter,\ + CppunitTest_filter_pcx_test \ + CppunitTest_filter_pict_test \ + CppunitTest_filter_ppm_test \ +- CppunitTest_filter_psd_test \ + CppunitTest_filter_ras_test \ + CppunitTest_filter_tiff_test \ + CppunitTest_filter_tga_test \ +-- +1.9.0 + diff --git a/SOURCES/0001-disable-firebird-unit-test.patch b/SOURCES/0001-disable-firebird-unit-test.patch new file mode 100644 index 0000000..fcea6d2 --- /dev/null +++ b/SOURCES/0001-disable-firebird-unit-test.patch @@ -0,0 +1,24 @@ +From 47c076d6bbe8b4d131351642c8ba796271be74fe Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 3 Feb 2014 21:52:11 +0100 +Subject: [PATCH] disable firebird unit test + +--- + dbaccess/Module_dbaccess.mk | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/dbaccess/Module_dbaccess.mk b/dbaccess/Module_dbaccess.mk +index b9d7d56..824f3f5 100644 +--- a/dbaccess/Module_dbaccess.mk ++++ b/dbaccess/Module_dbaccess.mk +@@ -36,7 +36,6 @@ $(eval $(call gb_Module_add_l10n_targets,dbaccess,\ + + ifeq ($(ENABLE_FIREBIRD_SDBC),TRUE) + $(eval $(call gb_Module_add_check_targets,dbaccess,\ +- CppunitTest_dbaccess_firebird_test \ + )) + endif + +-- +1.8.4.2 + diff --git a/SOURCES/0001-disable-generation-of-ole-previews-in-ODF-format-unt.patch b/SOURCES/0001-disable-generation-of-ole-previews-in-ODF-format-unt.patch new file mode 100644 index 0000000..7df8b23 --- /dev/null +++ b/SOURCES/0001-disable-generation-of-ole-previews-in-ODF-format-unt.patch @@ -0,0 +1,575 @@ +From da6682c1cf339cb711a6ba2d28673978d42e446a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 13 Sep 2016 12:32:04 +0100 +Subject: [PATCH] disable generation of ole previews in ODF format until after + load +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +so the user update links dialog can control their generation + +SdrEmbedObjectLink becomes exposed to calc so it can +detect if the link dialog needs to be used to update +ole links. + +Reviewed-on: https://gerrit.libreoffice.org/28879 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 74844277cc2194c9e43f5bd7a6f78a9603da32f3) + +detangle gadzillion checks into something readable + +no logic change intended + +(cherry picked from commit fad9786b06d188ba6e354620f57176f3d94a6637) + ++ partial merge of + +commit c09b3e32372537be739182b02ae83a96386d1e1c +Author: Noel Grandin +Date: Tue Mar 8 13:13:59 2016 +0200 + + loplugin:constantparam in sw + +for bool bUI is always true in UpdateLinks + +Unmodified default SdrOle2Obj size is 101x101 + +svx/source/unodraw/unoshape.cxx + +sets a css::awt::Size maSize to 100, 100 + +svx/source/unodraw/unopage.cxx + +increases that by 1, 1 + +awt::Size aSize = xShape->getSize(); +aSize.Width += 1; +aSize.Height += 1; + +to call SdrObjFactory::MakeNewObject with 101, 101 +so default size is 101x101 (getWidth() vs GetWidth() confusion ?) + +Reviewed-on: https://gerrit.libreoffice.org/28895 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 7f0a219c9ad38ae33b51ff69d545f69659691c1e) + +b6af93afc1f80b7fc36239c96d5e0a71fcbcb789 +4d4375dff64d7b8e236d1a24322e749e04ee530f +Reviewed-on: https://gerrit.libreoffice.org/28930 +Tested-by: Jenkins +Reviewed-by: Michael Stahl +Reviewed-by: Eike Rathke +Tested-by: Eike Rathke + +(cherry picked from commit 2ff4c68b63c4842ec85a21287317096b6ca8e66e) + +Change-Id: Id1dd7ea17342140eab9307d546528747e3a98090 +--- + embeddedobj/source/commonembedding/visobj.cxx | 6 +- + include/svx/svdoole2.hxx | 16 ++++ + sc/inc/documentlinkmgr.hxx | 5 +- + sc/source/ui/docshell/docsh.cxx | 7 +- + sc/source/ui/docshell/docsh4.cxx | 12 ++- + sc/source/ui/docshell/documentlinkmgr.cxx | 26 ++++++- + sc/source/ui/view/tabvwsh4.cxx | 2 +- + sd/source/core/drawdoc.cxx | 6 ++ + sd/source/ui/docshell/docshel4.cxx | 5 +- + svx/source/svdraw/svdoole2.cxx | 20 ----- + svx/source/unodraw/unoshap4.cxx | 4 +- + sw/inc/IDocumentLinksAdministration.hxx | 2 +- + .../doc/DocumentLinksAdministrationManager.cxx | 85 ++++++++++++---------- + .../inc/DocumentLinksAdministrationManager.hxx | 2 +- + sw/source/filter/basflt/shellio.cxx | 2 +- + sw/source/uibase/app/docsh.cxx | 2 +- + sw/source/uibase/app/docshini.cxx | 3 + + 17 files changed, 131 insertions(+), 74 deletions(-) + +diff --git a/embeddedobj/source/commonembedding/visobj.cxx b/embeddedobj/source/commonembedding/visobj.cxx +index fea7c3a2cf0a..3ee85851af9f 100644 +--- a/embeddedobj/source/commonembedding/visobj.cxx ++++ b/embeddedobj/source/commonembedding/visobj.cxx +@@ -174,7 +174,11 @@ embed::VisualRepresentation SAL_CALL OCommonEmbeddedObject::getPreferredVisualRe + bool bBackToLoaded = false; + if ( m_nObjectState == embed::EmbedStates::LOADED ) + { +- changeState( embed::EmbedStates::RUNNING ); ++ awt::Size aOrigSize = getVisualAreaSize(nAspect); ++ changeState(embed::EmbedStates::RUNNING); ++ awt::Size aNewSize = getVisualAreaSize(nAspect); ++ if (aOrigSize.Width != aNewSize.Width || aOrigSize.Height != aNewSize.Height) ++ setVisualAreaSize(nAspect, aOrigSize); + + // the links should be switched back to loaded state for now to avoid locking problems + bBackToLoaded = m_bIsLink; +diff --git a/include/svx/svdoole2.hxx b/include/svx/svdoole2.hxx +index f14646b20428..7f47ebff607b 100644 +--- a/include/svx/svdoole2.hxx ++++ b/include/svx/svdoole2.hxx +@@ -22,6 +22,7 @@ + + #include + #include ++#include + + #include + +@@ -179,6 +180,21 @@ public: + virtual SdrObject* DoConvertToPolyObj(bool bBezier, bool bAddText) const SAL_OVERRIDE; + }; + ++class SVX_DLLPUBLIC SdrEmbedObjectLink : public sfx2::SvBaseLink ++{ ++ SdrOle2Obj* pObj; ++ ++public: ++ explicit SdrEmbedObjectLink(SdrOle2Obj* pObj); ++ virtual ~SdrEmbedObjectLink(); ++ ++ virtual void Closed() override; ++ virtual ::sfx2::SvBaseLink::UpdateResult DataChanged( ++ const OUString& rMimeType, const css::uno::Any & rValue ) override; ++ ++ bool Connect() { return GetRealObject() != nullptr; } ++}; ++ + #endif // INCLUDED_SVX_SVDOOLE2_HXX + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx +index 0af5cf896c63..cc42410ca3dc 100644 +--- a/sc/inc/documentlinkmgr.hxx ++++ b/sc/inc/documentlinkmgr.hxx +@@ -53,14 +53,17 @@ public: + bool idleCheckLinks(); + + bool hasDdeLinks() const; ++ bool hasDdeOrOleLinks() const; + +- bool updateDdeLinks( vcl::Window* pWin ); ++ bool updateDdeOrOleLinks(vcl::Window* pWin); + + bool updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem ); + + size_t getDdeLinkCount() const; + + void disconnectDdeLinks(); ++private: ++ bool hasDdeOrOleLinks(bool bDde, bool bOle) const; + }; + + } +diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx +index d0c083625465..25dab86e5ca0 100644 +--- a/sc/source/ui/docshell/docsh.cxx ++++ b/sc/source/ui/docshell/docsh.cxx +@@ -561,9 +561,12 @@ bool ScDocShell::Load( SfxMedium& rMedium ) + + GetUndoManager()->Clear(); + +- bool bRet = SfxObjectShell::Load( rMedium ); +- if( bRet ) ++ bool bRet = SfxObjectShell::Load(rMedium); ++ if (bRet) + { ++ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); ++ + if (GetMedium()) + { + SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, false); +diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx +index 969c678e4ce1..9fcf549c8920 100644 +--- a/sc/source/ui/docshell/docsh4.cxx ++++ b/sc/source/ui/docshell/docsh4.cxx +@@ -29,6 +29,7 @@ using namespace ::com::sun::star; + + #include "scitems.hxx" + #include ++#include + #include + #include + #include +@@ -42,6 +43,7 @@ using namespace ::com::sun::star; + #include + #include + #include ++#include + #include + #include + #include +@@ -407,6 +409,9 @@ void ScDocShell::Execute( SfxRequest& rReq ) + break; + case SID_UPDATETABLINKS: + { ++ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true); ++ + ScDocument& rDoc = GetDocument(); + + ScLkUpdMode nSet = rDoc.GetLinkMode(); +@@ -450,9 +455,9 @@ void ScDocShell::Execute( SfxRequest& rReq ) + ReloadTabLinks(); + aDocument.UpdateExternalRefLinks(GetActiveDialogParent()); + +- bool bAny = aDocument.GetDocLinkManager().updateDdeLinks(GetActiveDialogParent()); ++ bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent()); + +- if (bAny) ++ if (bAnyDde) + { + // Formeln berechnen und painten wie im TrackTimeHdl + aDocument.TrackFormulas(); +@@ -468,7 +473,10 @@ void ScDocShell::Execute( SfxRequest& rReq ) + rReq.Done(); + } + else ++ { ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + rReq.Ignore(); ++ } + } + break; + +diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx +index 42745eb3f344..8e5a5c3a02bb 100644 +--- a/sc/source/ui/docshell/documentlinkmgr.cxx ++++ b/sc/source/ui/docshell/documentlinkmgr.cxx +@@ -23,7 +23,7 @@ + #include + #include + +-#include ++#include + #include + + #include +@@ -115,6 +115,16 @@ bool DocumentLinkManager::idleCheckLinks() + + bool DocumentLinkManager::hasDdeLinks() const + { ++ return hasDdeOrOleLinks(true, false); ++} ++ ++bool DocumentLinkManager::hasDdeOrOleLinks() const ++{ ++ return hasDdeOrOleLinks(true, true); ++} ++ ++bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const ++{ + if (!mpImpl->mpLinkManager) + return false; + +@@ -122,14 +132,16 @@ bool DocumentLinkManager::hasDdeLinks() const + for (size_t i = 0, n = rLinks.size(); i < n; ++i) + { + sfx2::SvBaseLink* pBase = *rLinks[i]; +- if (dynamic_cast(pBase)) ++ if (bDde && dynamic_cast(pBase)) ++ return true; ++ if (bOle && dynamic_cast(pBase)) + return true; + } + + return false; + } + +-bool DocumentLinkManager::updateDdeLinks( vcl::Window* pWin ) ++bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) + { + if (!mpImpl->mpLinkManager) + return false; +@@ -143,6 +155,14 @@ bool DocumentLinkManager::updateDdeLinks( vcl::Window* pWin ) + for (size_t i = 0, n = rLinks.size(); i < n; ++i) + { + sfx2::SvBaseLink* pBase = *rLinks[i]; ++ ++ SdrEmbedObjectLink* pOleLink = dynamic_cast(pBase); ++ if (pOleLink) ++ { ++ pOleLink->Update(); ++ continue; ++ } ++ + ScDdeLink* pDdeLink = dynamic_cast(pBase); + if (!pDdeLink) + continue; +diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx +index 64a6e9f0f063..ff3a5a1d94f1 100644 +--- a/sc/source/ui/view/tabvwsh4.cxx ++++ b/sc/source/ui/view/tabvwsh4.cxx +@@ -1584,7 +1584,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) + if (!bLink) + { + const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); +- if (rMgr.hasDdeLinks() || rDoc.HasAreaLinks()) ++ if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks()) + bLink = true; + } + if (bLink) +diff --git a/sd/source/core/drawdoc.cxx b/sd/source/core/drawdoc.cxx +index f820fabaab81..6b5673f66592 100644 +--- a/sd/source/core/drawdoc.cxx ++++ b/sd/source/core/drawdoc.cxx +@@ -694,6 +694,12 @@ void SdDrawDocument::UpdateAllLinks() + { + pDocLockedInsertingLinks = this; // lock inserting links. only links in this document should by resolved + ++ if (mpDocSh) ++ { ++ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mpDocSh->getEmbeddedObjectContainer(); ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true); ++ } ++ + pLinkManager->UpdateAllLinks(); // query box: update all links? + + if( pDocLockedInsertingLinks == this ) +diff --git a/sd/source/ui/docshell/docshel4.cxx b/sd/source/ui/docshell/docshel4.cxx +index bed2fd7b4e97..b56f46e717f9 100644 +--- a/sd/source/ui/docshell/docshel4.cxx ++++ b/sd/source/ui/docshell/docshel4.cxx +@@ -285,8 +285,11 @@ bool DrawDocShell::Load( SfxMedium& rMedium ) + } + + bRet = SfxObjectShell::Load( rMedium ); +- if( bRet ) ++ if (bRet) + { ++ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); ++ + bRet = SdXMLFilter( rMedium, *this, true, SDXMLMODE_Normal, SotStorage::GetVersion( rMedium.GetStorage() ) ).Import( nError ); + } + +diff --git a/svx/source/svdraw/svdoole2.cxx b/svx/source/svdraw/svdoole2.cxx +index 403646b6f10e..8985a3bb8a60 100644 +--- a/svx/source/svdraw/svdoole2.cxx ++++ b/svx/source/svdraw/svdoole2.cxx +@@ -58,7 +58,6 @@ + #include + + #include +-#include + #include + #include + +@@ -588,25 +587,6 @@ void SdrLightEmbeddedClient_Impl::setWindow(const uno::Reference< awt::XWindow > + m_xWindow = _xWindow; + } + +- +- +-class SdrEmbedObjectLink : public sfx2::SvBaseLink +-{ +- SdrOle2Obj* pObj; +- +-public: +- SdrEmbedObjectLink(SdrOle2Obj* pObj); +- virtual ~SdrEmbedObjectLink(); +- +- virtual void Closed() SAL_OVERRIDE; +- virtual ::sfx2::SvBaseLink::UpdateResult DataChanged( +- const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue ) SAL_OVERRIDE; +- +- bool Connect() { return GetRealObject() != NULL; } +-}; +- +- +- + SdrEmbedObjectLink::SdrEmbedObjectLink(SdrOle2Obj* pObject): + ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB ), + pObj(pObject) +diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx +index 9b9d7500b162..002f69e35dec 100644 +--- a/svx/source/unodraw/unoshap4.cxx ++++ b/svx/source/unodraw/unoshap4.cxx +@@ -416,7 +416,7 @@ bool SvxOle2Shape::createObject( const SvGlobalName &aClassName ) + if( xObj.is() ) + { + Rectangle aRect = pOle2Obj->GetLogicRect(); +- if ( aRect.GetWidth() == 100 && aRect.GetHeight() == 100 ) ++ if ( aRect.GetWidth() == 101 && aRect.GetHeight() == 101 ) + { + // TODO/LATER: is it possible that this method is used to create an iconified object? + // default size +@@ -484,7 +484,7 @@ bool SvxOle2Shape::createLink( const OUString& aLinkURL ) + if( xObj.is() ) + { + Rectangle aRect = pOle2Obj->GetLogicRect(); +- if ( aRect.GetWidth() == 100 && aRect.GetHeight() == 100 ) ++ if ( aRect.GetWidth() == 101 && aRect.GetHeight() == 101 ) + { + // default size + try +diff --git a/sw/inc/IDocumentLinksAdministration.hxx b/sw/inc/IDocumentLinksAdministration.hxx +index 8d4f4c74d47f..e618b111e427 100644 +--- a/sw/inc/IDocumentLinksAdministration.hxx ++++ b/sw/inc/IDocumentLinksAdministration.hxx +@@ -46,7 +46,7 @@ using rtl::OUString; + /** #i42634# Moved common code of SwReader::Read() and + SwDocShell::UpdateLinks() to new SwDoc::UpdateLinks(): + */ +- virtual void UpdateLinks(bool bUI) = 0; ++ virtual void UpdateLinks() = 0; + + /** SS fuers Linken von Dokumentteilen / ?? for linking of parts of documents. + */ +diff --git a/sw/source/core/doc/DocumentLinksAdministrationManager.cxx b/sw/source/core/doc/DocumentLinksAdministrationManager.cxx +index 989a85240f58..882050b52f45 100644 +--- a/sw/source/core/doc/DocumentLinksAdministrationManager.cxx ++++ b/sw/source/core/doc/DocumentLinksAdministrationManager.cxx +@@ -199,47 +199,58 @@ const sfx2::LinkManager& DocumentLinksAdministrationManager::GetLinkManager() co + + // #i42634# Moved common code of SwReader::Read() and SwDocShell::UpdateLinks() + // to new SwDoc::UpdateLinks(): +-void DocumentLinksAdministrationManager::UpdateLinks( bool bUI ) ++void DocumentLinksAdministrationManager::UpdateLinks() + { +- SfxObjectCreateMode eMode; +- sal_uInt16 nLinkMode = m_rDoc.GetDocumentSettingManager().getLinkUpdateMode( true ); +- if ( m_rDoc.GetDocShell()) { +- sal_uInt16 nUpdateDocMode = m_rDoc.GetDocShell()->GetUpdateDocMode(); +- if( (nLinkMode != NEVER || document::UpdateDocMode::FULL_UPDATE == nUpdateDocMode) && +- !GetLinkManager().GetLinks().empty() && +- SfxObjectCreateMode::INTERNAL != +- ( eMode = m_rDoc.GetDocShell()->GetCreateMode()) && +- SfxObjectCreateMode::ORGANIZER != eMode && +- SfxObjectCreateMode::PREVIEW != eMode && +- !m_rDoc.GetDocShell()->IsPreview() ) ++ if (!m_rDoc.GetDocShell()) ++ return; ++ SfxObjectCreateMode eMode = m_rDoc.GetDocShell()->GetCreateMode(); ++ if (eMode == SfxObjectCreateMode::INTERNAL) ++ return; ++ if (eMode == SfxObjectCreateMode::ORGANIZER) ++ return; ++ if (eMode == SfxObjectCreateMode::PREVIEW) ++ return; ++ if (m_rDoc.GetDocShell()->IsPreview()) ++ return; ++ if (GetLinkManager().GetLinks().empty()) ++ return; ++ sal_uInt16 nLinkMode = m_rDoc.GetDocumentSettingManager().getLinkUpdateMode(true); ++ sal_uInt16 nUpdateDocMode = m_rDoc.GetDocShell()->GetUpdateDocMode(); ++ if (nLinkMode == NEVER && nUpdateDocMode != document::UpdateDocMode::FULL_UPDATE) ++ return; ++ ++ bool bAskUpdate = nLinkMode == MANUAL; ++ bool bUpdate = true; ++ switch(nUpdateDocMode) ++ { ++ case document::UpdateDocMode::NO_UPDATE: bUpdate = false;break; ++ case document::UpdateDocMode::QUIET_UPDATE:bAskUpdate = false; break; ++ case document::UpdateDocMode::FULL_UPDATE: bAskUpdate = true; break; ++ } ++ if (nLinkMode == AUTOMATIC && !bAskUpdate) ++ { ++ SfxMedium * medium = m_rDoc.GetDocShell()->GetMedium(); ++ if (!SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( ++ medium == nullptr ? OUString() : medium->GetName())) + { +- bool bAskUpdate = nLinkMode == MANUAL; +- bool bUpdate = true; +- switch(nUpdateDocMode) +- { +- case document::UpdateDocMode::NO_UPDATE: bUpdate = false;break; +- case document::UpdateDocMode::QUIET_UPDATE:bAskUpdate = false; break; +- case document::UpdateDocMode::FULL_UPDATE: bAskUpdate = true; break; +- } +- if (nLinkMode == AUTOMATIC && !bAskUpdate) +- { +- SfxMedium * medium = m_rDoc.GetDocShell()->GetMedium(); +- if (!SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( +- medium == nullptr ? OUString() : medium->GetName())) +- { +- bAskUpdate = true; +- } +- } +- if( bUpdate && (bUI || !bAskUpdate) ) +- { +- SfxMedium* pMedium = m_rDoc.GetDocShell()->GetMedium(); +- SfxFrame* pFrm = pMedium ? pMedium->GetLoadTargetFrame() : 0; +- vcl::Window* pDlgParent = pFrm ? &pFrm->GetWindow() : 0; +- +- GetLinkManager().UpdateAllLinks( bAskUpdate, true, false, pDlgParent ); +- } ++ bAskUpdate = true; + } + } ++ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = m_rDoc.GetDocShell()->getEmbeddedObjectContainer(); ++ if (bUpdate) ++ { ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true); ++ ++ SfxMedium* pMedium = m_rDoc.GetDocShell()->GetMedium(); ++ SfxFrame* pFrame = pMedium ? pMedium->GetLoadTargetFrame() : nullptr; ++ vcl::Window* pDlgParent = pFrame ? &pFrame->GetWindow() : nullptr; ++ ++ GetLinkManager().UpdateAllLinks( bAskUpdate, true, false, pDlgParent ); ++ } ++ else ++ { ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); ++ } + } + + bool DocumentLinksAdministrationManager::GetData( const OUString& rItem, const OUString& rMimeType, +diff --git a/sw/source/core/inc/DocumentLinksAdministrationManager.hxx b/sw/source/core/inc/DocumentLinksAdministrationManager.hxx +index 79eb9adf3b96..712cb7942b74 100644 +--- a/sw/source/core/inc/DocumentLinksAdministrationManager.hxx ++++ b/sw/source/core/inc/DocumentLinksAdministrationManager.hxx +@@ -47,7 +47,7 @@ public: + + const sfx2::LinkManager& GetLinkManager() const SAL_OVERRIDE; + +- void UpdateLinks(bool bUI) SAL_OVERRIDE; ++ void UpdateLinks() override; + + bool GetData(const OUString& rItem, const OUString& rMimeType, ::com::sun::star::uno::Any& rValue) const SAL_OVERRIDE; + +diff --git a/sw/source/filter/basflt/shellio.cxx b/sw/source/filter/basflt/shellio.cxx +index d42b0642a52c..b111e80d73cc 100644 +--- a/sw/source/filter/basflt/shellio.cxx ++++ b/sw/source/filter/basflt/shellio.cxx +@@ -364,7 +364,7 @@ sal_uLong SwReader::Read( const Reader& rOptions ) + // #i42634# Moved common code of SwReader::Read() and + // SwDocShell::UpdateLinks() to new SwDoc::UpdateLinks(): + // ATM still with Update +- pDoc->getIDocumentLinksAdministration().UpdateLinks( true ); ++ pDoc->getIDocumentLinksAdministration().UpdateLinks(); + + // not insert: set the redline mode read from settings.xml + eOld = static_cast( +diff --git a/sw/source/uibase/app/docsh.cxx b/sw/source/uibase/app/docsh.cxx +index 6655f045539e..dd307248832e 100644 +--- a/sw/source/uibase/app/docsh.cxx ++++ b/sw/source/uibase/app/docsh.cxx +@@ -1179,7 +1179,7 @@ void SwDocShell::CalcLayoutForOLEObjects() + // read by the binary filter: + void SwDocShell::UpdateLinks() + { +- GetDoc()->getIDocumentLinksAdministration().UpdateLinks(true); ++ GetDoc()->getIDocumentLinksAdministration().UpdateLinks(); + // #i50703# Update footnote numbers + SwTextFootnote::SetUniqueSeqRefNo( *GetDoc() ); + SwNodeIndex aTmp( GetDoc()->GetNodes() ); +diff --git a/sw/source/uibase/app/docshini.cxx b/sw/source/uibase/app/docshini.cxx +index fca4e2e44657..faefa968d26c 100644 +--- a/sw/source/uibase/app/docshini.cxx ++++ b/sw/source/uibase/app/docshini.cxx +@@ -486,6 +486,9 @@ bool SwDocShell::Load( SfxMedium& rMedium ) + bool bRet = false; + if( SfxObjectShell::Load( rMedium )) + { ++ comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); ++ rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); ++ + SAL_INFO( "sw.ui", "after SfxInPlaceObject::Load" ); + if (m_pDoc) // for last version!! + RemoveLink(); // release the existing +-- +2.12.0 + diff --git a/SOURCES/0001-disable-libe-book-support.patch b/SOURCES/0001-disable-libe-book-support.patch new file mode 100644 index 0000000..b7d87b5 --- /dev/null +++ b/SOURCES/0001-disable-libe-book-support.patch @@ -0,0 +1,150 @@ +From e7836800ed8edc25284ac690acee2ce0819d5de1 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 21 Aug 2014 16:10:51 +0200 +Subject: [PATCH] disable libe-book support + +Change-Id: Ie915a9bd2acf7f3aeb8b0933252da33c17043bc4 +--- + configure.ac | 5 ----- + external/Module_external.mk | 1 - + filter/Configuration_filter.mk | 14 -------------- + writerperfect/Library_wpftwriter.mk | 2 -- + writerperfect/qa/unit/WpftWriterFilterTest.cxx | 1 - + writerperfect/source/writer/wpftwriter.component | 4 ---- + writerperfect/source/writer/wpftwriter_genericfilter.cxx | 6 ------ + 7 files changed, 33 deletions(-) + +diff --git a/configure.ac b/configure.ac +index ed71d8f..32fa8ae 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -7583,11 +7583,6 @@ AS_IF([test "$COM" = "MSC"], + libo_CHECK_SYSTEM_MODULE([librevenge],[REVENGE],[librevenge-0.0 >= 0.0.1],["-I${WORKDIR}/UnpackedTarball/librevenge/inc"],["-L${librevenge_libdir} -lrevenge-0.0"]) + + dnl =================================================================== +-dnl Check for system libe-book +-dnl =================================================================== +-libo_CHECK_SYSTEM_MODULE([libebook],[EBOOK],[libe-book-0.1 >= 0.1.1]) +- +-dnl =================================================================== + dnl Check for system libetonyek + dnl =================================================================== + libo_CHECK_SYSTEM_MODULE([libetonyek],[ETONYEK],[libetonyek-0.1 >= 0.1.2]) +diff --git a/external/Module_external.mk b/external/Module_external.mk +index 6d38fd5..25cb2d9 100644 +--- a/external/Module_external.mk ++++ b/external/Module_external.mk +@@ -34,7 +34,6 @@ $(eval $(call gb_Module_add_moduledirs,external,\ + $(call gb_Helper_optional,CPPUNIT,cppunit) \ + $(call gb_Helper_optional,CT2N,ct2n) \ + $(call gb_Helper_optional,CURL,curl) \ +- $(call gb_Helper_optional,EBOOK,libebook) \ + $(call gb_Helper_optional,EPM,epm) \ + $(call gb_Helper_optional,ETONYEK,libetonyek) \ + $(call gb_Helper_optional,EXPAT,expat) \ +diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk +index 29e672b..213e981 100644 +--- a/filter/Configuration_filter.mk ++++ b/filter/Configuration_filter.mk +@@ -362,13 +362,6 @@ $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_writer_types.xcu + writer_OOXML \ + writer_OOXML_Template \ + writer_layout_dump_xml \ +- writer_BroadBand_eBook \ +- writer_eReader_eBook \ +- writer_FictionBook_2 \ +- writer_PalmDoc \ +- writer_Plucker_eBook \ +- writer_TealDoc \ +- writer_zTXT \ + writer_ApplePages \ + )) + +@@ -425,13 +418,6 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_writer_filters + OOXML_Text \ + OOXML_Text_Template \ + writer_layout_dump \ +- BroadBand_eBook \ +- eReader_eBook \ +- FictionBook_2 \ +- PalmDoc \ +- Plucker_eBook \ +- TealDoc \ +- zTXT \ + ApplePages \ + )) + +diff --git a/writerperfect/Library_wpftwriter.mk b/writerperfect/Library_wpftwriter.mk +index 8557991..288c929 100644 +--- a/writerperfect/Library_wpftwriter.mk ++++ b/writerperfect/Library_wpftwriter.mk +@@ -49,7 +49,6 @@ $(eval $(call gb_Library_use_libraries,wpftwriter,\ + $(eval $(call gb_Library_use_externals,wpftwriter,\ + abw \ + boost_headers \ +- ebook \ + etonyek \ + icui18n \ + icuuc \ +@@ -65,7 +64,6 @@ $(eval $(call gb_Library_use_externals,wpftwriter,\ + + $(eval $(call gb_Library_add_exception_objects,wpftwriter,\ + writerperfect/source/writer/AbiWordImportFilter \ +- writerperfect/source/writer/EBookImportFilter \ + writerperfect/source/writer/MSWorksImportFilter \ + writerperfect/source/writer/MWAWImportFilter \ + writerperfect/source/writer/PagesImportFilter \ +diff --git a/writerperfect/qa/unit/WpftWriterFilterTest.cxx b/writerperfect/qa/unit/WpftWriterFilterTest.cxx +index f8f9f85..d928f52 100644 +--- a/writerperfect/qa/unit/WpftWriterFilterTest.cxx ++++ b/writerperfect/qa/unit/WpftWriterFilterTest.cxx +@@ -32,7 +32,6 @@ WpftWriterFilterTest::WpftWriterFilterTest() + void WpftWriterFilterTest::test() + { + doTest("com.sun.star.comp.Writer.AbiWordImportFilter", "/writerperfect/qa/unit/data/writer/libabw/"); +- doTest("org.libreoffice.comp.Writer.EBookImportFilter", "/writerperfect/qa/unit/data/writer/libe-book/"); + doTest("com.sun.star.comp.Writer.MSWorksImportFilter", "/writerperfect/qa/unit/data/writer/libwps/"); + doTest("com.sun.star.comp.Writer.MWAWImportFilter", "/writerperfect/qa/unit/data/writer/libmwaw/"); + doTest("org.libreoffice.comp.Writer.PagesImportFilter", "/writerperfect/qa/unit/data/writer/libetonyek/"); +diff --git a/writerperfect/source/writer/wpftwriter.component b/writerperfect/source/writer/wpftwriter.component +index eaf751a..4b8efbf 100644 +--- a/writerperfect/source/writer/wpftwriter.component ++++ b/writerperfect/source/writer/wpftwriter.component +@@ -34,10 +34,6 @@ + + + +- +- +- +- + + + +diff --git a/writerperfect/source/writer/wpftwriter_genericfilter.cxx b/writerperfect/source/writer/wpftwriter_genericfilter.cxx +index 3f508c4..7e10b9e 100644 +--- a/writerperfect/source/writer/wpftwriter_genericfilter.cxx ++++ b/writerperfect/source/writer/wpftwriter_genericfilter.cxx +@@ -32,7 +32,6 @@ + #include "sal/types.h" + + #include "AbiWordImportFilter.hxx" +-#include "EBookImportFilter.hxx" + #include "WordPerfectImportFilter.hxx" + #include "MSWorksImportFilter.hxx" + #include "MWAWImportFilter.hxx" +@@ -64,11 +63,6 @@ static cppu::ImplementationEntry const services[] = + &cppu::createSingleComponentFactory, 0, 0 + }, + { +- &EBookImportFilter_createInstance, &EBookImportFilter_getImplementationName, +- &EBookImportFilter_getSupportedServiceNames, +- &cppu::createSingleComponentFactory, 0, 0 +- }, +- { + &PagesImportFilter_createInstance, &PagesImportFilter_getImplementationName, + &PagesImportFilter_getSupportedServiceNames, + &cppu::createSingleComponentFactory, 0, 0 +-- +2.4.2 + diff --git a/SOURCES/0001-f22-openjdk-for-ppc64le-has-both-these-dirs-but-jawt.patch b/SOURCES/0001-f22-openjdk-for-ppc64le-has-both-these-dirs-but-jawt.patch new file mode 100644 index 0000000..0217b2d --- /dev/null +++ b/SOURCES/0001-f22-openjdk-for-ppc64le-has-both-these-dirs-but-jawt.patch @@ -0,0 +1,27 @@ +From e13b0657a3a05139f751124145aa10758c59d1dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 1 Jul 2015 08:34:58 +0100 +Subject: [PATCH] f22 openjdk for ppc64le has both these dirs, but jawt is only + on one + +Change-Id: Ie770ecceb8c8f5a6fa882a9f5d5a26806b029589 +--- + configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index aecbe8f..8964c96 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -7058,7 +7058,7 @@ then + my_java_arch=ppc64 + ;; + powerpc64le) +- AS_IF([test -d "$JAVA_HOME/jre/lib/ppc64le"], [my_java_arch=ppc64le], [my_java_arch=ppc64]) ++ AS_IF([test -e "$JAVA_HOME/jre/lib/ppc64le/libjawt.so"], [my_java_arch=ppc64le], [my_java_arch=ppc64]) + JAVA_ARCH=$my_java_arch + ;; + x86_64) +-- +2.4.0 + diff --git a/SOURCES/0001-fix-Link-operator.patch b/SOURCES/0001-fix-Link-operator.patch new file mode 100644 index 0000000..638cdca --- /dev/null +++ b/SOURCES/0001-fix-Link-operator.patch @@ -0,0 +1,87 @@ +From 7e4dd61f264a906885cde307929b300287dab8c5 Mon Sep 17 00:00:00 2001 +From: Noel Grandin +Date: Tue, 22 Dec 2015 09:05:32 +0200 +Subject: [PATCH] fix Link::operator< + +so that it is consistent with operator== + +plus c615943bda57eadfa73c14a7314938aabe0bd16f +and f120abb446bf3f5230ed06a3b148654dde36bb94 + +just in case + +(cherry picked from commit 144e73f50c49333f61c6f27b882be9dbc232ceb4) + +Change-Id: Ie4c68a1f02d8c298fe99e42c5854f89db79bf3bc +--- + include/tools/link.hxx | 10 ++++++++-- + vcl/source/control/combobox.cxx | 6 ++++++ + vcl/source/control/lstbox.cxx | 2 ++ + 3 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/include/tools/link.hxx b/include/tools/link.hxx +index fa86e5d..a3ad0c3 100644 +--- a/include/tools/link.hxx ++++ b/include/tools/link.hxx +@@ -131,8 +131,14 @@ public: + bool operator !() const { return !IsSet(); } + + bool operator <(Link const & other) const { +- return reinterpret_cast(function_) +- < reinterpret_cast(other.function_); ++ sal_uIntPtr ptr1 = reinterpret_cast(function_); ++ sal_uIntPtr ptr2 = reinterpret_cast(other.function_); ++ if (ptr1 < ptr2) ++ return true; ++ else if (ptr1 > ptr2) ++ return false; ++ else ++ return instance_ < other.instance_; + }; + + bool operator ==(Link const & other) const +diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx +index 19c95e7..9e05a69 100644 +--- a/vcl/source/control/combobox.cxx ++++ b/vcl/source/control/combobox.cxx +@@ -953,11 +953,15 @@ OUString ComboBox::GetEntry( sal_Int32 nPos ) const + + sal_Int32 ComboBox::GetEntryCount() const + { ++ if (!mpImplLB) ++ return 0; + return mpImplLB->GetEntryList()->GetEntryCount() - mpImplLB->GetEntryList()->GetMRUCount(); + } + + bool ComboBox::IsTravelSelect() const + { ++ if (!mpImplLB) ++ return false; + return mpImplLB->IsTravelSelect(); + } + +@@ -974,6 +978,8 @@ void ComboBox::EnableMultiSelection( bool bMulti ) + + bool ComboBox::IsMultiSelectionEnabled() const + { ++ if (!mpImplLB) ++ return false; + return mpImplLB->IsMultiSelectionEnabled(); + } + +diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx +index 1b0943b..8c701c7 100644 +--- a/vcl/source/control/lstbox.cxx ++++ b/vcl/source/control/lstbox.cxx +@@ -1215,6 +1215,8 @@ void ListBox::EnableMultiSelection( bool bMulti, bool bStackSelection ) + + bool ListBox::IsMultiSelectionEnabled() const + { ++ if (!mpImplLB) ++ return false; + return mpImplLB->IsMultiSelectionEnabled(); + } + +-- +2.9.3 + diff --git a/SOURCES/0001-gtk3-Resolves-tdf-96333-fix-RTL-menu-positioning.patch b/SOURCES/0001-gtk3-Resolves-tdf-96333-fix-RTL-menu-positioning.patch new file mode 100644 index 0000000..b5e4f20 --- /dev/null +++ b/SOURCES/0001-gtk3-Resolves-tdf-96333-fix-RTL-menu-positioning.patch @@ -0,0 +1,27 @@ +From e6e024c747eaaa58ccd7ed542c7c31fcb6911090 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 18 Feb 2016 17:20:34 +0000 +Subject: [PATCH] gtk3: Resolves: tdf#96333 fix RTL menu positioning + +Change-Id: I22c5186371e558ed84da81c43400379c218ca816 +(cherry picked from commit d7a292ce490eeb8ff02e145e0a55f41f4c179541) +--- + vcl/unx/gtk3/gtk3gtkframe.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index 3914de5..6902256 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -1613,7 +1613,7 @@ void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u + if( m_pParent ) + { + if( AllSettings::GetLayoutRTL() ) +- nX = m_pParent->maGeometry.nWidth-maGeometry.nWidth-1-nX; ++ nX = m_pParent->maGeometry.nWidth-m_nWidthRequest-1-nX; + nX += m_pParent->maGeometry.nX; + nY += m_pParent->maGeometry.nY; + } +-- +2.7.1 + diff --git a/SOURCES/0001-gtk3-avoid-empty-target-clipboard-warning.patch b/SOURCES/0001-gtk3-avoid-empty-target-clipboard-warning.patch new file mode 100644 index 0000000..4fec7fd --- /dev/null +++ b/SOURCES/0001-gtk3-avoid-empty-target-clipboard-warning.patch @@ -0,0 +1,42 @@ +From 7b422cce4ebc291d5eff723dc0fd4497ab412ed5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 4 Dec 2015 14:11:24 +0000 +Subject: [PATCH 1/3] gtk3: avoid empty target clipboard warning + +Change-Id: Ic6b46eb2c81398f0ab2e7539e5cdb27a508c8893 +(cherry picked from commit 66fedc0966ad0c732cada974ea910d7a98beca15) +--- + vcl/unx/gtk3/gtk3gtkinst.cxx | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx +index 9f15db0..e9210d0 100644 +--- a/vcl/unx/gtk3/gtk3gtkinst.cxx ++++ b/vcl/unx/gtk3/gtk3gtkinst.cxx +@@ -572,13 +572,16 @@ void VclGtkClipboard::setContents( + aGtkTargets.push_back(makeGtkTargetEntry(aFlavor)); + } + +- //if there was a previous gtk_clipboard_set_with_data call then +- //ClipboardClearFunc will be called now +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- //use with_owner with m_pOwner so we can distinguish in handle_owner_change +- //if we have gained or lost ownership of the clipboard +- gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(), +- ClipboardGetFunc, ClipboardClearFunc, G_OBJECT(m_pOwner)); ++ if (!aGtkTargets.empty()) ++ { ++ //if there was a previous gtk_clipboard_set_with_data call then ++ //ClipboardClearFunc will be called now ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ //use with_owner with m_pOwner so we can distinguish in handle_owner_change ++ //if we have gained or lost ownership of the clipboard ++ gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(), ++ ClipboardGetFunc, ClipboardClearFunc, G_OBJECT(m_pOwner)); ++ } + m_aGtkTargets = aGtkTargets; + } + +-- +2.5.0 + diff --git a/SOURCES/0001-gtk3-gtk_gesture_get_point-may-return-false.patch b/SOURCES/0001-gtk3-gtk_gesture_get_point-may-return-false.patch new file mode 100644 index 0000000..d527ee7 --- /dev/null +++ b/SOURCES/0001-gtk3-gtk_gesture_get_point-may-return-false.patch @@ -0,0 +1,53 @@ +From a645619a5740b1eb43795f07fd80f25e240821b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 1 Dec 2015 20:51:06 +0000 +Subject: [PATCH] gtk3: gtk_gesture_get_point may return false + +(cherry picked from commit 23d5775ecf04c001ecf86b6012aef4d1a3f2f063) + +Change-Id: Ibd175c65babdde48132692fd1979a00929356bb4 +--- + vcl/unx/gtk/window/gtksalframe.cxx | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx +index 616f73f..9e03f14 100644 +--- a/vcl/unx/gtk/window/gtksalframe.cxx ++++ b/vcl/unx/gtk/window/gtksalframe.cxx +@@ -3611,22 +3611,23 @@ gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame + #if GTK_CHECK_VERSION(3,14,0) + void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame) + { +- GtkSalFrame* pThis = static_cast(frame); +- +- SalSwipeEvent aEvent; +- aEvent.mnVelocityX = velocity_x; +- aEvent.mnVelocityY = velocity_y; +- + gdouble x, y; + GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); + //I feel I want the first point of the sequence, not the last point which + //the docs say this gives, but for the moment assume we start and end + //within the same vcl window +- gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y); +- aEvent.mnX = x; +- aEvent.mnY = y; ++ if (gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y)) ++ { ++ GtkSalFrame* pThis = static_cast(frame); + +- pThis->CallCallback(SALEVENT_SWIPE, &aEvent); ++ SalSwipeEvent aEvent; ++ aEvent.mnVelocityX = velocity_x; ++ aEvent.mnVelocityY = velocity_y; ++ aEvent.mnX = x; ++ aEvent.mnY = y; ++ ++ pThis->CallCallback(SALEVENT_SWIPE, &aEvent); ++ } + } + + void GtkSalFrame::gestureLongPress(GtkGestureLongPress* gesture, gpointer frame) +-- +2.5.0 + diff --git a/SOURCES/0001-gtk3-implement-SAL_INVERT_50-rectangle-case.patch b/SOURCES/0001-gtk3-implement-SAL_INVERT_50-rectangle-case.patch new file mode 100644 index 0000000..3de82c7 --- /dev/null +++ b/SOURCES/0001-gtk3-implement-SAL_INVERT_50-rectangle-case.patch @@ -0,0 +1,110 @@ +From 63d5cc018d268a8d269cb2353ddaeb68fc74d64c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 30 Nov 2015 10:22:46 +0000 +Subject: [PATCH] gtk3: implement SAL_INVERT_50 rectangle case + +missing stipple effect around slides in layout panel + +(cherry picked from commit a80dea3e77c2a8465cdd309c5f740fb8102dd826) +(cherry picked from commit 442d064188a2d50406e485d033accfffe4bd54e9) + +Change-Id: I8a55c6bda1e742e105ba22e4566658099ea16f46 +--- + vcl/headless/svpgdi.cxx | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 71 insertions(+), 2 deletions(-) + +diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx +index 06030d9..0afce7e 100644 +--- a/vcl/headless/svpgdi.cxx ++++ b/vcl/headless/svpgdi.cxx +@@ -913,9 +913,76 @@ SalColor SvpSalGraphics::getPixel( long nX, long nY ) + return aColor.toInt32(); + } + +-void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert /*nFlags*/ ) ++namespace + { +- // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME ++ cairo_pattern_t * create_stipple() ++ { ++ static unsigned char data[16] = { 0xFF, 0xFF, 0x00, 0x00, ++ 0xFF, 0xFF, 0x00, 0x00, ++ 0x00, 0x00, 0xFF, 0xFF, ++ 0x00, 0x00, 0xFF, 0xFF }; ++ cairo_surface_t* surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_A8, 4, 4, 4); ++ cairo_pattern_t* pattern = cairo_pattern_create_for_surface(surface); ++ cairo_surface_destroy(surface); ++ cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); ++ cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST); ++ return pattern; ++ } ++} ++ ++void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags ) ++{ ++#if ENABLE_CAIRO_CANVAS ++#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0) ++ // FIXME: handle SAL_INVERT_TRACKFRAME ++ if ( nFlags & SAL_INVERT_TRACKFRAME ) ++ { ++ SAL_WARN("vcl.gdi", "SvpSalGraphics::invert, unhandled SAL_INVERT_TRACKFRAME"); ++ } ++ else if ( nFlags & SAL_INVERT_50 ) ++ { ++ if (cairo_t* cr = createCairoContext(m_aDevice)) ++ { ++ if (!m_aDevice->isTopDown()) ++ { ++ cairo_scale(cr, 1, -1.0); ++ cairo_translate(cr, 0.0, -m_aDevice->getSize().getY()); ++ } ++ ++ clipRegion(cr); ++ ++ cairo_pattern_t *pattern = create_stipple(); ++ ++ cairo_rectangle_int_t extents; ++ basebmp::IBitmapDeviceDamageTrackerSharedPtr xDamageTracker(m_aDevice->getDamageTracker()); ++ ++ cairo_rectangle(cr, nX, nY, nWidth, nHeight); ++ ++ if (xDamageTracker) ++ extents = getFillDamage(cr); ++ ++ cairo_clip(cr); ++ ++ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); ++ cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); ++ cairo_mask(cr, pattern); ++ cairo_pattern_destroy(pattern); ++ ++ cairo_surface_flush(cairo_get_target(cr)); ++ cairo_destroy(cr); // unref ++ ++ return; ++ } ++ else ++ SAL_WARN("vcl.gdi", "SvpSalGraphics::invert unhandled XOR (?)"); ++ } ++ else ++ { ++ SAL_WARN("vcl.gdi", "SvpSalGraphics::invert, unhandled SAL_INVERT_TRACKFRAME"); ++ } ++#endif ++#endif ++ + basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) ); + basegfx::B2DPolyPolygon aPolyPoly( aRect ); + basegfx::B2IBox aDestRange( nX, nY, nX + nWidth, nY + nHeight ); +@@ -928,6 +995,8 @@ void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv + + void SvpSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert /*nFlags*/ ) + { ++ SAL_WARN("vcl.gdi", "SvpSalGraphics::invert, unhandled points case"); ++ + // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME + basegfx::B2DPolygon aPoly; + aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints ); +-- +2.5.0 + diff --git a/SOURCES/0001-gtk3-stop-the-ever-shrinking-size-of-toplevel-on-eve.patch b/SOURCES/0001-gtk3-stop-the-ever-shrinking-size-of-toplevel-on-eve.patch new file mode 100644 index 0000000..e357f9a --- /dev/null +++ b/SOURCES/0001-gtk3-stop-the-ever-shrinking-size-of-toplevel-on-eve.patch @@ -0,0 +1,105 @@ +From 3b31d0dc86d75f8283951f3fd6a4f48ff649ed99 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 4 Dec 2015 13:07:57 +0000 +Subject: [PATCH] gtk3: stop the ever shrinking size of toplevel on every + restore +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +for getting and setting the window state, work on the toplevel m_pWindow. Leave +the "geometry" alone as its for the purpose of the current known size of the +toplevel window contents + +Change-Id: Idf701aacf4aed4eefbca1bc1ebebaf38d1c82e27 +Reviewed-on: https://gerrit.libreoffice.org/20397 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 7242ed0567297c3c5186b4095496fc01448359f4) +--- + vcl/unx/gtk3/gtk3gtkframe.cxx | 41 ++++++++++++++++++++++++++++------------- + 1 file changed, 28 insertions(+), 13 deletions(-) + +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index 966dc80..576946f 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -1703,6 +1703,28 @@ void GtkSalFrame::SetWindowState( const SalFrameState* pState ) + TriggerPaintEvent(); + } + ++namespace ++{ ++ void GetPosAndSize(GtkWindow *pWindow, long& rX, long &rY, long &rWidth, long &rHeight) ++ { ++ gint root_x, root_y; ++ gtk_window_get_position(GTK_WINDOW(pWindow), &root_x, &root_y); ++ rX = root_x; ++ rY = root_y; ++ gint width, height; ++ gtk_window_get_size(GTK_WINDOW(pWindow), &width, &height); ++ rWidth = width; ++ rHeight = height; ++ } ++ ++ Rectangle GetPosAndSize(GtkWindow *pWindow) ++ { ++ long nX, nY, nWidth, nHeight; ++ GetPosAndSize(pWindow, nX, nY, nWidth, nHeight); ++ return Rectangle(nX, nY, nX + nWidth, nY + nHeight); ++ } ++} ++ + bool GtkSalFrame::GetWindowState( SalFrameState* pState ) + { + pState->mnState = WINDOWSTATE_STATE_NORMAL; +@@ -1717,10 +1739,8 @@ bool GtkSalFrame::GetWindowState( SalFrameState* pState ) + pState->mnY = m_aRestorePosSize.Top(); + pState->mnWidth = m_aRestorePosSize.GetWidth(); + pState->mnHeight = m_aRestorePosSize.GetHeight(); +- pState->mnMaximizedX = maGeometry.nX; +- pState->mnMaximizedY = maGeometry.nY; +- pState->mnMaximizedWidth = maGeometry.nWidth; +- pState->mnMaximizedHeight = maGeometry.nHeight; ++ GetPosAndSize(GTK_WINDOW(m_pWindow), pState->mnMaximizedX, pState->mnMaximizedY, ++ pState->mnMaximizedWidth, pState->mnMaximizedWidth); + pState->mnMask |= WINDOWSTATE_MASK_MAXIMIZED_X | + WINDOWSTATE_MASK_MAXIMIZED_Y | + WINDOWSTATE_MASK_MAXIMIZED_WIDTH | +@@ -1728,10 +1748,8 @@ bool GtkSalFrame::GetWindowState( SalFrameState* pState ) + } + else + { +- pState->mnX = maGeometry.nX; +- pState->mnY = maGeometry.nY; +- pState->mnWidth = maGeometry.nWidth; +- pState->mnHeight = maGeometry.nHeight; ++ GetPosAndSize(GTK_WINDOW(m_pWindow), pState->mnX, pState->mnY, ++ pState->mnWidth, pState->mnHeight); + } + pState->mnMask |= WINDOWSTATE_MASK_X | + WINDOWSTATE_MASK_Y | +@@ -1932,8 +1950,7 @@ void GtkSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen ) + + if( bFullScreen ) + { +- m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), +- Size( maGeometry.nWidth, maGeometry.nHeight ) ); ++ m_aRestorePosSize = GetPosAndSize(GTK_WINDOW(m_pWindow)); + SetScreen( nScreen, SET_FULLSCREEN ); + } + else +@@ -2963,9 +2980,7 @@ gboolean GtkSalFrame::signalWindowState( GtkWidget*, GdkEvent* pEvent, gpointer + if( (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) && + ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) ) + { +- pThis->m_aRestorePosSize = +- Rectangle( Point( pThis->maGeometry.nX, pThis->maGeometry.nY ), +- Size( pThis->maGeometry.nWidth, pThis->maGeometry.nHeight ) ); ++ pThis->m_aRestorePosSize = GetPosAndSize(GTK_WINDOW(pThis->m_pWindow)); + } + pThis->m_nState = pEvent->window_state.new_window_state; + +-- +2.5.0 + diff --git a/SOURCES/0001-gtk3-wayland-dialogs-work-a-lot-better-if-a-min-size.patch b/SOURCES/0001-gtk3-wayland-dialogs-work-a-lot-better-if-a-min-size.patch new file mode 100644 index 0000000..ec731c4 --- /dev/null +++ b/SOURCES/0001-gtk3-wayland-dialogs-work-a-lot-better-if-a-min-size.patch @@ -0,0 +1,31 @@ +From f4ac9a55997efbe9c71b7f87ef138e378d95583c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 8 Dec 2015 15:10:45 +0000 +Subject: [PATCH] gtk3+wayland: dialogs work a lot better if a min size is set + +instead of just an initial size, because we can set a size-request for the +minimum size and that's a reliable thing + +Change-Id: I83916715cb9e3dceb6e88f3ca8fc86920677c026 +(cherry picked from commit ebafc4fef20944c9c0ba75fbea064bf285a73735) +--- + vcl/source/window/btndlg.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/vcl/source/window/btndlg.cxx b/vcl/source/window/btndlg.cxx +index bb0f0a3..16a695f 100644 +--- a/vcl/source/window/btndlg.cxx ++++ b/vcl/source/window/btndlg.cxx +@@ -208,7 +208,8 @@ void ButtonDialog::ImplPosControls() + nY += maCtrlSize.Height()+IMPL_SEP_BUTTON_Y; + } + +- SetOutputSizePixel( aDlgSize ); ++ SetOutputSizePixel(aDlgSize); ++ SetMinOutputSizePixel(aDlgSize); + + mbFormat = false; + } +-- +2.5.0 + diff --git a/SOURCES/0001-gtk3-wayland-enable-manual-movement-of-toolbars.patch b/SOURCES/0001-gtk3-wayland-enable-manual-movement-of-toolbars.patch new file mode 100644 index 0000000..0ab0b43 --- /dev/null +++ b/SOURCES/0001-gtk3-wayland-enable-manual-movement-of-toolbars.patch @@ -0,0 +1,149 @@ +From 0f58534c4c3825f569a01774b7f8bb1808b37886 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 15 Dec 2015 14:24:35 +0000 +Subject: [PATCH] gtk3+wayland: enable manual movement of toolbars + +via gtk_window_begin_move_drag so add some BYDRAG/ByDrag hints +to select mechanism to move window by + +Change-Id: Icc58653dff752a6d4ee49446647d7ede2af9dd9b +--- + include/vcl/window.hxx | 3 ++- + vcl/inc/brdwin.hxx | 2 ++ + vcl/inc/salframe.hxx | 1 + + vcl/inc/unx/gtk/gtkframe.hxx | 5 ++++- + vcl/source/window/brdwin.cxx | 7 ++++++- + vcl/source/window/window.cxx | 2 ++ + vcl/unx/gtk3/gtk3gtkframe.cxx | 13 ++++++++++++- + 7 files changed, 29 insertions(+), 4 deletions(-) + +diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx +index ae28940..1f5c0c2 100644 +--- a/include/vcl/window.hxx ++++ b/include/vcl/window.hxx +@@ -161,10 +161,11 @@ enum class PosSizeFlags + PosSize = Pos | Size, + All = PosSize, + Dropdown = 0x0010, ++ ByDrag = 0x0020, + }; + namespace o3tl + { +- template<> struct typed_flags : is_typed_flags {}; ++ template<> struct typed_flags : is_typed_flags {}; + } + + // Flags for Show() +diff --git a/vcl/inc/brdwin.hxx b/vcl/inc/brdwin.hxx +index d00ca1b..7e89064 100644 +--- a/vcl/inc/brdwin.hxx ++++ b/vcl/inc/brdwin.hxx +@@ -170,6 +170,8 @@ public: + + Rectangle GetMenuRect() const; + ++ void MoveToByDrag(const Point& rNewPos); ++ + virtual Size GetOptimalSize() const SAL_OVERRIDE; + }; + +diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx +index cfd401d..9b3d52e 100644 +--- a/vcl/inc/salframe.hxx ++++ b/vcl/inc/salframe.hxx +@@ -94,6 +94,7 @@ typedef sal_uInt64 SalExtStyle; + #define SAL_FRAME_POSSIZE_Y ((sal_uInt16)0x0002) + #define SAL_FRAME_POSSIZE_WIDTH ((sal_uInt16)0x0004) + #define SAL_FRAME_POSSIZE_HEIGHT ((sal_uInt16)0x0008) ++#define SAL_FRAME_POSSIZE_BYDRAG ((sal_uInt16)0x0010) + + struct SystemParentData; + +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index b779d39..a55ff2c 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -316,7 +316,10 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + void widget_set_size_request(long nWidth, long nHeight); + + void resizeWindow( long nWidth, long nHeight ); +- void moveWindow( long nX, long nY ); ++ void moveWindow(long nX, long nY); ++#if GTK_CHECK_VERSION(3,0,0) ++ void dragWindowTo(long nX, long nY); ++#endif + + Size calcDefaultSize(); + +diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx +index 97dbc5b..f57ab37 100644 +--- a/vcl/source/window/brdwin.cxx ++++ b/vcl/source/window/brdwin.cxx +@@ -1243,7 +1243,7 @@ bool ImplStdBorderWindowView::Tracking( const TrackingEvent& rTEvt ) + aPos.Y() += aMousePos.Y(); + if ( maFrameData.mbDragFull ) + { +- pBorderWindow->SetPosPixel( aPos ); ++ pBorderWindow->MoveToByDrag(aPos); + pBorderWindow->ImplUpdateAll(); + pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll(); + } +@@ -2195,6 +2195,11 @@ Rectangle ImplBorderWindow::GetMenuRect() const + return mpBorderView->GetMenuRect(); + } + ++void ImplBorderWindow::MoveToByDrag(const Point& rNewPos) ++{ ++ setPosSizePixel(rNewPos.X(), rNewPos.Y(), 0, 0, PosSizeFlags::Pos | PosSizeFlags::ByDrag); ++} ++ + Size ImplBorderWindow::GetOptimalSize() const + { + const vcl::Window* pClientWindow = ImplGetClientWindow(); +diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx +index 20377ac..808d683 100644 +--- a/vcl/source/window/window.cxx ++++ b/vcl/source/window/window.cxx +@@ -2886,6 +2886,8 @@ void Window::setPosSizePixel( long nX, long nY, + nSysFlags |= SAL_FRAME_POSSIZE_WIDTH; + if( nFlags & PosSizeFlags::Height ) + nSysFlags |= SAL_FRAME_POSSIZE_HEIGHT; ++ if( nFlags & PosSizeFlags::ByDrag ) ++ nSysFlags |= SAL_FRAME_POSSIZE_BYDRAG; + if( nFlags & PosSizeFlags::X ) + { + nSysFlags |= SAL_FRAME_POSSIZE_X; +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index 7c24d2b..6a69c82 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -878,6 +878,14 @@ void GtkSalFrame::moveWindow( long nX, long nY ) + gtk_window_move( GTK_WINDOW(m_pWindow), nX, nY ); + } + ++void GtkSalFrame::dragWindowTo(long nX, long nY) ++{ ++ if (isChild(false)) ++ moveWindow(nX, nY); ++ else ++ gtk_window_begin_move_drag(GTK_WINDOW(m_pWindow), 1, nX, nY, GDK_CURRENT_TIME); ++} ++ + void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) + { + gtk_widget_set_size_request(GTK_WIDGET(m_pFixedContainer), nWidth, nHeight ); +@@ -1717,7 +1725,10 @@ void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_u + + m_bDefaultPos = false; + +- moveWindow(nX, nY); ++ if (nFlags & SAL_FRAME_POSSIZE_BYDRAG) ++ dragWindowTo(nX, nY); ++ else ++ moveWindow(nX, nY); + + updateScreenNumber(); + } +-- +2.5.0 + diff --git a/SOURCES/0001-gtk3-wayland-wrong-dialog-sizes.patch b/SOURCES/0001-gtk3-wayland-wrong-dialog-sizes.patch new file mode 100644 index 0000000..3db37e4 --- /dev/null +++ b/SOURCES/0001-gtk3-wayland-wrong-dialog-sizes.patch @@ -0,0 +1,56 @@ +From 88f9c7f53ad1abc49d8ed4cfc46081d767b0c065 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 1 Dec 2015 13:27:21 +0000 +Subject: [PATCH] gtk3+wayland: wrong dialog sizes + +use inner container, not outer toxic toplevel + +Change-Id: I44f2fe1e8e346e51e65158f7864293ef37732345 +--- + vcl/unx/gtk/window/gtksalframe.cxx | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx +index dd03073..99624e0 100644 +--- a/vcl/unx/gtk/window/gtksalframe.cxx ++++ b/vcl/unx/gtk/window/gtksalframe.cxx +@@ -950,22 +950,24 @@ void GtkSalFrame::moveWindow( long nX, long nY ) + + void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) + { ++#if !GTK_CHECK_VERSION(3,0,0) + gint nOrigwidth, nOrigheight; + gtk_window_get_size(GTK_WINDOW(m_pWindow), &nOrigwidth, &nOrigheight); +-#if !GTK_CHECK_VERSION(3,0,0) + if (nWidth > nOrigwidth || nHeight > nOrigheight) + { + m_bPaintsBlocked = true; + } +-#endif + gtk_widget_set_size_request(m_pWindow, nWidth, nHeight ); ++#else ++ gtk_widget_set_size_request(GTK_WIDGET(m_pFixedContainer), nWidth, nHeight ); ++#endif + } + + void GtkSalFrame::window_resize(long nWidth, long nHeight) + { ++#if !GTK_CHECK_VERSION(3,0,0) + gint nOrigwidth, nOrigheight; + gtk_window_get_size(GTK_WINDOW(m_pWindow), &nOrigwidth, &nOrigheight); +-#if !GTK_CHECK_VERSION(3,0,0) + if (nWidth > nOrigwidth || nHeight > nOrigheight) + { + m_bPaintsBlocked = true; +@@ -1087,7 +1089,7 @@ void GtkSalFrame::InitCommon() + m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this )); + #if GTK_CHECK_VERSION(3,0,0) + g_signal_connect( G_OBJECT(m_pFixedContainer), "draw", G_CALLBACK(signalDraw), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "size-allocate", G_CALLBACK(sizeAllocated), this ); ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "size-allocate", G_CALLBACK(sizeAllocated), this ); + // g_signal_connect( G_OBJECT(m_pWindow), "state-flags-changed", G_CALLBACK(signalFlagsChanged), this ); + #if GTK_CHECK_VERSION(3,14,0) + GtkGesture *pSwipe = gtk_gesture_swipe_new(pEventWidget); +-- +2.5.0 + diff --git a/SOURCES/0001-gtktiledviewer-allow-testing-of-destroyView.patch b/SOURCES/0001-gtktiledviewer-allow-testing-of-destroyView.patch new file mode 100644 index 0000000..3dfe99f --- /dev/null +++ b/SOURCES/0001-gtktiledviewer-allow-testing-of-destroyView.patch @@ -0,0 +1,59 @@ +From 905beaa8e862323199263feaeb6262f43fbfc0bc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 15 Jul 2016 15:37:51 +0200 +Subject: [PATCH] gtktiledviewer: allow testing of destroyView() + +By calling it when we're not the last window. + +Change-Id: I6fd4763243fc088ccfe015b6c03b6b3f25146fac +--- + libreofficekit/source/gtk/lokdocview.cxx | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 92cf6b3..b6f34ac 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -127,6 +127,9 @@ struct LOKDocViewPrivateImpl + /// View ID, returned by createView() or 0 by default. + int m_nViewId; + ++ /// Event source ID for handleTimeout() of this widget. ++ guint m_nTimeoutId; ++ + LOKDocViewPrivateImpl() + : m_aLOPath(nullptr), + m_pUserProfileURL(nullptr), +@@ -165,11 +168,19 @@ struct LOKDocViewPrivateImpl + m_aHandleEndRect({0, 0, 0, 0}), + m_bInDragEndHandle(false), + m_pGraphicHandle(nullptr), +- m_nViewId(0) ++ m_nViewId(0), ++ m_nTimeoutId(0) + { + memset(&m_aGraphicHandleRects, 0, sizeof(m_aGraphicHandleRects)); + memset(&m_bInDragGraphicHandles, 0, sizeof(m_bInDragGraphicHandles)); + } ++ ++ ~LOKDocViewPrivateImpl() ++ { ++ if (m_nTimeoutId) ++ g_source_remove(m_nTimeoutId); ++ } ++ + }; + + /// Wrapper around LOKDocViewPrivateImpl, managed by malloc/memset/free. +@@ -768,7 +779,7 @@ static gboolean postDocumentLoad(gpointer pData) + priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument, priv->m_aRenderingArguments.c_str()); + priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pLOKDocView); + priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); +- g_timeout_add(600, handleTimeout, pLOKDocView); ++ priv->m_nTimeoutId = g_timeout_add(600, handleTimeout, pLOKDocView); + + float zoom = priv->m_fZoom; + long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; +-- +1.8.3.1 + diff --git a/SOURCES/0001-implement-dialog-control-over-enhanced-shape-control.patch b/SOURCES/0001-implement-dialog-control-over-enhanced-shape-control.patch new file mode 100644 index 0000000..b71c7b3 --- /dev/null +++ b/SOURCES/0001-implement-dialog-control-over-enhanced-shape-control.patch @@ -0,0 +1,663 @@ +From e9680d99c4403bd07ab4d50939a5d7791bceb98c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 13 Oct 2015 13:16:31 +0100 +Subject: [PATCH] implement dialog control over enhanced shape control points + +use case is a desire to enable viewing and setting rounded rectangle radiuses +to an exact known value + +Change-Id: I7e6a4db0699076950adf5869a61825159766c46a +(cherry picked from commit b859d84e471fdb70b61607d2d919a7907d074bd0) +--- + cui/source/inc/transfrm.hxx | 6 + + cui/source/tabpages/transfrm.cxx | 137 ++++++++++++++- + cui/uiconfig/ui/slantcornertabpage.ui | 310 ++++++++++++++++++++++++++++++---- + include/svx/EnhancedCustomShape2d.hxx | 1 + + 4 files changed, 416 insertions(+), 38 deletions(-) + +diff --git a/cui/source/inc/transfrm.hxx b/cui/source/inc/transfrm.hxx +index 2945d28..2fe2524 100644 +--- a/cui/source/inc/transfrm.hxx ++++ b/cui/source/inc/transfrm.hxx +@@ -239,6 +239,12 @@ private: + VclPtr m_pFlAngle; + VclPtr m_pMtrAngle; + ++ VclPtr m_aControlGroups[2]; ++ VclPtr m_aControlGroupX[2]; ++ VclPtr m_aControlX[2]; ++ VclPtr m_aControlGroupY[2]; ++ VclPtr m_aControlY[2]; ++ + const SfxItemSet& rOutAttrs; + + const SdrView* pView; +diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx +index 950a4b2..43375c2 100644 +--- a/cui/source/tabpages/transfrm.cxx ++++ b/cui/source/tabpages/transfrm.cxx +@@ -18,6 +18,8 @@ + */ + + #include ++#include ++#include + #include + #include + #include +@@ -430,6 +432,15 @@ SvxSlantTabPage::SvxSlantTabPage(vcl::Window* pParent, const SfxItemSet& rInAttr + get(m_pFlAngle, "FL_SLANT"); + get(m_pMtrAngle, "MTR_FLD_ANGLE"); + ++ for (int i = 0; i < 2; ++i) ++ { ++ get(m_aControlGroups[i], "controlgroups" + OString::number(i+1)); ++ get(m_aControlGroupX[i], "controlgroupx" + OString::number(i+1)); ++ get(m_aControlX[i], "controlx" + OString::number(i+1)); ++ get(m_aControlGroupY[i], "controlgroupy" + OString::number(i+1)); ++ get(m_aControlY[i], "controly" + OString::number(i+1)); ++ } ++ + // this page needs ExchangeSupport + SetExchangeSupport(); + +@@ -450,6 +461,14 @@ void SvxSlantTabPage::dispose() + m_pMtrRadius.clear(); + m_pFlAngle.clear(); + m_pMtrAngle.clear(); ++ for (int i = 0; i < 2; ++i) ++ { ++ m_aControlGroups[i].clear(); ++ m_aControlGroupX[i].clear(); ++ m_aControlX[i].clear(); ++ m_aControlGroupY[i].clear(); ++ m_aControlY[i].clear(); ++ } + SvxTabPage::dispose(); + } + +@@ -506,10 +525,56 @@ bool SvxSlantTabPage::FillItemSet(SfxItemSet* rAttrs) + rAttrs->Put( SfxBoolItem( SID_ATTR_TRANSFORM_SHEAR_VERTICAL, false ) ); + } + +- return bModified; +-} ++ bool bControlPointsChanged = false; ++ for (int i = 0; i < 2; ++i) ++ { ++ bControlPointsChanged |= (m_aControlX[i]->IsValueChangedFromSaved() || ++ m_aControlY[i]->IsValueChangedFromSaved()); ++ } ++ ++ if (!bControlPointsChanged) ++ return bModified; ++ ++ SdrObject* pObj = pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj(); ++ SdrModel* pModel = pObj->GetModel(); ++ SdrUndoAction* pUndo = pModel->IsUndoEnabled() ? ++ pModel->GetSdrUndoFactory().CreateUndoAttrObject(*pObj) : ++ nullptr; + ++ if (pUndo) ++ pModel->BegUndo(pUndo->GetComment()); ++ ++ EnhancedCustomShape2d aShape(pObj); ++ Rectangle aLogicRect = aShape.GetLogicRect(); ++ ++ for (int i = 0; i < 2; ++i) ++ { ++ if (m_aControlX[i]->IsValueChangedFromSaved() || m_aControlY[i]->IsValueChangedFromSaved()) ++ { ++ Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit), ++ GetCoreValue(*m_aControlY[i], ePoolUnit)); ++ aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top()); ++ ++ css::awt::Point aPosition; ++ aPosition.X = aNewPosition.X(); ++ aPosition.Y = aNewPosition.Y(); ++ ++ aShape.SetHandleControllerPosition(i, aPosition); ++ } ++ } ++ ++ pObj->SetChanged(); ++ pObj->BroadcastObjectChange(); ++ bModified = true; ++ ++ if (pUndo) ++ { ++ pModel->AddUndo(pUndo); ++ pModel->EndUndo(); ++ } + ++ return bModified; ++} + + void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs) + { +@@ -561,17 +626,76 @@ void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs) + } + + m_pMtrAngle->SaveValue(); +-} +- + ++ const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); ++ if (rMarkList.GetMarkCount() == 1) ++ { ++ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); ++ SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier(); ++ if (eKind == OBJ_CUSTOMSHAPE) ++ { ++ EnhancedCustomShape2d aShape(pObj); ++ Point aInitialPosition; ++ for (int i = 0; i < 2; ++i) ++ { ++ if (!aShape.GetHandlePosition(i, aInitialPosition)) ++ break; ++ m_aControlGroups[i]->Enable(); ++ css::awt::Point aPosition; ++ ++ aPosition.X = SAL_MAX_INT32; ++ aPosition.Y = SAL_MAX_INT32; ++ aShape.SetHandleControllerPosition(i, aPosition); ++ Point aMaxPosition; ++ aShape.GetHandlePosition(i, aMaxPosition); ++ ++ aPosition.X = SAL_MIN_INT32; ++ aPosition.Y = SAL_MIN_INT32; ++ aShape.SetHandleControllerPosition(i, aPosition); ++ Point aMinPosition; ++ aShape.GetHandlePosition(i, aMinPosition); ++ ++ Rectangle aLogicRect = aShape.GetLogicRect(); ++ aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top()); ++ aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top()); ++ ++ aPosition.X = aInitialPosition.X(); ++ aPosition.Y = aInitialPosition.Y(); ++ aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top()); ++ aShape.SetHandleControllerPosition(i, aPosition); ++ ++ SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit); ++ SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit); ++ ++ if (aMaxPosition.X() == aMinPosition.X()) ++ m_aControlGroupX[i]->Disable(); ++ else ++ { ++ m_aControlX[i]->SetMin(aMinPosition.X(), FUNIT_MM); ++ m_aControlX[i]->SetMax(aMaxPosition.X(), FUNIT_MM); ++ } ++ if (aMaxPosition.Y() == aMinPosition.Y()) ++ m_aControlGroupY[i]->Disable(); ++ else ++ { ++ m_aControlY[i]->SetMin(aMinPosition.Y(), FUNIT_MM); ++ m_aControlY[i]->SetMax(aMaxPosition.Y(), FUNIT_MM); ++ } ++ } ++ } ++ } ++ for (int i = 0; i < 2; ++i) ++ { ++ m_aControlX[i]->SaveValue(); ++ m_aControlY[i]->SaveValue(); ++ } ++} + + VclPtr SvxSlantTabPage::Create( vcl::Window* pWindow, const SfxItemSet* rOutAttrs ) + { + return VclPtr::Create( pWindow, *rOutAttrs ); + } + +- +- + void SvxSlantTabPage::ActivatePage( const SfxItemSet& rSet ) + { + SfxRectangleItem const * pRectItem = NULL; +@@ -620,7 +744,6 @@ SvxPositionSizeTabPage::SvxPositionSizeTabPage(vcl::Window* pParent, const SfxIt + , mfOldWidth(0.0) + , mfOldHeight(0.0) + { +- + get(m_pFlPosition, "FL_POSITION"); + get(m_pMtrPosX, "MTR_FLD_POS_X"); + get(m_pMtrPosY, "MTR_FLD_POS_Y"); +diff --git a/cui/uiconfig/ui/slantcornertabpage.ui b/cui/uiconfig/ui/slantcornertabpage.ui +index 37b7b0e..b3ce646 100644 +--- a/cui/uiconfig/ui/slantcornertabpage.ui ++++ b/cui/uiconfig/ui/slantcornertabpage.ui +@@ -13,12 +13,132 @@ + 1 + 10 + +- ++ + True + False + 6 +- vertical +- 12 ++ 24 ++ 12 ++ ++ ++ True ++ False ++ False ++ 0 ++ none ++ ++ ++ True ++ False ++ 6 ++ 12 ++ ++ ++ True ++ False ++ 12 ++ 6 ++ ++ ++ True ++ False ++ 12 ++ ++ ++ True ++ False ++ _X: ++ True ++ controlx1:0.00cm ++ 0 ++ ++ ++ False ++ True ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ 0.00 ++ 2 ++ ++ ++ False ++ True ++ 1 ++ ++ ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ 12 ++ ++ ++ True ++ False ++ _Y: ++ True ++ controly1:0.00cm ++ 0 ++ ++ ++ False ++ True ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ 0.00 ++ 2 ++ ++ ++ False ++ True ++ 1 ++ ++ ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ Control Point 1 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ 0 ++ 1 ++ ++ + + + True +@@ -32,37 +152,36 @@ + 6 + 12 + +- ++ + True + False +- 12 ++ 12 + + + True + False +- 0 + _Radius: + True + MTR_FLD_RADIUS:0.00cm ++ 0 + + +- False +- True +- 0 ++ 0 ++ 0 + + + + + True +- False ++ True + ++ 0.00 + adjustmentRADIUS + 2 + + +- False +- True +- 1 ++ 1 ++ 0 + + + +@@ -73,8 +192,8 @@ + + True + False +- 0 + Corner Radius ++ 0 + + + +@@ -82,9 +201,8 @@ + + + +- False +- True +- 0 ++ 0 ++ 0 + + + +@@ -100,37 +218,36 @@ + 6 + 12 + +- ++ + True + False +- 12 ++ 12 + + + True + False +- 0 + _Angle: + True + MTR_FLD_ANGLE:0.00degrees ++ 0 + + +- False +- True +- 0 ++ 0 ++ 0 + + + + + True +- False ++ True + ++ 0.00 + adjustmentSLANT + 2 + + +- False +- True +- 1 ++ 1 ++ 0 + + + +@@ -141,8 +258,128 @@ + + True + False +- 0 + Slant ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ False ++ 0 ++ none ++ ++ ++ True ++ False ++ 6 ++ 12 ++ ++ ++ True ++ False ++ 12 ++ 6 ++ ++ ++ True ++ False ++ 12 ++ ++ ++ True ++ False ++ _X: ++ True ++ controlx2:0.00cm ++ 0 ++ ++ ++ False ++ True ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ 0.00 ++ 2 ++ ++ ++ False ++ True ++ 1 ++ ++ ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ 12 ++ ++ ++ True ++ False ++ _Y: ++ True ++ controly2:0.00cm ++ 0 ++ ++ ++ False ++ True ++ 0 ++ ++ ++ ++ ++ True ++ True ++ ++ 0.00 ++ 2 ++ ++ ++ False ++ True ++ 1 ++ ++ ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ ++ ++ ++ ++ True ++ False ++ Control Point 2 ++ 0 + + + +@@ -150,16 +387,19 @@ + + + +- False +- True +- 1 ++ 1 ++ 1 + + + + + ++ ++ + + ++ ++ + + + +@@ -168,4 +408,12 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ + +diff --git a/include/svx/EnhancedCustomShape2d.hxx b/include/svx/EnhancedCustomShape2d.hxx +index b9ed6f2..b1cc1b7 100644 +--- a/include/svx/EnhancedCustomShape2d.hxx ++++ b/include/svx/EnhancedCustomShape2d.hxx +@@ -191,6 +191,7 @@ class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet + SdrObject* CreateObject( bool bLineGeometryNeededOnly ); + void ApplyGluePoints( SdrObject* pObj ); + Rectangle GetTextRect() const; ++ Rectangle GetLogicRect() const { return aLogicRect; } + + sal_uInt32 GetHdlCount() const; + bool GetHandlePosition( const sal_uInt32 nIndex, Point& rReturnPosition ) const; +-- +2.4.3 + diff --git a/SOURCES/0001-implement-equalize-width-and-height-for-impress-draw.patch b/SOURCES/0001-implement-equalize-width-and-height-for-impress-draw.patch new file mode 100644 index 0000000..ac1c0fc --- /dev/null +++ b/SOURCES/0001-implement-equalize-width-and-height-for-impress-draw.patch @@ -0,0 +1,370 @@ +From bdd33fda337d37431e6bffb99fb90416884981c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 25 Jun 2015 10:33:06 +0100 +Subject: [PATCH] implement equalize width and height for impress/draw + +Equalize width/height adjusts width/height of selected objects to the +width/height of the last selected object. + +Change-Id: I7c222a6591112cb674322d310ebd87f04a9198bd +--- + include/svx/svdedtv.hxx | 5 +++ + include/svx/svdstr.hrc | 4 +- + include/svx/svxids.hrc | 2 + + .../org/openoffice/Office/UI/GenericCommands.xcu | 10 +++++ + sd/sdi/_drvwsh.sdi | 10 +++++ + sd/source/ui/view/drviews2.cxx | 13 ++++++ + sd/source/ui/view/drviewsj.cxx | 16 ++++++-- + sd/uiconfig/sdraw/menubar/menubar.xml | 3 ++ + svx/inc/globlmn_tmpl.hrc | 20 +++++++++ + svx/sdi/svx.sdi | 47 ++++++++++++++++++++++ + svx/source/svdraw/svdedtv2.cxx | 38 +++++++++++++++++ + svx/source/svdraw/svdstr.src | 8 ++++ + 12 files changed, 171 insertions(+), 5 deletions(-) + +diff --git a/include/svx/svdedtv.hxx b/include/svx/svdedtv.hxx +index cdc2308..b109e0c 100644 +--- a/include/svx/svdedtv.hxx ++++ b/include/svx/svdedtv.hxx +@@ -272,6 +272,11 @@ public: + // for distribution dialog function + void DistributeMarkedObjects(); + ++ // for setting either the width or height of all selected ++ // objects to the width/height of the last selected object ++ // of the selection ++ void EqualizeMarkedObjects(bool bWidth); ++ + // Decompose marked polypolygon objects into polygons. + // Grouped objects are searched and decomposed, if all member objects are PathObjs. + // bMakeLines=TRUE: all polygones are decomposed into single lines resp. bezier segments +diff --git a/include/svx/svdstr.hrc b/include/svx/svdstr.hrc +index 90ef697..36e8719 100644 +--- a/include/svx/svdstr.hrc ++++ b/include/svx/svdstr.hrc +@@ -241,7 +241,9 @@ + #define STR_EditMergeSubstractPoly (STR_EditBegin + 55) + #define STR_EditMergeIntersectPoly (STR_EditBegin + 56) + #define STR_DistributeMarkedObjects (STR_EditBegin + 57) +-#define STR_EditEnd (STR_DistributeMarkedObjects) ++#define STR_EqualizeWidthMarkedObjects (STR_EditBegin + 58) ++#define STR_EqualizeHeightMarkedObjects (STR_EditBegin + 59) ++#define STR_EditEnd (STR_EqualizeHeightMarkedObjects) + + #define STR_ExchangeBegin (STR_EditEnd+1) + #define STR_ExchangePaste (STR_ExchangeBegin +0) +diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc +index 5b8efbc..67ee3da 100644 +--- a/include/svx/svxids.hrc ++++ b/include/svx/svxids.hrc +@@ -113,6 +113,8 @@ + #define SID_POLY_INTERSECT (SID_SFX_START + 681) + #define SID_POLY_FORMEN (SID_SFX_START + 682) + #define SID_DISTRIBUTE_DLG (SID_SFX_START + 683) ++#define SID_EQUALIZEWIDTH (SID_SFX_START + 684) ++#define SID_EQUALIZEHEIGHT (SID_SFX_START + 685) + + // Basic IDE-Id's + +diff --git a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu +index 1c679bd..d221d56 100644 +--- a/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu ++++ b/officecfg/registry/data/org/openoffice/Office/UI/GenericCommands.xcu +@@ -3472,6 +3472,16 @@ + ~Subtract + + ++ ++ ++ Equalize ~Width ++ ++ ++ ++ ++ Equalize ~Height ++ ++ + + + Superscript +diff --git a/sd/sdi/_drvwsh.sdi b/sd/sdi/_drvwsh.sdi +index 0b5469bf..6b2f17c 100644 +--- a/sd/sdi/_drvwsh.sdi ++++ b/sd/sdi/_drvwsh.sdi +@@ -507,6 +507,16 @@ interface DrawView + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] ++ SID_EQUALIZEWIDTH // ole : no, status : ? ++ [ ++ ExecMethod = FuTemporary ; ++ StateMethod = GetMenuState ; ++ ] ++ SID_EQUALIZEHEIGHT // ole : no, status : ? ++ [ ++ ExecMethod = FuTemporary ; ++ StateMethod = GetMenuState ; ++ ] + SID_CONNECT // ole : no, status : ? + [ + ExecMethod = FuTemporary ; +diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx +index ffbb503..90c3d59 100644 +--- a/sd/source/ui/view/drviews2.cxx ++++ b/sd/source/ui/view/drviews2.cxx +@@ -2272,6 +2272,19 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) + } + break; + ++ case SID_EQUALIZEWIDTH: ++ case SID_EQUALIZEHEIGHT: ++ { ++ // End text edit to avoid conflicts ++ if(mpDrawView->IsTextEdit()) ++ mpDrawView->SdrEndTextEdit(); ++ ++ mpDrawView->EqualizeMarkedObjects(nSId == SID_EQUALIZEWIDTH); ++ Cancel(); ++ rReq.Done (); ++ } ++ break; ++ + case SID_DISMANTLE: // BASIC + { + if ( mpDrawView->IsDismantlePossible(false) ) +diff --git a/sd/source/ui/view/drviewsj.cxx b/sd/source/ui/view/drviewsj.cxx +index 857601f..10a3f5a 100644 +--- a/sd/source/ui/view/drviewsj.cxx ++++ b/sd/source/ui/view/drviewsj.cxx +@@ -284,13 +284,15 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) + rSet.Put(SfxBoolItem(SID_OUTLINE_TEXT_AUTOFIT, bSet)); + } + +- rSet.DisableItem( SID_GROUP ); +- rSet.DisableItem( SID_COMBINE ); ++ rSet.DisableItem(SID_GROUP); ++ rSet.DisableItem(SID_COMBINE); + rSet.DisableItem(SID_DISTRIBUTE_DLG); + rSet.DisableItem(SID_POLY_MERGE); + rSet.DisableItem(SID_POLY_SUBSTRACT); + rSet.DisableItem(SID_POLY_INTERSECT); +- rSet.DisableItem( SID_CONNECT ); ++ rSet.DisableItem(SID_EQUALIZEWIDTH); ++ rSet.DisableItem(SID_EQUALIZEHEIGHT); ++ rSet.DisableItem(SID_CONNECT); + } + // multi-selection + else if( nMarkCount > 1 ) +@@ -377,6 +379,8 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) + rSet.DisableItem(SID_POLY_MERGE); + rSet.DisableItem(SID_POLY_SUBSTRACT); + rSet.DisableItem(SID_POLY_INTERSECT); ++ rSet.DisableItem(SID_EQUALIZEWIDTH); ++ rSet.DisableItem(SID_EQUALIZEHEIGHT); + } + + if (b3dObj || +@@ -438,10 +442,12 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) + } + if ( !mpDrawView->IsCombinePossible(false) ) + { +- rSet.DisableItem( SID_COMBINE ); ++ rSet.DisableItem(SID_COMBINE); + rSet.DisableItem(SID_POLY_MERGE); + rSet.DisableItem(SID_POLY_SUBSTRACT); + rSet.DisableItem(SID_POLY_INTERSECT); ++ rSet.DisableItem(SID_EQUALIZEWIDTH); ++ rSet.DisableItem(SID_EQUALIZEHEIGHT); + } + if ( !mpDrawView->IsCombinePossible(true) ) + { +@@ -501,6 +507,8 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet ) + rSet.DisableItem(SID_POLY_MERGE); + rSet.DisableItem(SID_POLY_SUBSTRACT); + rSet.DisableItem(SID_POLY_INTERSECT); ++ rSet.DisableItem(SID_EQUALIZEWIDTH); ++ rSet.DisableItem(SID_EQUALIZEHEIGHT); + rSet.DisableItem( SID_CONNECT ); + rSet.DisableItem( SID_ANIMATION_EFFECTS ); + rSet.DisableItem( SID_MODIFY_FIELD ); +diff --git a/sd/uiconfig/sdraw/menubar/menubar.xml b/sd/uiconfig/sdraw/menubar/menubar.xml +index f12287b..bc8cfee 100644 +--- a/sd/uiconfig/sdraw/menubar/menubar.xml ++++ b/sd/uiconfig/sdraw/menubar/menubar.xml +@@ -346,6 +346,9 @@ + + + ++ ++ ++ + + + +diff --git a/svx/inc/globlmn_tmpl.hrc b/svx/inc/globlmn_tmpl.hrc +index 9d511c8..8d82489 100644 +--- a/svx/inc/globlmn_tmpl.hrc ++++ b/svx/inc/globlmn_tmpl.hrc +@@ -306,6 +306,20 @@ + Command = ".uno:Intersect" ; \ + Text [ en-US ] = "I~ntersect" ; \ + }; ++#define ITEM_EQUALIZEWIDTH \ ++ MenuItem\ ++ {\ ++ Identifier = SID_EQUALIZEWIDTH ; \ ++ Command = ".uno:EqualizeWidth" ; \ ++ Text [ en-US ] = "Equalize ~Width" ; \ ++ }; ++#define ITEM_EQUALIZEHEIGHT \ ++ MenuItem\ ++ {\ ++ Identifier = SID_EQUALIZEHEIGHT ; \ ++ Command = ".uno:EqualizeHeight" ; \ ++ Text [ en-US ] = "Equalize ~Height" ; \ ++ }; + + #define MNSUB_FORMEN \ + MenuItem \ +@@ -320,6 +334,12 @@ + ITEM_POLY_MERGE \ + ITEM_POLY_SUBSTRACT \ + ITEM_POLY_INTERSECT \ ++ MenuItem \ ++ { \ ++ Separator = TRUE; \ ++ }; \ ++ ITEM_EQUALIZEWIDTH \ ++ ITEM_EQUALIZEHEIGHT \ + };\ + };\ + }; +diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi +index 941f3e8..b301c58 100644 +--- a/svx/sdi/svx.sdi ++++ b/svx/sdi/svx.sdi +@@ -11100,6 +11100,53 @@ SfxVoidItem Substract SID_POLY_SUBSTRACT + GroupId = GID_MODIFY; + ] + ++SfxVoidItem EqualizeWidth SID_EQUALIZEWIDTH ++() ++[ ++ /* flags: */ ++ AutoUpdate = FALSE, ++ Cachable = Cachable, ++ FastCall = FALSE, ++ HasCoreId = FALSE, ++ HasDialog = FALSE, ++ ReadOnlyDoc = FALSE, ++ Toggle = FALSE, ++ Container = FALSE, ++ RecordAbsolute = FALSE, ++ RecordPerSet; ++ Synchron; ++ ++ /* config: */ ++ AccelConfig = TRUE, ++ MenuConfig = TRUE, ++ StatusBarConfig = FALSE, ++ ToolBoxConfig = TRUE, ++ GroupId = GID_MODIFY; ++] ++ ++SfxVoidItem EqualizeHeight SID_EQUALIZEHEIGHT ++() ++[ ++ /* flags: */ ++ AutoUpdate = FALSE, ++ Cachable = Cachable, ++ FastCall = FALSE, ++ HasCoreId = FALSE, ++ HasDialog = FALSE, ++ ReadOnlyDoc = FALSE, ++ Toggle = FALSE, ++ Container = FALSE, ++ RecordAbsolute = FALSE, ++ RecordPerSet; ++ Synchron; ++ ++ /* config: */ ++ AccelConfig = TRUE, ++ MenuConfig = TRUE, ++ StatusBarConfig = FALSE, ++ ToolBoxConfig = TRUE, ++ GroupId = GID_MODIFY; ++] + + SfxBoolItem SuperScript SID_SET_SUPER_SCRIPT + +diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx +index 0a60082..ad7dd3f 100644 +--- a/svx/source/svdraw/svdedtv2.cxx ++++ b/svx/source/svdraw/svdedtv2.cxx +@@ -1173,6 +1173,44 @@ void SdrEditView::MergeMarkedObjects(SdrMergeMode eMode) + } + } + ++void SdrEditView::EqualizeMarkedObjects(bool bWidth) ++{ ++ const SdrMarkList& rMarkList = GetMarkedObjectList(); ++ size_t nMarked = rMarkList.GetMarkCount(); ++ ++ if (nMarked < 2) ++ return; ++ ++ SdrObject* pLastSelectedObj = rMarkList.GetMark(nMarked-1)->GetMarkedSdrObj(); ++ Size aLastRectSize(pLastSelectedObj->GetLogicRect().GetSize()); ++ ++ const bool bUndo = IsUndoEnabled(); ++ ++ if (bUndo) ++ BegUndo(); ++ ++ for (size_t a = 0; a < nMarked-1; ++a) ++ { ++ SdrMark* pM = rMarkList.GetMark(a); ++ SdrObject* pObj = pM->GetMarkedSdrObj(); ++ Rectangle aLogicRect(pObj->GetLogicRect()); ++ Size aLogicRectSize(aLogicRect.GetSize()); ++ if (bWidth) ++ aLogicRectSize.Width() = aLastRectSize.Width(); ++ else ++ aLogicRectSize.Height() = aLastRectSize.Height(); ++ aLogicRect.SetSize(aLogicRectSize); ++ pObj->SetLogicRect(aLogicRect); ++ } ++ ++ SetUndoComment( ++ ImpGetResStr(bWidth ? STR_EqualizeWidthMarkedObjects : STR_EqualizeHeightMarkedObjects), ++ rMarkList.GetMarkDescription()); ++ ++ if (bUndo) ++ EndUndo(); ++} ++ + void SdrEditView::CombineMarkedObjects(bool bNoPolyPoly) + { + // #105899# Start of Combine-Undo put to front, else ConvertMarkedToPolyObj would +diff --git a/svx/source/svdraw/svdstr.src b/svx/source/svdraw/svdstr.src +index 364749a..6dc4420 100644 +--- a/svx/source/svdraw/svdstr.src ++++ b/svx/source/svdraw/svdstr.src +@@ -823,6 +823,14 @@ String STR_DistributeMarkedObjects + { + Text [ en-US ] = "Distribute selected objects"; + }; ++String STR_EqualizeWidthMarkedObjects ++{ ++ Text [ en-US ] = "Equalize Width %1"; ++}; ++String STR_EqualizeHeightMarkedObjects ++{ ++ Text [ en-US ] = "Equalize Height %1"; ++}; + String STR_EditCombine_OnePoly + { + Text [ en-US ] = "Combine %1" ; +-- +2.4.0 + diff --git a/SOURCES/0001-implement-save-slide-background-for-impress.patch b/SOURCES/0001-implement-save-slide-background-for-impress.patch new file mode 100644 index 0000000..d443779 --- /dev/null +++ b/SOURCES/0001-implement-save-slide-background-for-impress.patch @@ -0,0 +1,359 @@ +From 402f64fc8464366015259d44e238a77cb7d9d776 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 30 Sep 2015 13:30:36 +0100 +Subject: [PATCH] implement save slide background for impress + +to go along with the existing "set background", +same sort of thing as the competitor's effort + +(cherry picked from commit ed25a000ab67324075e68d9a7f3ca657b4e6a573) + +Change-Id: I2a1106771ead2cd926f3d631850447499340697c +--- + sd/inc/app.hrc | 3 +- + sd/inc/sdcommands.h | 1 + + sd/sdi/_drvwsh.sdi | 5 +++ + sd/sdi/sdraw.sdi | 24 +++++++++++ + sd/source/ui/app/menuids_tmpl.src | 11 ++++- + sd/source/ui/func/fupage.cxx | 85 +++++++++++++++++++++++--------------- + sd/source/ui/inc/DrawViewShell.hxx | 4 ++ + sd/source/ui/view/drviews2.cxx | 1 + + sd/source/ui/view/drviews7.cxx | 25 ++++++++++- + 9 files changed, 122 insertions(+), 37 deletions(-) + +diff --git a/sd/inc/app.hrc b/sd/inc/app.hrc +index 4f3d82e..956c7d4 100644 +--- a/sd/inc/app.hrc ++++ b/sd/inc/app.hrc +@@ -421,7 +421,8 @@ + #define SID_SLIDE_SORTER_MULTI_PANE_GUI (SID_SD_START+421) + + #define SID_SELECT_BACKGROUND (SID_SD_START+422) +- ++#define SID_SAVE_BACKGROUND (SID_SD_START+423) ++ // FREE + // Slots for the tool pane popup + #define SID_TP_APPLY_TO_ALL_SLIDES (SID_SD_START+425) + #define SID_TP_APPLY_TO_SELECTED_SLIDES (SID_SD_START+426) +diff --git a/sd/inc/sdcommands.h b/sd/inc/sdcommands.h +index 2f4bf56..1d3502f 100644 +--- a/sd/inc/sdcommands.h ++++ b/sd/inc/sdcommands.h +@@ -90,6 +90,7 @@ + #define CMD_SID_DELETE_MASTER_PAGE ".uno:DeleteMasterPage" + #define CMD_SID_RENAME_MASTER_PAGE ".uno:RenameMasterPage" + #define CMD_SID_SELECT_BACKGROUND ".uno:SelectBackground" ++#define CMD_SID_SAVE_BACKGROUND ".uno:SaveBackground" + #define CMD_SID_DISPLAY_MASTER_BACKGROUND ".uno:DisplayMasterBackground" + #define CMD_SID_DISPLAY_MASTER_OBJECTS ".uno:DisplayMasterObjects" + #define CMD_SID_TABLE_DISTRIBUTE_COLUMNS ".uno:DistributeColumns" +diff --git a/sd/sdi/_drvwsh.sdi b/sd/sdi/_drvwsh.sdi +index 263a8ed..28ee22c 100644 +--- a/sd/sdi/_drvwsh.sdi ++++ b/sd/sdi/_drvwsh.sdi +@@ -2662,6 +2662,11 @@ interface DrawView + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] ++ SID_SAVE_BACKGROUND ++ [ ++ ExecMethod = FuTemporary ; ++ StateMethod = GetMenuState ; ++ ] + SID_DISPLAY_MASTER_BACKGROUND + [ + ExecMethod = FuTemporary ; +diff --git a/sd/sdi/sdraw.sdi b/sd/sdi/sdraw.sdi +index 7297c1f..d2d5d28 100644 +--- a/sd/sdi/sdraw.sdi ++++ b/sd/sdi/sdraw.sdi +@@ -6439,6 +6439,30 @@ SfxVoidItem SelectBackground SID_SELECT_BACKGROUND + GroupId = GID_OPTIONS; + ] + ++SfxVoidItem SaveBackground SID_SAVE_BACKGROUND ++() ++[ ++ /* flags: */ ++ AutoUpdate = FALSE, ++ Cachable = Cachable, ++ FastCall = FALSE, ++ HasCoreId = FALSE, ++ HasDialog = TRUE, ++ ReadOnlyDoc = TRUE, ++ Toggle = FALSE, ++ Container = FALSE, ++ RecordAbsolute = FALSE, ++ RecordPerSet; ++ Synchron; ++ ++ /* config: */ ++ AccelConfig = FALSE, ++ MenuConfig = FALSE, ++ StatusBarConfig = FALSE, ++ ToolBoxConfig = FALSE, ++ GroupId = GID_OPTIONS; ++] ++ + SfxBoolItem DisplayMasterBackground SID_DISPLAY_MASTER_BACKGROUND + [ + /* flags: */ +diff --git a/sd/source/ui/app/menuids_tmpl.src b/sd/source/ui/app/menuids_tmpl.src +index bf30830..6917de2 100644 +--- a/sd/source/ui/app/menuids_tmpl.src ++++ b/sd/source/ui/app/menuids_tmpl.src +@@ -138,6 +138,13 @@ + HelpId = CMD_SID_SELECT_BACKGROUND ; \ + Text [ en-US ] = "Set Background Image..." ; \ + }; ++#define MN_SAVE_BACKGROUND \ ++ MenuItem\ ++ {\ ++ Identifier = SID_SAVE_BACKGROUND ; \ ++ HelpId = CMD_SID_SAVE_BACKGROUND ; \ ++ Text [ en-US ] = "Save Background Image..." ; \ ++ }; + #define MN_DISPLAY_MASTER_BACKGROUND \ + MenuItem\ + {\ +@@ -169,6 +176,7 @@ + MN_SELECT_BACKGROUND\ + MN_PAGE_DESIGN\ + MN_RENAME_PAGE\ ++ MN_SAVE_BACKGROUND\ + };\ + };\ + Text [ en-US ] = "Pag~e" ; \ +@@ -200,7 +208,8 @@ + MN_DISPLAY_MASTER_OBJECTS\ + };\ + };\ +- }; ++ }; \ ++ MN_SAVE_BACKGROUND + + // Layer + #define MN_RENAME_LAYER \ +diff --git a/sd/source/ui/func/fupage.cxx b/sd/source/ui/func/fupage.cxx +index 83146e4..d3a053f 100644 +--- a/sd/source/ui/func/fupage.cxx ++++ b/sd/source/ui/func/fupage.cxx +@@ -36,6 +36,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -164,6 +165,41 @@ void FuPage::Deactivate() + { + } + ++void MergePageBackgroundFilling(SdPage *pPage, SdStyleSheet *pStyleSheet, bool bMasterPage, SfxItemSet& rMergedAttr) ++{ ++ if (bMasterPage) ++ { ++ if (pStyleSheet) ++ mergeItemSetsImpl(rMergedAttr, pStyleSheet->GetItemSet()); ++ } ++ else ++ { ++ // Only this page, get attributes for background fill ++ const SfxItemSet& rBackgroundAttributes = pPage->getSdrPageProperties().GetItemSet(); ++ ++ if(drawing::FillStyle_NONE != static_cast(rBackgroundAttributes.Get(XATTR_FILLSTYLE)).GetValue()) ++ { ++ // page attributes are used, take them ++ rMergedAttr.Put(rBackgroundAttributes); ++ } ++ else ++ { ++ if(pStyleSheet ++ && drawing::FillStyle_NONE != static_cast(pStyleSheet->GetItemSet().Get(XATTR_FILLSTYLE)).GetValue()) ++ { ++ // if the page has no fill style, use the settings from the ++ // background stylesheet (if used) ++ mergeItemSetsImpl(rMergedAttr, pStyleSheet->GetItemSet()); ++ } ++ else ++ { ++ // no fill style from page, start with no fill style ++ rMergedAttr.Put(XFillStyleItem(drawing::FillStyle_NONE)); ++ } ++ } ++ } ++} ++ + const SfxItemSet* FuPage::ExecuteDialog( vcl::Window* pParent ) + { + if (!mpDrawViewShell) +@@ -247,44 +283,27 @@ const SfxItemSet* FuPage::ExecuteDialog( vcl::Window* pParent ) + // merge page background filling to the dialogs input set + if( mbDisplayBackgroundTabPage ) + { +- if( mbMasterPage ) +- { +- if(pStyleSheet) +- mergeItemSetsImpl( aMergedAttr, pStyleSheet->GetItemSet() ); +- } +- else +- { +- // Only this page, get attributes for background fill +- const SfxItemSet& rBackgroundAttributes = mpPage->getSdrPageProperties().GetItemSet(); +- +- if(drawing::FillStyle_NONE != static_cast(rBackgroundAttributes.Get(XATTR_FILLSTYLE)).GetValue()) +- { +- // page attributes are used, take them +- aMergedAttr.Put(rBackgroundAttributes); +- } +- else +- { +- if(pStyleSheet +- && drawing::FillStyle_NONE != static_cast(pStyleSheet->GetItemSet().Get(XATTR_FILLSTYLE)).GetValue()) +- { +- // if the page has no fill style, use the settings from the +- // background stylesheet (if used) +- mergeItemSetsImpl(aMergedAttr, pStyleSheet->GetItemSet()); +- } +- else +- { +- // no fill style from page, start with no fill style +- aMergedAttr.Put(XFillStyleItem(drawing::FillStyle_NONE)); +- } +- } +- } ++ MergePageBackgroundFilling(mpPage, pStyleSheet, mbMasterPage, aMergedAttr); + } + + boost::scoped_ptr< SfxItemSet > pTempSet; + +- if( GetSlotID() == SID_SELECT_BACKGROUND ) ++ const sal_uInt16 nId = GetSlotID(); ++ if (nId == SID_SAVE_BACKGROUND) ++ { ++ const XFillStyleItem& rStyleItem = ++ static_cast(aMergedAttr.Get(XATTR_FILLSTYLE)); ++ if (drawing::FillStyle_BITMAP == (drawing::FillStyle)rStyleItem.GetValue()) ++ { ++ const XFillBitmapItem& rBitmap = ++ static_cast(aMergedAttr.Get(XATTR_FILLBITMAP)); ++ const GraphicObject& rGraphicObj = rBitmap.GetGraphicObject(); ++ GraphicHelper::ExportGraphic(rGraphicObj.GetGraphic(), ""); ++ } ++ } ++ else if (nId == SID_SELECT_BACKGROUND) + { +- SvxOpenGraphicDialog aDlg(SdResId(STR_SET_BACKGROUND_PICTURE)); ++ SvxOpenGraphicDialog aDlg(SdResId(STR_SET_BACKGROUND_PICTURE)); + + if( aDlg.Execute() == GRFILTER_OK ) + { +diff --git a/sd/source/ui/inc/DrawViewShell.hxx b/sd/source/ui/inc/DrawViewShell.hxx +index 405e7af..5ec628c 100644 +--- a/sd/source/ui/inc/DrawViewShell.hxx ++++ b/sd/source/ui/inc/DrawViewShell.hxx +@@ -33,6 +33,7 @@ + + class Outliner; + class SdPage; ++class SdStyleSheet; + class SdrExternalToolEdit; + class DrawDocShell; + class TabBar; +@@ -509,6 +510,9 @@ private: + std::vector> m_ExternalEdits; + }; + ++ /// Merge the background properties together and deposit the result in rMergeAttr ++ void MergePageBackgroundFilling(SdPage *pPage, SdStyleSheet *pStyleSheet, bool bMasterPage, SfxItemSet& rMergedAttr); ++ + } // end of namespace sd + + #endif +diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx +index e9c5f00..5c26c55 100644 +--- a/sd/source/ui/view/drviews2.cxx ++++ b/sd/source/ui/view/drviews2.cxx +@@ -1190,6 +1190,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) + break; + + case SID_SELECT_BACKGROUND: ++ case SID_SAVE_BACKGROUND: + case SID_PAGESETUP: // BASIC ?? + { + SetCurrentFunction( FuPage::Create( this, GetActiveWindow(), mpDrawView, GetDoc(), rReq ) ); +diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx +index 8b6d968..fba8bc1 100644 +--- a/sd/source/ui/view/drviews7.cxx ++++ b/sd/source/ui/view/drviews7.cxx +@@ -83,6 +83,7 @@ + #include "fuediglu.hxx" + #include "fubullet.hxx" + #include "fuformatpaintbrush.hxx" ++#include "stlsheet.hxx" + + #include + +@@ -714,6 +715,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) + { + rSet.DisableItem(SID_PRESENTATION_LAYOUT); + rSet.DisableItem(SID_SELECT_BACKGROUND); ++ rSet.DisableItem(SID_SAVE_BACKGROUND); + } + + if (mePageKind == PK_NOTES) +@@ -730,6 +732,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) + rSet.DisableItem(SID_MODIFYPAGE); + + rSet.DisableItem(SID_SELECT_BACKGROUND); ++ rSet.DisableItem(SID_SAVE_BACKGROUND); + rSet.DisableItem(SID_INSERTLAYER); + rSet.DisableItem(SID_LAYERMODE); + rSet.DisableItem(SID_INSERTFILE); +@@ -750,6 +753,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) + rSet.DisableItem(SID_INSERTFILE); + rSet.DisableItem(SID_PAGEMODE); + rSet.DisableItem(SID_SELECT_BACKGROUND); ++ rSet.DisableItem(SID_SAVE_BACKGROUND); + } + else + { +@@ -1646,8 +1650,7 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) + || rSet.GetItemState(SID_DISPLAY_MASTER_OBJECTS) == SfxItemState::DEFAULT) + { + SdPage* pPage = GetActualPage(); +- if (pPage != NULL +- && GetDoc() != NULL) ++ if (pPage != NULL && GetDoc() != NULL) + { + SetOfByte aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers(); + SdrLayerAdmin& rLayerAdmin = GetDoc()->GetLayerAdmin(); +@@ -1668,6 +1671,24 @@ void DrawViewShell::GetMenuState( SfxItemSet &rSet ) + } + #endif + ++ if (rSet.GetItemState(SID_SAVE_BACKGROUND) == SfxItemState::DEFAULT) ++ { ++ bool bDisableSaveBackground = true; ++ SdPage* pPage = GetActualPage(); ++ if (pPage != NULL && GetDoc() != NULL) ++ { ++ SfxItemSet aMergedAttr(GetDoc()->GetPool(), XATTR_FILL_FIRST, XATTR_FILL_LAST, 0); ++ SdStyleSheet* pStyleSheet = pPage->getPresentationStyle(HID_PSEUDOSHEET_BACKGROUND); ++ MergePageBackgroundFilling(pPage, pStyleSheet, meEditMode == EM_MASTERPAGE, aMergedAttr); ++ if (drawing::FillStyle_BITMAP == static_cast(aMergedAttr.Get(XATTR_FILLSTYLE)).GetValue()) ++ { ++ bDisableSaveBackground = false; ++ } ++ } ++ if (bDisableSaveBackground) ++ rSet.DisableItem(SID_SAVE_BACKGROUND); ++ } ++ + GetModeSwitchingMenuState (rSet); + } + +-- +2.4.3 + diff --git a/SOURCES/0001-implement-undo-for-equalize-marked-objects.patch b/SOURCES/0001-implement-undo-for-equalize-marked-objects.patch new file mode 100644 index 0000000..60d4121 --- /dev/null +++ b/SOURCES/0001-implement-undo-for-equalize-marked-objects.patch @@ -0,0 +1,26 @@ +From 4c8197bc270ec65c147af3388e35403aa77fd02f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 28 Aug 2015 13:08:44 +0100 +Subject: [PATCH] implement undo for equalize-marked-objects + +Change-Id: I245e08674b52c2a5648e9d7762101b8057fd30e9 +--- + svx/source/svdraw/svdedtv2.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx +index 75c884c..719355d 100644 +--- a/svx/source/svdraw/svdedtv2.cxx ++++ b/svx/source/svdraw/svdedtv2.cxx +@@ -1200,6 +1200,8 @@ void SdrEditView::EqualizeMarkedObjects(bool bWidth) + else + aLogicRectSize.Height() = aLastRectSize.Height(); + aLogicRect.SetSize(aLogicRectSize); ++ if (bUndo) ++ AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); + pObj->SetLogicRect(aLogicRect); + } + +-- +2.4.0 + diff --git a/SOURCES/0001-implement-undo-of-delete-impress-cell-contents.patch b/SOURCES/0001-implement-undo-of-delete-impress-cell-contents.patch new file mode 100644 index 0000000..287a0cf --- /dev/null +++ b/SOURCES/0001-implement-undo-of-delete-impress-cell-contents.patch @@ -0,0 +1,79 @@ +From 35a3fb2ca34b30a1bdaf64f0091fcd42af6bfd2c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 1 Sep 2015 16:32:15 +0100 +Subject: [PATCH] implement undo of delete impress cell contents + +Change-Id: I7aa99f3a6668e66b8d02e20b7ea1cf0862e5d760 +(cherry picked from commit d38e4b2ee73ad38881465f9f97eb8d8397ee98ff) +--- + include/svx/svdstr.hrc | 1 + + svx/source/svdraw/svdstr.src | 5 +++++ + svx/source/table/tablecontroller.cxx | 15 +++++++++++++-- + 3 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/include/svx/svdstr.hrc b/include/svx/svdstr.hrc +index 90ef697..f45b55f 100644 +--- a/include/svx/svdstr.hrc ++++ b/include/svx/svdstr.hrc +@@ -711,5 +711,6 @@ + #define STR_TABLE_STYLE (SIP_Begin + 274) + #define STR_TABLE_STYLE_SETTINGS (SIP_Begin + 275) + #define SIP_SA_CROP_MARKERS (SIP_Begin + 276) ++#define STR_TABLE_DELETE_CELL_CONTENTS (SIP_Begin + 277) + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/svx/source/svdraw/svdstr.src b/svx/source/svdraw/svdstr.src +index 364749a..c7977c1 100644 +--- a/svx/source/svdraw/svdstr.src ++++ b/svx/source/svdraw/svdstr.src +@@ -2770,6 +2770,11 @@ String STR_TABLE_DISTRIBUTE_COLUMNS + Text [ en-US ] = "Distribute columns" ; + }; + ++String STR_TABLE_DELETE_CELL_CONTENTS ++{ ++ Text [ en-US ] = "Delete cell contents" ; ++}; ++ + String STR_TABLE_STYLE + { + Text [ en-US ] = "Table style" ; +diff --git a/svx/source/table/tablecontroller.cxx b/svx/source/table/tablecontroller.cxx +index 64b40da..6a8bd3f 100644 +--- a/svx/source/table/tablecontroller.cxx ++++ b/svx/source/table/tablecontroller.cxx +@@ -1331,6 +1331,10 @@ bool SvxTableController::DeleteMarked() + { + if( mxTable.is() ) + { ++ const bool bUndo = mpModel && mpModel->IsUndoEnabled(); ++ if (bUndo) ++ mpModel->BegUndo(ImpGetResStr(STR_TABLE_DELETE_CELL_CONTENTS)); ++ + CellPos aStart, aEnd; + getSelectedCells( aStart, aEnd ); + for( sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++ ) +@@ -1338,11 +1342,18 @@ bool SvxTableController::DeleteMarked() + for( sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++ ) + { + CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) ); +- if( xCell.is() ) +- xCell->SetOutlinerParaObject( 0 ); ++ if (xCell.is() && xCell->hasText()) ++ { ++ if (bUndo) ++ xCell->AddUndo(); ++ xCell->SetOutlinerParaObject(0); ++ } + } + } + ++ if (bUndo) ++ mpModel->EndUndo(); ++ + UpdateTableShape(); + return true; + } +-- +2.4.0 + diff --git a/SOURCES/0001-impress-s-AnnotationWindow-is-the-only-user-of-WB_NE.patch b/SOURCES/0001-impress-s-AnnotationWindow-is-the-only-user-of-WB_NE.patch new file mode 100644 index 0000000..735fe71 --- /dev/null +++ b/SOURCES/0001-impress-s-AnnotationWindow-is-the-only-user-of-WB_NE.patch @@ -0,0 +1,49 @@ +From 94341df754fddacefb01638e5c544a5ba66de750 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 16 Dec 2015 21:26:15 +0000 +Subject: [PATCH] impress's AnnotationWindow is the only user of WB_NEEDSFOCUS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Here it is creating a toplevel floating system window which needs special +hackery to function. + +Instead convert it to a non-system window which means that it is in reality +only a vcl construct. The small downside is that it is now unable to leave the +confines of the toplevel system window in which it lives. Upside is that +all the special hackery related to it which generally doesn't work half the time +in various window managers and now in wayland can go away. + +Change-Id: I7ad7c35091086f7671ff4a178c7fa04202c20e09 +Reviewed-on: https://gerrit.libreoffice.org/20745 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +--- + sd/source/ui/annotations/annotationwindow.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sd/source/ui/annotations/annotationwindow.cxx b/sd/source/ui/annotations/annotationwindow.cxx +index bcad03d..c307f1d 100644 +--- a/sd/source/ui/annotations/annotationwindow.cxx ++++ b/sd/source/ui/annotations/annotationwindow.cxx +@@ -273,7 +273,7 @@ Selection AnnotationTextWindow::GetSurroundingTextSelection() const + /************** AnnotationWindow***********************************++*/ + + AnnotationWindow::AnnotationWindow( AnnotationManagerImpl& rManager, DrawDocShell* pDocShell, vcl::Window* pParent ) +-: FloatingWindow(pParent, WB_SYSTEMWINDOW|WB_BORDER|WB_NEEDSFOCUS) ++: FloatingWindow(pParent, WB_BORDER) + , mrManager( rManager ) + , mpDocShell( pDocShell ) + , mpView( pDocShell->GetViewShell()->GetView() ) +@@ -287,6 +287,7 @@ AnnotationWindow::AnnotationWindow( AnnotationManagerImpl& rManager, DrawDocShel + , mpTextWindow(0) + , mpMeta(0) + { ++ EnableAlwaysOnTop(); + } + + AnnotationWindow::~AnnotationWindow() +-- +2.5.0 + diff --git a/SOURCES/0001-improve-perf.-of-VCL-event-dispatch.patch b/SOURCES/0001-improve-perf.-of-VCL-event-dispatch.patch new file mode 100644 index 0000000..2583609 --- /dev/null +++ b/SOURCES/0001-improve-perf.-of-VCL-event-dispatch.patch @@ -0,0 +1,118 @@ +From 12776a97a32449f5c0fc6de735c29fc30c0d7d14 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 10 May 2016 09:00:20 +0200 +Subject: [PATCH] improve perf. of VCL event dispatch + +Change-Id: I5052f0c3e2c8739b336da52ef9590e5008255247 +--- + vcl/inc/window.h | 4 +++- + vcl/source/window/event.cxx | 39 ++++++++++++++++++++++++++++++++++++--- + vcl/source/window/window.cxx | 1 + + 3 files changed, 40 insertions(+), 4 deletions(-) + +diff --git a/vcl/inc/window.h b/vcl/inc/window.h +index 67d5f94..60f7e82 100644 +--- a/vcl/inc/window.h ++++ b/vcl/inc/window.h +@@ -224,7 +224,9 @@ public: + VclPtr mpNextOverlap; + VclPtr mpLastFocusWindow; + VclPtr mpDlgCtrlDownWindow; +- VclEventListeners maEventListeners; ++ std::vector> maEventListeners; ++ int mnEventListenersIteratingCount; ++ std::set> maEventListenersDeleted; + VclEventListeners maChildEventListeners; + + // The canvas interface for this VCL window. Is persistent after the first GetCanvas() call +diff --git a/vcl/source/window/event.cxx b/vcl/source/window/event.cxx +index 35c3e38..cbd5b23 100644 +--- a/vcl/source/window/event.cxx ++++ b/vcl/source/window/event.cxx +@@ -18,6 +18,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -27,6 +28,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -212,7 +215,32 @@ void Window::CallEventListeners( sal_uLong nEvent, void* pData ) + if ( aDelData.IsDead() ) + return; + +- mpWindowImpl->maEventListeners.Call( &aEvent ); ++ if (!mpWindowImpl->maEventListeners.empty()) ++ { ++ // Copy the list, because this can be destroyed when calling a Link... ++ std::vector> aCopy( mpWindowImpl->maEventListeners ); ++ // we use an iterating counter/flag and a set of deleted Link's to avoid O(n^2) behaviour ++ mpWindowImpl->mnEventListenersIteratingCount++; ++ auto& rWindowImpl = *mpWindowImpl; ++ comphelper::ScopeGuard aGuard( ++ [&rWindowImpl, &aDelData]() ++ { ++ if (!aDelData.IsDead()) ++ { ++ rWindowImpl.mnEventListenersIteratingCount--; ++ if (rWindowImpl.mnEventListenersIteratingCount == 0) ++ rWindowImpl.maEventListenersDeleted.clear(); ++ } ++ } ++ ); ++ for ( Link<>& rLink : aCopy ) ++ { ++ if (aDelData.IsDead()) break; ++ // check this hasn't been removed in some re-enterancy scenario fdo#47368 ++ if( rWindowImpl.maEventListenersDeleted.find(rLink) == rWindowImpl.maEventListenersDeleted.end() ) ++ rLink.Call( &aEvent ); ++ } ++ } + + if ( aDelData.IsDead() ) + return; +@@ -245,13 +273,18 @@ void Window::FireVclEvent( VclSimpleEvent* pEvent ) + + void Window::AddEventListener( const Link<>& rEventListener ) + { +- mpWindowImpl->maEventListeners.addListener( rEventListener ); ++ mpWindowImpl->maEventListeners.push_back( rEventListener ); + } + + void Window::RemoveEventListener( const Link<>& rEventListener ) + { + if (mpWindowImpl) +- mpWindowImpl->maEventListeners.removeListener( rEventListener ); ++ { ++ auto& rListeners = mpWindowImpl->maEventListeners; ++ rListeners.erase( std::remove(rListeners.begin(), rListeners.end(), rEventListener ), rListeners.end() ); ++ if (mpWindowImpl->mnEventListenersIteratingCount) ++ mpWindowImpl->maEventListenersDeleted.insert(rEventListener); ++ } + } + + void Window::AddChildEventListener( const Link<>& rEventListener ) +diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx +index e8d2b96..cbfc4cd 100644 +--- a/vcl/source/window/window.cxx ++++ b/vcl/source/window/window.cxx +@@ -630,6 +630,7 @@ WindowImpl::WindowImpl( WindowType nType ) + mpLastFocusWindow = NULL; // window for focus restore + mpDlgCtrlDownWindow = NULL; // window for dialog control + mpFirstDel = NULL; // Dtor notification list ++ mnEventListenersIteratingCount = 0; + mpUserData = NULL; // user data + mpCursor = NULL; // cursor + mpControlFont = NULL; // font properties +-- +2.7.3 + diff --git a/SOURCES/0001-limit-WEBSERVICE-to-http-s-protocols.patch b/SOURCES/0001-limit-WEBSERVICE-to-http-s-protocols.patch new file mode 100644 index 0000000..ea4c862 --- /dev/null +++ b/SOURCES/0001-limit-WEBSERVICE-to-http-s-protocols.patch @@ -0,0 +1,922 @@ +From f045768636399e028963a259dc074afcaa4bef2e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 10 Jan 2018 14:27:35 +0000 +Subject: [PATCH] limit WEBSERVICE to http[s] protocols +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +and like excel... + +'For protocols that aren’t supported, such as ftp:// or file://, WEBSERVICE +returns the #VALUE! error value.' + +Reviewed-on: https://gerrit.libreoffice.org/47776 +Tested-by: Jenkins +Reviewed-by: Markus Mohrhard + +Better handle ScDde formulas with missing dde-link entries + +typically each ScDde formula has a matching table:dde-link which +results in a ScDdeLink getting inserted during the load. If that dde-link +is missing then no ScDdeLink exists and ScDde() will create a new one without +cached content. So detect that ScDde is used in the freshing loaded ods +and defer fetching new content until the right time. + +only call GetHasMacroFunc to set SetHasMacroFunc + +and bHasMacroFunc is not accessed any other way, so this is an oxbow + +Reviewed-on: https://gerrit.libreoffice.org/47757 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit b0597ba5d745974fce752e1b677451a19350d351) +Reviewed-on: https://gerrit.libreoffice.org/47818 +Reviewed-by: Eike Rathke + +handle ocWebservice similarly to ocDde + +might have too much in here seeing as we don't need to worry about +ocWebservice calling into itself + +Reviewed-on: https://gerrit.libreoffice.org/47819 +Tested-by: Jenkins +Reviewed-by: Eike Rathke + +CheckLinkFormulaNeedingCheck() for .xls and .xlsx formula cells + + This is a combination of 3 commits. + +Move implementation to CheckLinkFormulaNeedingCheck() for further reuse + +(cherry picked from commit 55e484c7bcd3ef218e08d3fd93f97bf98fd8cb7f) + +CheckLinkFormulaNeedingCheck() for .xlsx cell formulas + +(cherry picked from commit f96dbc3dd9c33202f75e29ef49d962386595995d) + +CheckLinkFormulaNeedingCheck() for .xls cell formulas + +(cherry picked from commit 6bc48275558c3f76c4da25eb8af3c48583ac5599) + +a6dd195f7eb4d43483e87eeca59f651e7bf2dcb8 +2587fbc4fec39b6f2c8e733331815a2953dee308 + +Reviewed-on: https://gerrit.libreoffice.org/48143 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara + +CheckLinkFormulaNeedingCheck() for conditional format expressions + + This is a combination of 4 commits. + +Prepare CheckLinkFormulaNeedingCheck() to use either RPN or tokenized code + +Conditional format formulas aren't finally compiled until needed +so the check will have to operate on the tokenized expression +instead of RPN code. + +(cherry picked from commit faa0305ba3d0dc698fce4915d4f3a1fb52422380) + +CheckLinkFormulaNeedingCheck() for .ods conditional format expressions + +(cherry picked from commit 2930ba2ac5d9423f2848b968edcd8ddc71966186) + +CheckLinkFormulaNeedingCheck() for .xlsx conditional format expressions + +(cherry picked from commit fef24d9f999ee54d7936900485d97ff26656f517) + +CheckLinkFormulaNeedingCheck() for .xls conditional format expressions + +(cherry picked from commit af2a2a0c72db312902e466c36697b5c198041e82) + +45eb1ab5efa0ec9da2663f20427d2474ce300826 +31ede1a23223a798141a0891deeabd8cf88fff58 +afa112cc591b411d80ead48bf726788d361f6eb3 + +Reviewed-on: https://gerrit.libreoffice.org/48719 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara + +CheckLinkFormulaNeedingCheck() for named expressions + + This is a combination of 3 commits. + +CheckLinkFormulaNeedingCheck() for .ods named expressions + +This is specifically necessary for named expressions that are used +in conditional format formulas, for which RPN is generated at a +later stage, not during import. + +(cherry picked from commit eae9648e99be53ba441d9d8207aac6f3ce211ef2) + +CheckLinkFormulaNeedingCheck() for .xls named expressions + +(cherry picked from commit 8512f13c42ae3fbb287a555616fe10ff04295616) + +CheckLinkFormulaNeedingCheck() for .xlsx named expressions + +(cherry picked from commit a1f933ee2b9e23a505d937035821e9571cf4119c) + + Conflicts: + sc/source/filter/oox/defnamesbuffer.cxx + +e03cb5767c34f8157a492a6d6c3b0700d065052d +217c89822ab477a6c383d170ae739e44efd10fa3 + +Change-Id: I0e9c6fd3426fad56a199eafac48de9b0f23914b3 +016b53288076d83dd49e92e245346a5f7f560522 +0145f38cc1c1f9ff514a496f7101d81cde9e7c67 +541d2b6e12a88371c064b901b00e71206ee0c18e +68837e9bd33f125ab47b10b1a6fa18175abd1627 +54ab8dc14f81d6b18b0d17f448187d19d8e396fc +Reviewed-on: https://gerrit.libreoffice.org/48858 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +--- + sc/Library_sc.mk | 1 + + sc/inc/document.hxx | 8 ++- + sc/inc/documentlinkmgr.hxx | 6 +- + sc/source/core/data/conditio.cxx | 6 ++ + sc/source/core/data/documen2.cxx | 2 +- + sc/source/core/data/documen8.cxx | 23 +++++++ + sc/source/core/data/formulacell.cxx | 7 +- + sc/source/core/inc/webservicelink.hxx | 49 ++++++++++++++ + sc/source/core/tool/interpr2.cxx | 8 ++- + sc/source/core/tool/interpr7.cxx | 106 ++++++++++++++++++++++-------- + sc/source/core/tool/rangenam.cxx | 8 ++- + sc/source/core/tool/webservicelink.cxx | 106 ++++++++++++++++++++++++++++++ + sc/source/filter/excel/excform.cxx | 1 + + sc/source/filter/excel/excform8.cxx | 1 + + sc/source/filter/excel/impop.cxx | 1 + + sc/source/filter/excel/xicontent.cxx | 6 ++ + sc/source/filter/excel/xiname.cxx | 3 + + sc/source/filter/oox/condformatbuffer.cxx | 2 + + sc/source/filter/oox/defnamesbuffer.cxx | 2 + + sc/source/filter/oox/formulabuffer.cxx | 4 ++ + sc/source/ui/docshell/docsh4.cxx | 4 +- + sc/source/ui/docshell/documentlinkmgr.cxx | 20 ++++-- + sc/source/ui/view/tabvwsh4.cxx | 2 +- + 23 files changed, 327 insertions(+), 49 deletions(-) + create mode 100644 sc/source/core/inc/webservicelink.hxx + create mode 100644 sc/source/core/tool/webservicelink.cxx + +diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk +index d2fd5cd..02d3b7d 100644 +--- a/sc/Library_sc.mk ++++ b/sc/Library_sc.mk +@@ -282,6 +282,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ + sc/source/core/tool/unitconv \ + sc/source/core/tool/userlist \ + sc/source/core/tool/viewopti \ ++ sc/source/core/tool/webservicelink \ + sc/source/core/tool/zforauto \ + sc/source/filter/xml/datastreamimport \ + sc/source/filter/xml/XMLCalculationSettingsContext \ +diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx +index 69e6f5b..77ff388 100644 +--- a/sc/inc/document.hxx ++++ b/sc/inc/document.hxx +@@ -429,7 +429,7 @@ private: + bool bDetectiveDirty; + + sal_uInt8 nMacroCallMode; // Macros per warning dialog disabled? +- bool bHasMacroFunc; // valid only after loading ++ bool bLinkFormulaNeedingCheck; // valid only after loading, for ocDde and ocWebservice + + sal_uInt8 nVisSpellState; + +@@ -1793,8 +1793,10 @@ public: + sal_uInt8 GetMacroCallMode() const { return nMacroCallMode; } + void SetMacroCallMode(sal_uInt8 nNew) { nMacroCallMode = nNew; } + +- bool GetHasMacroFunc() const { return bHasMacroFunc; } +- void SetHasMacroFunc(bool bSet) { bHasMacroFunc = bSet; } ++ bool HasLinkFormulaNeedingCheck() const { return bLinkFormulaNeedingCheck; } ++ void SetLinkFormulaNeedingCheck(bool bSet) { bLinkFormulaNeedingCheck = bSet; } ++ /** Check token array and set link check if ocDde/ocWebservice is contained. */ ++ SC_DLLPUBLIC void CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ); + + static bool CheckMacroWarn(); + +diff --git a/sc/inc/documentlinkmgr.hxx b/sc/inc/documentlinkmgr.hxx +index cc42410..d7972b1 100644 +--- a/sc/inc/documentlinkmgr.hxx ++++ b/sc/inc/documentlinkmgr.hxx +@@ -53,9 +53,9 @@ public: + bool idleCheckLinks(); + + bool hasDdeLinks() const; +- bool hasDdeOrOleLinks() const; ++ bool hasDdeOrOleOrWebServiceLinks() const; + +- bool updateDdeOrOleLinks(vcl::Window* pWin); ++ bool updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin); + + bool updateDdeLink( const OUString& rAppl, const OUString& rTopic, const OUString& rItem ); + +@@ -63,7 +63,7 @@ public: + + void disconnectDdeLinks(); + private: +- bool hasDdeOrOleLinks(bool bDde, bool bOle) const; ++ bool hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const; + }; + + } +diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx +index f087af6..8627367 100644 +--- a/sc/source/core/data/conditio.cxx ++++ b/sc/source/core/data/conditio.cxx +@@ -471,6 +471,12 @@ void ScConditionEntry::CompileXML() + Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1), + GetExpression(aSrcPos, 1, 0, eTempGrammar2), + aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, true ); ++ ++ // Importing ocDde/ocWebservice? ++ if (pFormula1) ++ mpDoc->CheckLinkFormulaNeedingCheck(*pFormula1); ++ if (pFormula2) ++ mpDoc->CheckLinkFormulaNeedingCheck(*pFormula2); + } + + void ScConditionEntry::SetSrcString( const OUString& rNew ) +diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx +index 8d3e4e3..0d494c4 100644 +--- a/sc/source/core/data/documen2.cxx ++++ b/sc/source/core/data/documen2.cxx +@@ -202,7 +202,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : + bExpandRefs( false ), + bDetectiveDirty( false ), + nMacroCallMode( SC_MACROCALL_ALLOWED ), +- bHasMacroFunc( false ), ++ bLinkFormulaNeedingCheck( false ), + nVisSpellState( 0 ), + nAsianCompression(SC_ASIANCOMPRESSION_INVALID), + nAsianKerning(SC_ASIANKERNING_INVALID), +diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx +index 2bdfa30..7391e1c 100644 +--- a/sc/source/core/data/documen8.cxx ++++ b/sc/source/core/data/documen8.cxx +@@ -88,6 +88,7 @@ + #include "stringutil.hxx" + #include + #include ++#include + + #include + +@@ -1158,6 +1159,28 @@ void ScDocument::UpdateRefAreaLinks( UpdateRefMode eUpdateRefMode, + } + } + ++void ScDocument::CheckLinkFormulaNeedingCheck( const ScTokenArray& rCode ) ++{ ++ if (HasLinkFormulaNeedingCheck()) ++ return; ++ ++ // Prefer RPN over tokenized formula if available. ++ if (rCode.GetCodeLen()) ++ { ++ if (rCode.HasOpCodeRPN(ocDde) || rCode.HasOpCodeRPN(ocWebservice)) ++ SetLinkFormulaNeedingCheck(true); ++ } ++ else if (rCode.GetLen()) ++ { ++ if (rCode.HasOpCode(ocDde) || rCode.HasOpCode(ocWebservice)) ++ SetLinkFormulaNeedingCheck(true); ++ } ++ else ++ { ++ assert(!"called with empty ScTokenArray"); ++ } ++} ++ + // TimerDelays etc. + void ScDocument::KeyInput( const KeyEvent& ) + { +diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx +index ceb7f68..49d3133 100644 +--- a/sc/source/core/data/formulacell.cxx ++++ b/sc/source/core/data/formulacell.cxx +@@ -1351,10 +1351,9 @@ void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rPr + bChanged = true; + } + +- // Same as in Load: after loading, it must be known if ocMacro is in any formula +- // (for macro warning, CompileXML is called at the end of loading XML file) +- if ( !pDocument->GetHasMacroFunc() && pCode->HasOpCodeRPN( ocMacro ) ) +- pDocument->SetHasMacroFunc( true ); ++ // After loading, it must be known if ocDde/ocWebservice is in any formula ++ // (for external links warning, CompileXML is called at the end of loading XML file) ++ pDocument->CheckLinkFormulaNeedingCheck(*pCode); + + //volatile cells must be added here for import + if( pCode->IsRecalcModeAlways() || pCode->IsRecalcModeForced() || +diff --git a/sc/source/core/inc/webservicelink.hxx b/sc/source/core/inc/webservicelink.hxx +new file mode 100644 +index 0000000..e61ebfd +--- /dev/null ++++ b/sc/source/core/inc/webservicelink.hxx +@@ -0,0 +1,49 @@ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ ++/* ++ * 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/. ++ */ ++ ++#ifndef INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX ++#define INCLUDED_SC_SOURCE_CORE_INC_WEBSERVICE_HXX ++ ++#include ++#include ++#include ++#include ++ ++class ScDocument; ++ ++class ScWebServiceLink : public ::sfx2::SvBaseLink, public SvtBroadcaster ++{ ++private: ++ ScDocument* pDoc; ++ OUString aURL; // connection/ link data ++ bool bHasResult; // is set aResult is useful ++ OUString aResult; ++ ++public: ++ ScWebServiceLink(ScDocument* pD, const OUString& rURL); ++ virtual ~ScWebServiceLink() override; ++ ++ // SvBaseLink override: ++ virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(const OUString& rMimeType, ++ const css::uno::Any& rValue) override; ++ ++ // SvtBroadcaster override: ++ virtual void ListenersGone() override; ++ ++ // for interpreter: ++ ++ const OUString& GetResult() const { return aResult; } ++ bool HasResult() const { return bHasResult; } ++ ++ const OUString& GetURL() const { return aURL; } ++}; ++ ++#endif ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ +diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx +index d82bc29..5f6b5af 100644 +--- a/sc/source/core/tool/interpr2.cxx ++++ b/sc/source/core/tool/interpr2.cxx +@@ -2421,8 +2421,14 @@ void ScInterpreter::ScDde() + pBindings->Invalidate( SID_LINKS ); // Link-Manager enablen + } + ++ //if the document was just loaded, but the ScDdeLink entry was missing, then ++ //don't update this link until the links are updated in response to the users ++ //decision ++ if (!pDok->HasLinkFormulaNeedingCheck()) ++ { + //TODO: evaluate asynchron ??? +- pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times ++ pLink->TryUpdate(); // TryUpdate doesn't call Update multiple times ++ } + + if (pMyFormulaCell) + { +diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx +index ce69848..53524a1 100644 +--- a/sc/source/core/tool/interpr7.cxx ++++ b/sc/source/core/tool/interpr7.cxx +@@ -10,7 +10,10 @@ + #include "interpre.hxx" + #include + #include ++#include ++#include + #include ++#include + + #include + #include +@@ -20,6 +23,11 @@ + #include + #include + #include ++#include "formulacell.hxx" ++#include ++#include ++ ++#include + + #include + #include +@@ -145,6 +153,22 @@ void ScInterpreter::ScFilterXML() + } + } + ++static ScWebServiceLink* lcl_GetWebServiceLink(const sfx2::LinkManager* pLinkMgr, const OUString& rURL) ++{ ++ size_t nCount = pLinkMgr->GetLinks().size(); ++ for (size_t i=0; iGetLinks()[i]; ++ if (ScWebServiceLink* pLink = dynamic_cast(pBase)) ++ { ++ if (pLink->GetURL() == rURL) ++ return pLink; ++ } ++ } ++ ++ return nullptr; ++} ++ + void ScInterpreter::ScWebservice() + { + sal_uInt8 nParamCount = GetByte(); +@@ -152,54 +176,78 @@ void ScInterpreter::ScWebservice() + { + OUString aURI = GetString().getString(); + +- if(aURI.isEmpty()) ++ if (aURI.isEmpty()) + { + PushError( errNoValue ); + return; + } + +- uno::Reference< ucb::XSimpleFileAccess3 > xFileAccess( ucb::SimpleFileAccess::create( comphelper::getProcessComponentContext() ), uno::UNO_QUERY ); +- if(!xFileAccess.is()) ++ INetURLObject aObj(aURI, INetProtocol::File); ++ INetProtocol eProtocol = aObj.GetProtocol(); ++ if (eProtocol != INetProtocol::Http && eProtocol != INetProtocol::Https) + { +- PushError( errNoValue ); ++ PushError(errNoValue); + return; + } + +- uno::Reference< io::XInputStream > xStream; +- try { +- xStream = xFileAccess->openFileRead( aURI ); +- } +- catch (...) ++ sfx2::LinkManager* pLinkMgr = pDok->GetLinkManager(); ++ if (!pLinkMgr) + { +- // don't let any exceptions pass +- PushError( errNoValue ); +- return; +- } +- if ( !xStream.is() ) +- { +- PushError( errNoValue ); ++ PushError(errNoValue); + return; + } + +- const sal_Int32 BUF_LEN = 8000; +- uno::Sequence< sal_Int8 > buffer( BUF_LEN ); +- OStringBuffer aBuffer( 64000 ); ++ // Need to reinterpret after loading (build links) ++ if (rArr.IsRecalcModeNormal()) ++ rArr.SetExclusiveRecalcModeOnLoad(); + +- sal_Int32 nRead = 0; +- while ( ( nRead = xStream->readBytes( buffer, BUF_LEN ) ) == BUF_LEN ) +- { +- aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); +- } ++ // while the link is not evaluated, idle must be disabled (to avoid circular references) ++ bool bOldEnabled = pDok->IsIdleEnabled(); ++ pDok->EnableIdle(false); ++ ++ // Get/ Create link object ++ ScWebServiceLink* pLink = lcl_GetWebServiceLink(pLinkMgr, aURI); + +- if ( nRead > 0 ) ++ bool bWasError = (pMyFormulaCell && pMyFormulaCell->GetRawError() != 0); ++ ++ if (!pLink) + { +- aBuffer.append( reinterpret_cast< const char* >( buffer.getConstArray() ), nRead ); ++ pLink = new ScWebServiceLink(pDok, aURI); ++ pLinkMgr->InsertFileLink(*pLink, OBJECT_CLIENT_FILE, aURI); ++ if ( pLinkMgr->GetLinks().size() == 1 ) // the first one? ++ { ++ SfxBindings* pBindings = pDok->GetViewBindings(); ++ if (pBindings) ++ pBindings->Invalidate( SID_LINKS ); // Link-Manager enabled ++ } ++ ++ //if the document was just loaded, but the ScDdeLink entry was missing, then ++ //don't update this link until the links are updated in response to the users ++ //decision ++ if (!pDok->HasLinkFormulaNeedingCheck()) ++ { ++ pLink->Update(); ++ } ++ ++ if (pMyFormulaCell) ++ { ++ // StartListening after the Update to avoid circular references ++ pMyFormulaCell->StartListening(*pLink); ++ } + } + +- xStream->closeInput(); ++ // If an new Error from Reschedule appears when the link is executed then reset the errorflag ++ if (pMyFormulaCell && pMyFormulaCell->GetRawError() != 0 && !bWasError) ++ pMyFormulaCell->SetErrCode(0); ++ ++ // check the value ++ if (pLink->HasResult()) ++ PushString(pLink->GetResult()); ++ else ++ PushError(errNoValue); + +- OUString aContent = OStringToOUString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); +- PushString( aContent ); ++ pDok->EnableIdle(bOldEnabled); ++ pLinkMgr->CloseCachedComps(); + } + } + +diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx +index 4235ef7..f1f8b9d 100644 +--- a/sc/source/core/tool/rangenam.cxx ++++ b/sc/source/core/tool/rangenam.cxx +@@ -63,9 +63,14 @@ ScRangeData::ScRangeData( ScDocument* pDok, + mnMaxCol (-1) + { + if (!rSymbol.isEmpty()) +- CompileRangeData( rSymbol, pDoc->IsImportingXML()); ++ { + // Let the compiler set an error on unknown names for a subsequent + // CompileUnresolvedXML(). ++ const bool bImporting = pDoc->IsImportingXML(); ++ CompileRangeData( rSymbol, bImporting); ++ if (bImporting) ++ pDoc->CheckLinkFormulaNeedingCheck( *pCode); ++ } + else + { + // #i63513#/#i65690# don't leave pCode as NULL. +@@ -198,6 +203,7 @@ void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ) + // Don't let the compiler set an error for unknown names on final + // compile, errors are handled by the interpreter thereafter. + CompileRangeData( aSymbol, false); ++ rCxt.getDoc()->CheckLinkFormulaNeedingCheck( *pCode); + } + } + +diff --git a/sc/source/core/tool/webservicelink.cxx b/sc/source/core/tool/webservicelink.cxx +new file mode 100644 +index 0000000..82310f2 +--- /dev/null ++++ b/sc/source/core/tool/webservicelink.cxx +@@ -0,0 +1,106 @@ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ ++/* ++ * 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 ++#include ++#include ++ ++ScWebServiceLink::ScWebServiceLink(ScDocument* pD, const OUString& rURL) ++ : ::sfx2::SvBaseLink(SfxLinkUpdateMode::ALWAYS, SotClipboardFormatId::STRING) ++ , pDoc(pD) ++ , aURL(rURL) ++ , bHasResult(false) ++{ ++} ++ ++ScWebServiceLink::~ScWebServiceLink() {} ++ ++sfx2::SvBaseLink::UpdateResult ScWebServiceLink::DataChanged(const OUString&, const css::uno::Any&) ++{ ++ aResult.clear(); ++ bHasResult = false; ++ ++ css::uno::Reference xFileAccess( ++ css::ucb::SimpleFileAccess::create(comphelper::getProcessComponentContext()), ++ css::uno::UNO_QUERY); ++ if (!xFileAccess.is()) ++ return ERROR_GENERAL; ++ ++ css::uno::Reference xStream; ++ try ++ { ++ xStream = xFileAccess->openFileRead(aURL); ++ } ++ catch (...) ++ { ++ // don't let any exceptions pass ++ return ERROR_GENERAL; ++ } ++ if (!xStream.is()) ++ return ERROR_GENERAL; ++ ++ const sal_Int32 BUF_LEN = 8000; ++ css::uno::Sequence buffer(BUF_LEN); ++ OStringBuffer aBuffer(64000); ++ ++ sal_Int32 nRead = 0; ++ while ((nRead = xStream->readBytes(buffer, BUF_LEN)) == BUF_LEN) ++ aBuffer.append(reinterpret_cast(buffer.getConstArray()), nRead); ++ ++ if (nRead > 0) ++ aBuffer.append(reinterpret_cast(buffer.getConstArray()), nRead); ++ ++ xStream->closeInput(); ++ ++ aResult = OStringToOUString(aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8); ++ bHasResult = true; ++ ++ // Something happened... ++ if (HasListeners()) ++ { ++ Broadcast(ScHint(SC_HINT_DATACHANGED, ScAddress())); ++ pDoc->TrackFormulas(); // must happen immediately ++ pDoc->StartTrackTimer(); ++ } ++ ++ return SUCCESS; ++} ++ ++void ScWebServiceLink::ListenersGone() ++{ ++ ScDocument* pStackDoc = pDoc; // member pDoc can't be used after removing the link ++ ++ sfx2::LinkManager* pLinkMgr = pDoc->GetLinkManager(); ++ pLinkMgr->Remove(this); // deletes this ++ ++ if (pLinkMgr->GetLinks().empty()) // deleted the last one ? ++ { ++ SfxBindings* pBindings = pStackDoc->GetViewBindings(); // don't use member pDoc! ++ if (pBindings) ++ pBindings->Invalidate(SID_LINKS); ++ } ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ +diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx +index 0839955..14be167 100644 +--- a/sc/source/filter/excel/excform.cxx ++++ b/sc/source/filter/excel/excform.cxx +@@ -157,6 +157,7 @@ void ImportExcel::Formula( + { + pCell = new ScFormulaCell(&rDoc.getDoc(), aScPos, *pResult); + pCell->GetCode()->WrapReference(aScPos, EXC_MAXCOL8, EXC_MAXROW8); ++ rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode()); + rDoc.getDoc().EnsureTable(aScPos.Tab()); + rDoc.setFormulaCell(aScPos, pCell); + SetLastFormula(aScPos.Col(), aScPos.Row(), fCurVal, nXF, pCell); +diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx +index ebe3b64..c7e56af 100644 +--- a/sc/source/filter/excel/excform8.cxx ++++ b/sc/source/filter/excel/excform8.cxx +@@ -729,6 +729,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, + << nMerk0 << ocClose; + aPool >> aStack; + pExtName->CreateDdeData( GetDoc(), aApplic, aTopic ); ++ GetDoc().SetLinkFormulaNeedingCheck(true); + } + } + break; +diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx +index 904209d..69e536e 100644 +--- a/sc/source/filter/excel/impop.cxx ++++ b/sc/source/filter/excel/impop.cxx +@@ -866,6 +866,7 @@ void ImportExcel::Shrfmla() + + ScFormulaCell* pCell = new ScFormulaCell(pD, aPos, *pErgebnis); + pCell->GetCode()->WrapReference(aPos, EXC_MAXCOL8, EXC_MAXROW8); ++ rDoc.getDoc().CheckLinkFormulaNeedingCheck( *pCell->GetCode()); + rDoc.getDoc().EnsureTable(aPos.Tab()); + rDoc.setFormulaCell(aPos, pCell); + pCell->SetNeedNumberFormat(false); +diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx +index 9613019..589ce4b 100644 +--- a/sc/source/filter/excel/xicontent.cxx ++++ b/sc/source/filter/excel/xicontent.cxx +@@ -641,7 +641,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm ) + rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize1, false, FT_CondFormat ); + // formula converter owns pTokArr -> create a copy of the token array + if( pTokArr ) ++ { + xTokArr1.reset( pTokArr->Clone() ); ++ GetDocPtr()->CheckLinkFormulaNeedingCheck( *xTokArr1); ++ } + } + + ::std::unique_ptr< ScTokenArray > pTokArr2; +@@ -652,7 +655,10 @@ void XclImpCondFormat::ReadCF( XclImpStream& rStrm ) + rFmlaConv.Convert( pTokArr, rStrm, nFmlaSize2, false, FT_CondFormat ); + // formula converter owns pTokArr -> create a copy of the token array + if( pTokArr ) ++ { + pTokArr2.reset( pTokArr->Clone() ); ++ GetDocPtr()->CheckLinkFormulaNeedingCheck( *pTokArr2); ++ } + } + + // *** create the Calc conditional formatting *** +diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx +index c1bee5a..344ecb6 100644 +--- a/sc/source/filter/excel/xiname.cxx ++++ b/sc/source/filter/excel/xiname.cxx +@@ -264,7 +264,10 @@ void XclImpName::InsertName(const ScTokenArray* pArray) + } + } + if (pData) ++ { ++ GetDoc().CheckLinkFormulaNeedingCheck( *pData->GetCode()); + mpScData = pData; // cache for later use ++ } + } + + XclImpNameManager::XclImpNameManager( const XclImpRoot& rRoot ) : +diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx +index 955b304..9ffcf51 100644 +--- a/sc/source/filter/oox/condformatbuffer.cxx ++++ b/sc/source/filter/oox/condformatbuffer.cxx +@@ -882,11 +882,13 @@ void CondFormatRule::finalizeImport() + { + pTokenArray2.reset(new ScTokenArray()); + ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] ); ++ rDoc.CheckLinkFormulaNeedingCheck( *pTokenArray2.get()); + } + + ScTokenArray aTokenArray; + OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId ); + ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] ); ++ rDoc.CheckLinkFormulaNeedingCheck( aTokenArray); + ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(eOperator, + &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName); + mpFormat->AddEntry(pNewEntry); +diff --git a/sc/source/filter/oox/defnamesbuffer.cxx b/sc/source/filter/oox/defnamesbuffer.cxx +index fa2a0cf..c4cb011 100644 +--- a/sc/source/filter/oox/defnamesbuffer.cxx ++++ b/sc/source/filter/oox/defnamesbuffer.cxx +@@ -38,6 +38,7 @@ + #include "tokenarray.hxx" + #include "tokenuno.hxx" + #include "compiler.hxx" ++#include "document.hxx" + + namespace oox { + namespace xls { +@@ -392,6 +393,7 @@ std::unique_ptr DefinedName::getScTokens() + // after, a resulting error must be reset. + sal_uInt16 nErr = pArray->GetCodeError(); + aCompiler.CompileTokenArray(); ++ getScDocument().CheckLinkFormulaNeedingCheck( *pArray); + pArray->DelRPN(); + pArray->SetCodeError(nErr); + +diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx +index 189017d..2d20e9d 100644 +--- a/sc/source/filter/oox/formulabuffer.cxx ++++ b/sc/source/filter/oox/formulabuffer.cxx +@@ -229,6 +229,10 @@ void applyCellFormulas( + continue; + + aCompiler.CompileTokenArray(); // Generate RPN tokens. ++ ++ // Check if ocDde/ocWebservice is in any formula for external links warning. ++ rDoc.getDoc().CheckLinkFormulaNeedingCheck(*pCode); ++ + ScFormulaCell* pCell = new ScFormulaCell(&rDoc.getDoc(), aPos, pCode); + rDoc.setFormulaCell(aPos, pCell); + rCache.store(aPos, pCell); +diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx +index 9fcf549..2645c7f 100644 +--- a/sc/source/ui/docshell/docsh4.cxx ++++ b/sc/source/ui/docshell/docsh4.cxx +@@ -455,7 +455,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) + ReloadTabLinks(); + aDocument.UpdateExternalRefLinks(GetActiveDialogParent()); + +- bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleLinks(GetActiveDialogParent()); ++ bool bAnyDde = aDocument.GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(GetActiveDialogParent()); + + if (bAnyDde) + { +@@ -477,6 +477,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) + rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); + rReq.Ignore(); + } ++ ++ rDoc.SetLinkFormulaNeedingCheck(false); + } + break; + +diff --git a/sc/source/ui/docshell/documentlinkmgr.cxx b/sc/source/ui/docshell/documentlinkmgr.cxx +index 8e5a5c3..ae8984b 100644 +--- a/sc/source/ui/docshell/documentlinkmgr.cxx ++++ b/sc/source/ui/docshell/documentlinkmgr.cxx +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -115,15 +116,15 @@ bool DocumentLinkManager::idleCheckLinks() + + bool DocumentLinkManager::hasDdeLinks() const + { +- return hasDdeOrOleLinks(true, false); ++ return hasDdeOrOleOrWebServiceLinks(true, false, false); + } + +-bool DocumentLinkManager::hasDdeOrOleLinks() const ++bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks() const + { +- return hasDdeOrOleLinks(true, true); ++ return hasDdeOrOleOrWebServiceLinks(true, true, true); + } + +-bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const ++bool DocumentLinkManager::hasDdeOrOleOrWebServiceLinks(bool bDde, bool bOle, bool bWebService) const + { + if (!mpImpl->mpLinkManager) + return false; +@@ -136,12 +137,14 @@ bool DocumentLinkManager::hasDdeOrOleLinks(bool bDde, bool bOle) const + return true; + if (bOle && dynamic_cast(pBase)) + return true; ++ if (bWebService && dynamic_cast(pBase)) ++ return true; + } + + return false; + } + +-bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) ++bool DocumentLinkManager::updateDdeOrOleOrWebServiceLinks(vcl::Window* pWin) + { + if (!mpImpl->mpLinkManager) + return false; +@@ -163,6 +166,13 @@ bool DocumentLinkManager::updateDdeOrOleLinks( vcl::Window* pWin ) + continue; + } + ++ ScWebServiceLink* pWebserviceLink = dynamic_cast(pBase); ++ if (pWebserviceLink) ++ { ++ pWebserviceLink->Update(); ++ continue; ++ } ++ + ScDdeLink* pDdeLink = dynamic_cast(pBase); + if (!pDdeLink) + continue; +diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx +index ff3a5a1..c7209c1 100644 +--- a/sc/source/ui/view/tabvwsh4.cxx ++++ b/sc/source/ui/view/tabvwsh4.cxx +@@ -1584,7 +1584,7 @@ void ScTabViewShell::Construct( TriState nForceDesignMode ) + if (!bLink) + { + const sc::DocumentLinkManager& rMgr = rDoc.GetDocLinkManager(); +- if (rMgr.hasDdeOrOleLinks() || rDoc.HasAreaLinks()) ++ if (rDoc.HasLinkFormulaNeedingCheck() || rDoc.HasAreaLinks() || rMgr.hasDdeOrOleOrWebServiceLinks()) + bLink = true; + } + if (bLink) +-- +2.14.3 + diff --git a/SOURCES/0001-lp-1566050-prevent-cyclic-reference-zombies.patch b/SOURCES/0001-lp-1566050-prevent-cyclic-reference-zombies.patch new file mode 100644 index 0000000..4131b85 --- /dev/null +++ b/SOURCES/0001-lp-1566050-prevent-cyclic-reference-zombies.patch @@ -0,0 +1,40 @@ +From 25b8bcab289f13cab6c0a154a0c32ab19de2ef21 Mon Sep 17 00:00:00 2001 +From: Bjoern Michaelsen +Date: Tue, 12 Apr 2016 12:20:07 +0200 +Subject: [PATCH] lp#1566050: prevent cyclic reference zombies + +regression, likely from 2660d24a07866e083c5135ea263030f3e3a2e729: + +1/ Since that change mxAccessible in ScCsvGrid holds a rtl::Reference on +a ScAccessibleCsvGrid +2/ Which in turn holds a VclPtr<> (aka a rtl::Reference with lipstick) +on the ScCsvControl + +These are a circular references, making both of them live forever and +leak past the point where on LibreOffice close all of Vcl is long gone, +when these are dtored. Clearing mxAccessible on disposing should help. + +Change-Id: Iebb2635ec4ea143e7f0dbfebad2e6141a68e72e8 +Reviewed-on: https://gerrit.libreoffice.org/24020 +Reviewed-by: Noel Grandin +Tested-by: Noel Grandin +(cherry picked from commit 941e891d16853e5eff3e40cf48cdafb3146b2750) +--- + sc/source/ui/dbgui/csvcontrol.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sc/source/ui/dbgui/csvcontrol.cxx b/sc/source/ui/dbgui/csvcontrol.cxx +index b53b5bc..7449192 100644 +--- a/sc/source/ui/dbgui/csvcontrol.cxx ++++ b/sc/source/ui/dbgui/csvcontrol.cxx +@@ -81,6 +81,7 @@ void ScCsvControl::dispose() + { + if( mxAccessible.is() ) + mxAccessible->dispose(); ++ mxAccessible = nullptr; // lp#1566050: prevent cyclic reference zombies + Control::dispose(); + } + +-- +2.9.3 + diff --git a/SOURCES/0001-move-things-around-a-little-to-make-backporting-easi.patch b/SOURCES/0001-move-things-around-a-little-to-make-backporting-easi.patch new file mode 100644 index 0000000..e10fae2 --- /dev/null +++ b/SOURCES/0001-move-things-around-a-little-to-make-backporting-easi.patch @@ -0,0 +1,14975 @@ +From a95302af9fabfc9a4e6b5d2983b9f75645f47438 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 9 Dec 2015 15:33:06 +0000 +Subject: [PATCH] move things around a little to make backporting easier + +Change-Id: I0fa86b4b524056f7a9fac228062401ea1ec2ca25 +--- + vcl/Library_vclplug_gtk.mk | 2 +- + vcl/Library_vclplug_gtk3.mk | 2 +- + vcl/inc/unx/gtk/gtkframe.hxx | 1 - + vcl/unx/gtk/gtksalframe.cxx | 4883 ++++++++++++++++++++++++++++++++++ + vcl/unx/gtk/window/gtksalframe.cxx | 4883 ---------------------------------- + vcl/unx/gtk3/app/gtk3gtkinst.cxx | 641 ----- + vcl/unx/gtk3/gtk3gtkframe.cxx | 3803 ++++++++++++++++++++++++++ + vcl/unx/gtk3/gtk3gtkinst.cxx | 641 +++++ + vcl/unx/gtk3/window/gtk3gtkframe.cxx | 12 - + 9 files changed, 9329 insertions(+), 5539 deletions(-) + create mode 100644 vcl/unx/gtk/gtksalframe.cxx + delete mode 100644 vcl/unx/gtk/window/gtksalframe.cxx + delete mode 100644 vcl/unx/gtk3/app/gtk3gtkinst.cxx + create mode 100644 vcl/unx/gtk3/gtk3gtkframe.cxx + create mode 100644 vcl/unx/gtk3/gtk3gtkinst.cxx + delete mode 100644 vcl/unx/gtk3/window/gtk3gtkframe.cxx + +diff --git a/vcl/Library_vclplug_gtk.mk b/vcl/Library_vclplug_gtk.mk +index ec7f2f8..6d10d5c 100644 +--- a/vcl/Library_vclplug_gtk.mk ++++ b/vcl/Library_vclplug_gtk.mk +@@ -100,7 +100,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk,\ + vcl/unx/gtk/app/gtkinst \ + vcl/unx/gtk/app/gtksys \ + vcl/unx/gtk/gdi/salnativewidgets-gtk \ +- vcl/unx/gtk/window/gtksalframe \ ++ vcl/unx/gtk/gtksalframe \ + vcl/unx/gtk/window/gtkobject \ + vcl/unx/gtk/fpicker/resourceprovider \ + vcl/unx/gtk/fpicker/SalGtkPicker \ +diff --git a/vcl/Library_vclplug_gtk3.mk b/vcl/Library_vclplug_gtk3.mk +index 515a81c..222c9d6 100644 +--- a/vcl/Library_vclplug_gtk3.mk ++++ b/vcl/Library_vclplug_gtk3.mk +@@ -99,7 +99,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\ + vcl/unx/gtk3/a11y/gtk3atkwindow \ + vcl/unx/gtk3/a11y/gtk3atkwrapper \ + vcl/unx/gtk3/app/gtk3gtkdata \ +- vcl/unx/gtk3/app/gtk3gtkinst \ ++ vcl/unx/gtk3/gtk3gtkinst \ + vcl/unx/gtk3/app/gtk3gtksys \ + vcl/unx/gtk3/app/gtk3fpicker \ + vcl/unx/gtk3/gdi/cairo_gtk3_cairo \ +@@ -107,7 +107,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_gtk3,\ + vcl/unx/gtk3/gdi/gtk3gtkprintwrapper \ + vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk \ + vcl/unx/gtk3/gdi/gtk3salprn-gtk \ +- vcl/unx/gtk3/window/gtk3gtkframe \ ++ vcl/unx/gtk3/gtk3gtkframe \ + vcl/unx/gtk3/window/gtk3gtkobject \ + vcl/unx/gtk3/window/gtk3gtksalmenu \ + vcl/unx/gtk3/window/gtk3glomenu \ +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index 4594249..0fb5da7 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -240,7 +240,6 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + static void signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer ); + #if GTK_CHECK_VERSION(3,0,0) + static gboolean signalDraw( GtkWidget*, cairo_t *cr, gpointer ); +- static void signalFlagsChanged( GtkWidget*, GtkStateFlags, gpointer ); + static void sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer frame); + #if GTK_CHECK_VERSION(3,14,0) + static void gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame); +diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx +new file mode 100644 +index 0000000..9e03f14 +--- /dev/null ++++ b/vcl/unx/gtk/gtksalframe.cxx +@@ -0,0 +1,4883 @@ ++/* -*- 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/. ++ * ++ * This file incorporates work covered by the following license notice: ++ * ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed ++ * with this work for additional information regarding copyright ++ * ownership. The ASF licenses this file to you under the Apache ++ * License, Version 2.0 (the "License"); you may not use this file ++ * except in compliance with the License. You may obtain a copy of ++ * the License at http://www.apache.org/licenses/LICENSE-2.0 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++# include ++#endif ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++# include ++#endif ++#if defined ENABLE_GMENU_INTEGRATION // defined in gtksalmenu.hxx above ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#if OSL_DEBUG_LEVEL > 1 ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if GTK_CHECK_VERSION(3,0,0) ++# include ++#endif ++ ++#ifdef ENABLE_DBUS ++#include ++ ++#define GSM_DBUS_SERVICE "org.gnome.SessionManager" ++#define GSM_DBUS_PATH "/org/gnome/SessionManager" ++#define GSM_DBUS_INTERFACE "org.gnome.SessionManager" ++#endif ++ ++#include ++ ++#if GTK_CHECK_VERSION(3,0,0) ++#define IS_WIDGET_REALIZED gtk_widget_get_realized ++#define IS_WIDGET_MAPPED gtk_widget_get_mapped ++#else ++#define IS_WIDGET_REALIZED GTK_WIDGET_REALIZED ++#define IS_WIDGET_MAPPED GTK_WIDGET_MAPPED ++#endif ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++#define GDK_IS_X11_DISPLAY(foo) (true) ++#endif ++ ++using namespace com::sun::star; ++ ++int GtkSalFrame::m_nFloats = 0; ++ ++#if defined ENABLE_GMENU_INTEGRATION ++static GDBusConnection* pSessionBus = NULL; ++#endif ++ ++static sal_uInt16 GetKeyModCode( guint state ) ++{ ++ sal_uInt16 nCode = 0; ++ if( (state & GDK_SHIFT_MASK) ) ++ nCode |= KEY_SHIFT; ++ if( (state & GDK_CONTROL_MASK) ) ++ nCode |= KEY_MOD1; ++ if( (state & GDK_MOD1_MASK) ) ++ nCode |= KEY_MOD2; ++ ++ // Map Meta/Super keys to MOD3 modifier on all Unix systems ++ // except Mac OS X ++ if ( (state & GDK_META_MASK ) || ( state & GDK_SUPER_MASK ) ) ++ nCode |= KEY_MOD3; ++ return nCode; ++} ++ ++static sal_uInt16 GetMouseModCode( guint state ) ++{ ++ sal_uInt16 nCode = GetKeyModCode( state ); ++ if( (state & GDK_BUTTON1_MASK) ) ++ nCode |= MOUSE_LEFT; ++ if( (state & GDK_BUTTON2_MASK) ) ++ nCode |= MOUSE_MIDDLE; ++ if( (state & GDK_BUTTON3_MASK) ) ++ nCode |= MOUSE_RIGHT; ++ ++ return nCode; ++} ++ ++static sal_uInt16 GetKeyCode( guint keyval ) ++{ ++ sal_uInt16 nCode = 0; ++ if( keyval >= GDK_0 && keyval <= GDK_9 ) ++ nCode = KEY_0 + (keyval-GDK_0); ++ else if( keyval >= GDK_KP_0 && keyval <= GDK_KP_9 ) ++ nCode = KEY_0 + (keyval-GDK_KP_0); ++ else if( keyval >= GDK_A && keyval <= GDK_Z ) ++ nCode = KEY_A + (keyval-GDK_A ); ++ else if( keyval >= GDK_a && keyval <= GDK_z ) ++ nCode = KEY_A + (keyval-GDK_a ); ++ else if( keyval >= GDK_F1 && keyval <= GDK_F26 ) ++ { ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( GetGtkSalData()->GetGtkDisplay()->IsNumLockFromXS() ) ++ { ++ nCode = KEY_F1 + (keyval-GDK_F1); ++ } ++ else ++#endif ++ { ++ switch( keyval ) ++ { ++ // - - - - - Sun keyboard, see vcl/unx/source/app/saldisp.cxx ++ case GDK_L2: ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( GetGtkSalData()->GetGtkDisplay()->GetServerVendor() == vendor_sun ) ++ nCode = KEY_REPEAT; ++ else ++#endif ++ nCode = KEY_F12; ++ break; ++ case GDK_L3: nCode = KEY_PROPERTIES; break; ++ case GDK_L4: nCode = KEY_UNDO; break; ++ case GDK_L6: nCode = KEY_COPY; break; // KEY_F16 ++ case GDK_L8: nCode = KEY_PASTE; break; // KEY_F18 ++ case GDK_L10: nCode = KEY_CUT; break; // KEY_F20 ++ default: ++ nCode = KEY_F1 + (keyval-GDK_F1); break; ++ } ++ } ++ } ++ else ++ { ++ switch( keyval ) ++ { ++ case GDK_KP_Down: ++ case GDK_Down: nCode = KEY_DOWN; break; ++ case GDK_KP_Up: ++ case GDK_Up: nCode = KEY_UP; break; ++ case GDK_KP_Left: ++ case GDK_Left: nCode = KEY_LEFT; break; ++ case GDK_KP_Right: ++ case GDK_Right: nCode = KEY_RIGHT; break; ++ case GDK_KP_Begin: ++ case GDK_KP_Home: ++ case GDK_Begin: ++ case GDK_Home: nCode = KEY_HOME; break; ++ case GDK_KP_End: ++ case GDK_End: nCode = KEY_END; break; ++ case GDK_KP_Page_Up: ++ case GDK_Page_Up: nCode = KEY_PAGEUP; break; ++ case GDK_KP_Page_Down: ++ case GDK_Page_Down: nCode = KEY_PAGEDOWN; break; ++ case GDK_KP_Enter: ++ case GDK_Return: nCode = KEY_RETURN; break; ++ case GDK_Escape: nCode = KEY_ESCAPE; break; ++ case GDK_ISO_Left_Tab: ++ case GDK_KP_Tab: ++ case GDK_Tab: nCode = KEY_TAB; break; ++ case GDK_BackSpace: nCode = KEY_BACKSPACE; break; ++ case GDK_KP_Space: ++ case GDK_space: nCode = KEY_SPACE; break; ++ case GDK_KP_Insert: ++ case GDK_Insert: nCode = KEY_INSERT; break; ++ case GDK_KP_Delete: ++ case GDK_Delete: nCode = KEY_DELETE; break; ++ case GDK_plus: ++ case GDK_KP_Add: nCode = KEY_ADD; break; ++ case GDK_minus: ++ case GDK_KP_Subtract: nCode = KEY_SUBTRACT; break; ++ case GDK_asterisk: ++ case GDK_KP_Multiply: nCode = KEY_MULTIPLY; break; ++ case GDK_slash: ++ case GDK_KP_Divide: nCode = KEY_DIVIDE; break; ++ case GDK_period: nCode = KEY_POINT; break; ++ case GDK_decimalpoint: nCode = KEY_POINT; break; ++ case GDK_comma: nCode = KEY_COMMA; break; ++ case GDK_less: nCode = KEY_LESS; break; ++ case GDK_greater: nCode = KEY_GREATER; break; ++ case GDK_KP_Equal: ++ case GDK_equal: nCode = KEY_EQUAL; break; ++ case GDK_Find: nCode = KEY_FIND; break; ++ case GDK_Menu: nCode = KEY_CONTEXTMENU;break; ++ case GDK_Help: nCode = KEY_HELP; break; ++ case GDK_Undo: nCode = KEY_UNDO; break; ++ case GDK_Redo: nCode = KEY_REPEAT; break; ++ case GDK_KP_Decimal: ++ case GDK_KP_Separator: nCode = KEY_DECIMAL; break; ++ case GDK_asciitilde: nCode = KEY_TILDE; break; ++ case GDK_leftsinglequotemark: ++ case GDK_quoteleft: nCode = KEY_QUOTELEFT; break; ++ case GDK_bracketleft: nCode = KEY_BRACKETLEFT; break; ++ case GDK_bracketright: nCode = KEY_BRACKETRIGHT; break; ++ case GDK_semicolon: nCode = KEY_SEMICOLON; break; ++ case GDK_quoteright: nCode = KEY_QUOTERIGHT; break; ++ // some special cases, also see saldisp.cxx ++ // - - - - - - - - - - - - - Apollo - - - - - - - - - - - - - 0x1000 ++ case 0x1000FF02: // apXK_Copy ++ nCode = KEY_COPY; ++ break; ++ case 0x1000FF03: // apXK_Cut ++ nCode = KEY_CUT; ++ break; ++ case 0x1000FF04: // apXK_Paste ++ nCode = KEY_PASTE; ++ break; ++ case 0x1000FF14: // apXK_Repeat ++ nCode = KEY_REPEAT; ++ break; ++ // Exit, Save ++ // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000 ++ case 0x1000FF00: ++ nCode = KEY_DELETE; ++ break; ++ // - - - - - - - - - - - - - - H P - - - - - - - - - - - - - 0x1000 ++ case 0x1000FF73: // hpXK_DeleteChar ++ nCode = KEY_DELETE; ++ break; ++ case 0x1000FF74: // hpXK_BackTab ++ case 0x1000FF75: // hpXK_KP_BackTab ++ nCode = KEY_TAB; ++ break; ++ // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - - ++ // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004 ++ case 0x1004FF02: // osfXK_Copy ++ nCode = KEY_COPY; ++ break; ++ case 0x1004FF03: // osfXK_Cut ++ nCode = KEY_CUT; ++ break; ++ case 0x1004FF04: // osfXK_Paste ++ nCode = KEY_PASTE; ++ break; ++ case 0x1004FF07: // osfXK_BackTab ++ nCode = KEY_TAB; ++ break; ++ case 0x1004FF08: // osfXK_BackSpace ++ nCode = KEY_BACKSPACE; ++ break; ++ case 0x1004FF1B: // osfXK_Escape ++ nCode = KEY_ESCAPE; ++ break; ++ // Up, Down, Left, Right, PageUp, PageDown ++ // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - - ++ // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007 ++ // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - - ++ // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005 ++ case 0x1005FF10: // SunXK_F36 ++ nCode = KEY_F11; ++ break; ++ case 0x1005FF11: // SunXK_F37 ++ nCode = KEY_F12; ++ break; ++ case 0x1005FF70: // SunXK_Props ++ nCode = KEY_PROPERTIES; ++ break; ++ case 0x1005FF71: // SunXK_Front ++ nCode = KEY_FRONT; ++ break; ++ case 0x1005FF72: // SunXK_Copy ++ nCode = KEY_COPY; ++ break; ++ case 0x1005FF73: // SunXK_Open ++ nCode = KEY_OPEN; ++ break; ++ case 0x1005FF74: // SunXK_Paste ++ nCode = KEY_PASTE; ++ break; ++ case 0x1005FF75: // SunXK_Cut ++ nCode = KEY_CUT; ++ break; ++ } ++ } ++ ++ return nCode; ++} ++ ++static guint GetKeyValFor(GdkKeymap* pKeyMap, guint16 hardware_keycode, guint8 group) ++{ ++ guint updated_keyval = 0; ++ gdk_keymap_translate_keyboard_state(pKeyMap, hardware_keycode, ++ (GdkModifierType)0, group, &updated_keyval, NULL, NULL, NULL); ++ return updated_keyval; ++} ++ ++// F10 means either KEY_F10 or KEY_MENU, which has to be decided ++// in the independent part. ++struct KeyAlternate ++{ ++ sal_uInt16 nKeyCode; ++ sal_Unicode nCharCode; ++ KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {} ++ KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {} ++}; ++ ++inline KeyAlternate ++GetAlternateKeyCode( const sal_uInt16 nKeyCode ) ++{ ++ KeyAlternate aAlternate; ++ ++ switch( nKeyCode ) ++ { ++ case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break; ++ case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break; ++ } ++ ++ return aAlternate; ++} ++ ++#if GTK_CHECK_VERSION(3,0,0) ++ ++namespace { ++/// Decouple SalFrame lifetime from damagetracker lifetime ++struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker ++{ ++ DamageTracker(GtkSalFrame& rFrame) : m_rFrame(rFrame) ++ {} ++ ++ virtual ~DamageTracker() {} ++ ++ virtual void damaged(const basegfx::B2IBox& rDamageRect) const SAL_OVERRIDE ++ { ++ m_rFrame.damaged(rDamageRect); ++ } ++ ++ GtkSalFrame& m_rFrame; ++}; ++} ++ ++static bool dumpframes = false; ++#endif ++ ++void GtkSalFrame::doKeyCallback( guint state, ++ guint keyval, ++ guint16 hardware_keycode, ++ guint8 group, ++ guint32 time, ++ sal_Unicode aOrigCode, ++ bool bDown, ++ bool bSendRelease ++ ) ++{ ++ SalKeyEvent aEvent; ++ ++ aEvent.mnTime = time; ++ aEvent.mnCharCode = aOrigCode; ++ aEvent.mnRepeat = 0; ++ ++ vcl::DeletionListener aDel( this ); ++ ++#if GTK_CHECK_VERSION(3,0,0) ++#if 0 ++ // shift-zero forces a re-draw and event is swallowed ++ if (keyval == GDK_0) ++ { ++ fprintf( stderr, "force widget_queue_draw\n"); ++ gtk_widget_queue_draw (m_pFixedContainer); ++ return; ++ } ++ else if (keyval == GDK_1) ++ { ++ fprintf( stderr, "force repaint all\n"); ++ TriggerPaintEvent(); ++ return; ++ } ++ else if (keyval == GDK_2) ++ { ++ dumpframes = !dumpframes; ++ fprintf(stderr, "toggle dump frames to %d\n", dumpframes); ++ return; ++ } ++#endif ++#endif ++ ++ /* ++ * #i42122# translate all keys with Ctrl and/or Alt to group 0 else ++ * shortcuts (e.g. Ctrl-o) will not work but be inserted by the ++ * application ++ * ++ * #i52338# do this for all keys that the independent part has no key code ++ * for ++ * ++ * fdo#41169 rather than use group 0, detect if there is a group which can ++ * be used to input Latin text and use that if possible ++ */ ++ aEvent.mnCode = GetKeyCode( keyval ); ++ if( aEvent.mnCode == 0 ) ++ { ++ gint best_group = SAL_MAX_INT32; ++ ++ // Try and find Latin layout ++ GdkKeymap* keymap = gdk_keymap_get_default(); ++ GdkKeymapKey *keys; ++ gint n_keys; ++ if (gdk_keymap_get_entries_for_keyval(keymap, GDK_A, &keys, &n_keys)) ++ { ++ // Find the lowest group that supports Latin layout ++ for (gint i = 0; i < n_keys; ++i) ++ { ++ if (keys[i].level != 0 && keys[i].level != 1) ++ continue; ++ best_group = std::min(best_group, keys[i].group); ++ if (best_group == 0) ++ break; ++ } ++ g_free(keys); ++ } ++ ++ //Unavailable, go with original group then I suppose ++ if (best_group == SAL_MAX_INT32) ++ best_group = group; ++ ++ guint updated_keyval = GetKeyValFor(keymap, hardware_keycode, best_group); ++ aEvent.mnCode = GetKeyCode(updated_keyval); ++ } ++ ++ aEvent.mnCode |= GetKeyModCode( state ); ++ ++ if( bDown ) ++ { ++ bool bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); ++ // #i46889# copy AlternatKeyCode handling from generic plugin ++ if( ! bHandled ) ++ { ++ KeyAlternate aAlternate = GetAlternateKeyCode( aEvent.mnCode ); ++ if( aAlternate.nKeyCode ) ++ { ++ aEvent.mnCode = aAlternate.nKeyCode; ++ if( aAlternate.nCharCode ) ++ aEvent.mnCharCode = aAlternate.nCharCode; ++ bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); ++ } ++ } ++ if( bSendRelease && ! aDel.isDeleted() ) ++ { ++ CallCallback( SALEVENT_KEYUP, &aEvent ); ++ } ++ } ++ else ++ CallCallback( SALEVENT_KEYUP, &aEvent ); ++} ++ ++GtkSalFrame::GraphicsHolder::~GraphicsHolder() ++{ ++ delete pGraphics; ++} ++ ++GtkSalFrame::GtkSalFrame( SalFrame* pParent, sal_uLong nStyle ) ++ : m_nXScreen( getDisplay()->GetDefaultXScreen() ) ++{ ++ getDisplay()->registerFrame( this ); ++ m_bDefaultPos = true; ++ m_bDefaultSize = ( (nStyle & SAL_FRAME_STYLE_SIZEABLE) && ! pParent ); ++ m_bWindowIsGtkPlug = false; ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++ m_pLastSyncedDbusMenu = NULL; ++#endif ++ Init( pParent, nStyle ); ++} ++ ++GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) ++ : m_nXScreen( getDisplay()->GetDefaultXScreen() ) ++{ ++ getDisplay()->registerFrame( this ); ++ // permanently ignore errors from our unruly children ... ++ GetGenericData()->ErrorTrapPush(); ++ m_bDefaultPos = true; ++ m_bDefaultSize = true; ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++ m_pLastSyncedDbusMenu = NULL; ++#endif ++ Init( pSysData ); ++} ++ ++#ifdef ENABLE_GMENU_INTEGRATION ++ ++static void ++gdk_x11_window_set_utf8_property (GdkWindow *window, ++ const gchar *name, ++ const gchar *value) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ GdkDisplay* display = gdk_window_get_display (window); ++ ++ if (value != NULL) ++ { ++ XChangeProperty (GDK_DISPLAY_XDISPLAY (display), ++ GDK_WINDOW_XID (window), ++ gdk_x11_get_xatom_by_name_for_display (display, name), ++ gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, ++ PropModeReplace, reinterpret_cast(value), strlen (value)); ++ } ++ else ++ { ++ XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), ++ GDK_WINDOW_XID (window), ++ gdk_x11_get_xatom_by_name_for_display (display, name)); ++ } ++#endif ++} ++ ++// AppMenu watch functions. ++ ++static void ObjectDestroyedNotify( gpointer data ) ++{ ++ if ( data ) { ++ g_object_unref( data ); ++ } ++} ++ ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++void GtkSalFrame::EnsureDbusMenuSynced() ++{ ++ GtkSalMenu* pSalMenu = static_cast(GetMenu()); ++ if(m_pLastSyncedDbusMenu != pSalMenu) { ++ m_pLastSyncedDbusMenu = pSalMenu; ++ static_cast(pSalMenu)->Activate(); ++ } ++} ++#endif ++ ++static void hud_activated( gboolean hud_active, gpointer user_data ) ++{ ++ if ( hud_active ) ++ { ++ SolarMutexGuard aGuard; ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); ++ GtkSalMenu* pSalMenu = reinterpret_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); ++ ++ if ( pSalMenu ) ++ pSalMenu->UpdateFull(); ++ } ++} ++ ++static void activate_uno(GSimpleAction *action, GVariant*, gpointer) ++{ ++ uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext(); ++ ++ uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext ); ++ ++ uno::Reference < css::frame::XFrame > xFrame(xDesktop->getActiveFrame()); ++ if (!xFrame.is()) ++ xFrame = uno::Reference < css::frame::XFrame >(xDesktop, uno::UNO_QUERY); ++ ++ if (!xFrame.is()) ++ return; ++ ++ uno::Reference< css::frame::XDispatchProvider > xDispatchProvider(xFrame, uno::UNO_QUERY); ++ if (!xDispatchProvider.is()) ++ return; ++ ++ gchar *strval = NULL; ++ g_object_get(action, "name", &strval, NULL); ++ if (!strval) ++ return; ++ ++ if (strcmp(strval, "New") == 0) ++ { ++ uno::Reference xModuleManager(frame::ModuleManager::create(xContext)); ++ OUString aModuleId(xModuleManager->identify(xFrame)); ++ if (aModuleId.isEmpty()) ++ return; ++ ++ comphelper::SequenceAsHashMap lModuleDescription(xModuleManager->getByName(aModuleId)); ++ OUString sFactoryService; ++ lModuleDescription[OUString("ooSetupFactoryEmptyDocumentURL")] >>= sFactoryService; ++ if (sFactoryService.isEmpty()) ++ return; ++ ++ uno::Sequence < css::beans::PropertyValue > args(0); ++ xDesktop->loadComponentFromURL(sFactoryService, OUString("_blank"), 0, args); ++ return; ++ } ++ ++ OUString sCommand(".uno:"); ++ sCommand += OUString(strval, strlen(strval), RTL_TEXTENCODING_UTF8); ++ g_free(strval); ++ ++ css::util::URL aCommand; ++ aCommand.Complete = sCommand; ++ uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext); ++ xParser->parseStrict(aCommand); ++ ++ uno::Reference< css::frame::XDispatch > xDisp = xDispatchProvider->queryDispatch(aCommand, OUString(), 0); ++ ++ if (!xDisp.is()) ++ return; ++ ++ xDisp->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >()); ++} ++ ++static const GActionEntry app_entries[] = { ++ { "OptionsTreeDialog", activate_uno, NULL, NULL, NULL, {0} }, ++ { "About", activate_uno, NULL, NULL, NULL, {0} }, ++ { "HelpIndex", activate_uno, NULL, NULL, NULL, {0} }, ++ { "Quit", activate_uno, NULL, NULL, NULL, {0} }, ++ { "New", activate_uno, NULL, NULL, NULL, {0} } ++}; ++ ++gboolean ensure_dbus_setup( gpointer data ) ++{ ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( data ); ++ GdkWindow* gdkWindow = widget_get_window( pSalFrame->getWindow() ); ++ ++ if ( gdkWindow != NULL && g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) == NULL ) ++ { ++ // Get a DBus session connection. ++ if(!pSessionBus) ++ pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); ++ if( !pSessionBus ) ++ return FALSE; ++ ++ // Create menu model and action group attached to this frame. ++ GMenuModel* pMenuModel = G_MENU_MODEL( g_lo_menu_new() ); ++ GActionGroup* pActionGroup = reinterpret_cast(g_lo_action_group_new( static_cast< gpointer >( pSalFrame ) )); ++ ++ // Generate menu paths. ++ ::Window windowId = GDK_WINDOW_XID( gdkWindow ); ++ gchar* aDBusWindowPath = g_strdup_printf( "/org/libreoffice/window/%lu", windowId ); ++ gchar* aDBusMenubarPath = g_strdup_printf( "/org/libreoffice/window/%lu/menus/menubar", windowId ); ++ ++ // Set window properties. ++ g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", pMenuModel, ObjectDestroyedNotify ); ++ g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", pActionGroup, ObjectDestroyedNotify ); ++ ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_ID", "org.libreoffice" ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", "/org/libreoffice" ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aDBusWindowPath ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); ++ ++ // Publish the menu model and the action group. ++ SAL_INFO("vcl.unity", "exporting menu model at " << pMenuModel << " for window " << windowId); ++ pSalFrame->m_nMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, NULL); ++ SAL_INFO("vcl.unity", "exporting action group at " << pActionGroup << " for window " << windowId); ++ pSalFrame->m_nActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, aDBusWindowPath, pActionGroup, NULL); ++ pSalFrame->m_nHudAwarenessId = hud_awareness_register( pSessionBus, aDBusMenubarPath, hud_activated, pSalFrame, NULL, NULL ); ++ ++ // fdo#70885 we don't want app menu under Unity ++ bool bDesktopIsUnity = (SalGetDesktopEnvironment() == "UNITY"); ++ ++ if (!bDesktopIsUnity) ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APP_MENU_OBJECT_PATH", "/org/libreoffice/menus/appmenu" ); ++ ++ //app menu, to-do translations, block normal menus when active, honor use appmenu settings ++ ResMgr* pMgr = ImplGetResMgr(); ++ if( pMgr && !bDesktopIsUnity ) ++ { ++ GMenu *menu = g_menu_new (); ++ GMenuItem* item; ++ ++ GMenu *firstsubmenu = g_menu_new (); ++ ++ OString sNew(OUStringToOString(ResId(SV_BUTTONTEXT_NEW, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sNew.getStr(), "app.New"); ++ g_menu_append_item( firstsubmenu, item ); ++ g_object_unref(item); ++ ++ g_menu_append_section( menu, NULL, G_MENU_MODEL(firstsubmenu)); ++ g_object_unref(firstsubmenu); ++ ++ GMenu *secondsubmenu = g_menu_new (); ++ ++ OString sPreferences(OUStringToOString(ResId(SV_STDTEXT_PREFERENCES, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sPreferences.getStr(), "app.OptionsTreeDialog"); ++ g_menu_append_item( secondsubmenu, item ); ++ g_object_unref(item); ++ ++ g_menu_append_section( menu, NULL, G_MENU_MODEL(secondsubmenu)); ++ g_object_unref(secondsubmenu); ++ ++ GMenu *thirdsubmenu = g_menu_new (); ++ ++ OString sHelp(OUStringToOString(ResId(SV_BUTTONTEXT_HELP, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sHelp.getStr(), "app.HelpIndex"); ++ g_menu_append_item( thirdsubmenu, item ); ++ g_object_unref(item); ++ ++ OString sAbout(OUStringToOString(ResId(SV_STDTEXT_ABOUT, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sAbout.getStr(), "app.About"); ++ g_menu_append_item( thirdsubmenu, item ); ++ g_object_unref(item); ++ ++ OString sQuit(OUStringToOString(ResId(SV_MENU_MAC_QUITAPP, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sQuit.getStr(), "app.Quit"); ++ g_menu_append_item( thirdsubmenu, item ); ++ g_object_unref(item); ++ g_menu_append_section( menu, NULL, G_MENU_MODEL(thirdsubmenu)); ++ g_object_unref(thirdsubmenu); ++ ++ GSimpleActionGroup *group = g_simple_action_group_new (); ++#if GLIB_CHECK_VERSION(2,38,0) // g_simple_action_group_add_entries is deprecated since 2.38 ++ g_action_map_add_action_entries (G_ACTION_MAP (group), app_entries, G_N_ELEMENTS (app_entries), NULL); ++#else ++ g_simple_action_group_add_entries (group, app_entries, G_N_ELEMENTS (app_entries), NULL); ++#endif ++ GActionGroup* pAppActionGroup = G_ACTION_GROUP(group); ++ ++ pSalFrame->m_nAppActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, "/org/libreoffice", pAppActionGroup, NULL); ++ g_object_unref(pAppActionGroup); ++ pSalFrame->m_nAppMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, "/org/libreoffice/menus/appmenu", G_MENU_MODEL (menu), NULL); ++ g_object_unref(menu); ++ } ++ ++ g_free( aDBusMenubarPath ); ++ g_free( aDBusWindowPath ); ++ } ++ ++ return FALSE; ++} ++ ++void on_registrar_available( GDBusConnection * /*connection*/, ++ const gchar * /*name*/, ++ const gchar * /*name_owner*/, ++ gpointer user_data ) ++{ ++ SolarMutexGuard aGuard; ++ ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); ++ ++ SalMenu* pSalMenu = pSalFrame->GetMenu(); ++ ++ if ( pSalMenu != NULL ) ++ { ++ GtkSalMenu* pGtkSalMenu = static_cast(pSalMenu); ++ pGtkSalMenu->Display( true ); ++ pGtkSalMenu->UpdateFull(); ++ } ++} ++ ++// This is called when the registrar becomes unavailable. It shows the menubar. ++void on_registrar_unavailable( GDBusConnection * /*connection*/, ++ const gchar * /*name*/, ++ gpointer user_data ) ++{ ++ SolarMutexGuard aGuard; ++ ++ SAL_INFO("vcl.unity", "on_registrar_unavailable"); ++ ++ //pSessionBus = NULL; ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); ++ ++ SalMenu* pSalMenu = pSalFrame->GetMenu(); ++ ++ if ( pSalMenu ) { ++ GtkSalMenu* pGtkSalMenu = static_cast< GtkSalMenu* >( pSalMenu ); ++ pGtkSalMenu->Display( false ); ++ } ++} ++#endif ++ ++void GtkSalFrame::EnsureAppMenuWatch() ++{ ++#ifdef ENABLE_GMENU_INTEGRATION ++ if ( !m_nWatcherId ) ++ { ++ // Get a DBus session connection. ++ if ( pSessionBus == NULL ) ++ { ++ pSessionBus = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, NULL ); ++ ++ if ( pSessionBus == NULL ) ++ return; ++ } ++ ++ // Publish the menu only if AppMenu registrar is available. ++ m_nWatcherId = g_bus_watch_name_on_connection( pSessionBus, ++ "com.canonical.AppMenu.Registrar", ++ G_BUS_NAME_WATCHER_FLAGS_NONE, ++ on_registrar_available, ++ on_registrar_unavailable, ++ static_cast(this), ++ NULL ); ++ } ++ ++ //ensure_dbus_setup( this ); ++#else ++ (void) this; // loplugin:staticmethods ++#endif ++} ++ ++void GtkSalFrame::InvalidateGraphics() ++{ ++ for (unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); ++i) ++ { ++ if( !m_aGraphics[i].pGraphics ) ++ continue; ++#if !GTK_CHECK_VERSION(3,0,0) ++ m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen ); ++ m_aGraphics[i].pGraphics->SetWindow(NULL); ++#endif ++ m_aGraphics[i].bInUse = false; ++ } ++} ++ ++GtkSalFrame::~GtkSalFrame() ++{ ++ InvalidateGraphics(); ++ ++ if( m_pParent ) ++ m_pParent->m_aChildren.remove( this ); ++ ++ getDisplay()->deregisterFrame( this ); ++ ++ if( m_pRegion ) ++ { ++#if GTK_CHECK_VERSION(3,0,0) ++ cairo_region_destroy( m_pRegion ); ++#else ++ gdk_region_destroy( m_pRegion ); ++#endif ++ } ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( m_hBackgroundPixmap ) ++ { ++ XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), ++ widget_get_xid(m_pWindow), ++ None ); ++ XFreePixmap( getDisplay()->GetDisplay(), m_hBackgroundPixmap ); ++ } ++#endif ++ ++ if( m_pIMHandler ) ++ delete m_pIMHandler; ++ ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ for (auto handler_id : m_aMouseSignalIds) ++ g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); ++ if( m_pFixedContainer ) ++ gtk_widget_destroy( GTK_WIDGET( m_pFixedContainer ) ); ++ if( m_pEventBox ) ++ gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); ++ { ++ SolarMutexGuard aGuard; ++#if defined ENABLE_GMENU_INTEGRATION ++ if(m_nWatcherId) ++ g_bus_unwatch_name(m_nWatcherId); ++#endif ++ if( m_pWindow ) ++ { ++ g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", NULL ); ++ ++#if defined ENABLE_GMENU_INTEGRATION ++ if ( pSessionBus ) ++ { ++ if ( m_nHudAwarenessId ) ++ hud_awareness_unregister( pSessionBus, m_nHudAwarenessId ); ++ if ( m_nMenuExportId ) ++ g_dbus_connection_unexport_menu_model( pSessionBus, m_nMenuExportId ); ++ if ( m_nAppMenuExportId ) ++ g_dbus_connection_unexport_menu_model( pSessionBus, m_nAppMenuExportId ); ++ if ( m_nActionGroupExportId ) ++ g_dbus_connection_unexport_action_group( pSessionBus, m_nActionGroupExportId ); ++ if ( m_nAppActionGroupExportId ) ++ g_dbus_connection_unexport_action_group( pSessionBus, m_nAppActionGroupExportId ); ++ } ++#endif ++ gtk_widget_destroy( m_pWindow ); ++ } ++ } ++ if( m_pForeignParent ) ++ g_object_unref( G_OBJECT( m_pForeignParent ) ); ++ if( m_pForeignTopLevel ) ++ g_object_unref( G_OBJECT( m_pForeignTopLevel) ); ++} ++ ++void GtkSalFrame::moveWindow( long nX, long nY ) ++{ ++ if( isChild( false, true ) ) ++ { ++ if( m_pParent ) ++ gtk_fixed_move( m_pParent->getFixedContainer(), ++ m_pWindow, ++ nX - m_pParent->maGeometry.nX, nY - m_pParent->maGeometry.nY ); ++ } ++ else ++ gtk_window_move( GTK_WINDOW(m_pWindow), nX, nY ); ++} ++ ++void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ gint nOrigwidth, nOrigheight; ++ gtk_window_get_size(GTK_WINDOW(m_pWindow), &nOrigwidth, &nOrigheight); ++ if (nWidth > nOrigwidth || nHeight > nOrigheight) ++ { ++ m_bPaintsBlocked = true; ++ } ++ gtk_widget_set_size_request(m_pWindow, nWidth, nHeight ); ++#else ++ gtk_widget_set_size_request(GTK_WIDGET(m_pFixedContainer), nWidth, nHeight ); ++#endif ++} ++ ++void GtkSalFrame::window_resize(long nWidth, long nHeight) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ gint nOrigwidth, nOrigheight; ++ gtk_window_get_size(GTK_WINDOW(m_pWindow), &nOrigwidth, &nOrigheight); ++ if (nWidth > nOrigwidth || nHeight > nOrigheight) ++ { ++ m_bPaintsBlocked = true; ++ } ++#endif ++ gtk_window_resize(GTK_WINDOW(m_pWindow), nWidth, nHeight); ++} ++ ++void GtkSalFrame::resizeWindow( long nWidth, long nHeight ) ++{ ++ if( isChild( false, true ) ) ++ { ++ widget_set_size_request(nWidth, nHeight); ++ } ++ else if( ! isChild( true, false ) ) ++ window_resize(nWidth, nHeight); ++} ++ ++#if GTK_CHECK_VERSION(3,2,0) ++ ++static void ++ooo_fixed_class_init(GtkFixedClass *klass) ++{ ++ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); ++ widget_class->get_accessible = ooo_fixed_get_accessible; ++} ++ ++#endif ++ ++/* ++ * Always use a sub-class of GtkFixed we can tag for a11y. This allows us to ++ * utilize GAIL for the toplevel window and toolkit implementation incl. ++ * key event listener support .. ++ */ ++ ++GType ++ooo_fixed_get_type() ++{ ++ static GType type = 0; ++ ++ if (!type) { ++ static const GTypeInfo tinfo = ++ { ++ sizeof (GtkFixedClass), ++ nullptr, /* base init */ ++ nullptr, /* base finalize */ ++#if GTK_CHECK_VERSION(3,2,0) ++ reinterpret_cast(ooo_fixed_class_init), /* class init */ ++#else ++ nullptr, /* class init */ ++#endif ++ nullptr, /* class finalize */ ++ NULL, /* class data */ ++ sizeof (GtkFixed), /* instance size */ ++ 0, /* nb preallocs */ ++ (GInstanceInitFunc) NULL, /* instance init */ ++ NULL /* value table */ ++ }; ++ ++ type = g_type_register_static( GTK_TYPE_FIXED, "OOoFixed", ++ &tinfo, (GTypeFlags) 0); ++ } ++ ++ return type; ++} ++ ++void GtkSalFrame::updateScreenNumber() ++{ ++ int nScreen = 0; ++ GdkScreen *pScreen = gtk_widget_get_screen( m_pWindow ); ++ if( pScreen ) ++ nScreen = getDisplay()->getSystem()->getScreenMonitorIdx( pScreen, maGeometry.nX, maGeometry.nY ); ++ maGeometry.nDisplayScreenNumber = nScreen; ++} ++ ++GtkWidget *GtkSalFrame::getMouseEventWidget() const ++{ ++#if GTK_CHECK_VERSION(3,0,0) ++ return GTK_WIDGET(m_pEventBox); ++#else ++ return m_pWindow; ++#endif ++} ++ ++void GtkSalFrame::InitCommon() ++{ ++#if GTK_CHECK_VERSION(3,0,0) ++ m_pEventBox = GTK_EVENT_BOX(gtk_event_box_new()); ++ gtk_widget_add_events( GTK_WIDGET(m_pEventBox), ++ GDK_ALL_EVENTS_MASK ); ++ gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pEventBox) ); ++ ++ // add the fixed container child, ++ // fixed is needed since we have to position plugin windows ++ m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); ++ gtk_container_add( GTK_CONTAINER(m_pEventBox), GTK_WIDGET(m_pFixedContainer) ); ++#else ++ m_pEventBox = 0; ++ // add the fixed container child, ++ // fixed is needed since we have to position plugin windows ++ m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); ++ gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) ); ++#endif ++ ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ ++ gtk_widget_set_app_paintable(GTK_WIDGET(m_pFixedContainer), true); ++ /*non-X11 displays won't show anything at all without double-buffering ++ enabled*/ ++ if (GDK_IS_X11_DISPLAY(getGdkDisplay())) ++ gtk_widget_set_double_buffered(GTK_WIDGET(m_pFixedContainer), false); ++ gtk_widget_set_redraw_on_allocate(GTK_WIDGET(m_pFixedContainer), false); ++ ++ ++ // connect signals ++ g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this ); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-press-event", G_CALLBACK(signalButton), this )); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this )); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this )); ++#if GTK_CHECK_VERSION(3,0,0) ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "draw", G_CALLBACK(signalDraw), this ); ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "size-allocate", G_CALLBACK(sizeAllocated), this ); ++// g_signal_connect( G_OBJECT(m_pWindow), "state-flags-changed", G_CALLBACK(signalFlagsChanged), this ); ++#if GTK_CHECK_VERSION(3,14,0) ++ GtkGesture *pSwipe = gtk_gesture_swipe_new(pEventWidget); ++ g_signal_connect(pSwipe, "swipe", G_CALLBACK(gestureSwipe), this); ++ gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pSwipe), GTK_PHASE_TARGET); ++ g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pSwipe); ++ ++ GtkGesture *pLongPress = gtk_gesture_long_press_new(pEventWidget); ++ g_signal_connect(pLongPress, "pressed", G_CALLBACK(gestureLongPress), this); ++ gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pLongPress), GTK_PHASE_TARGET); ++ g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pLongPress); ++ ++#endif ++ ++#else ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "expose-event", G_CALLBACK(signalExpose), this ); ++#endif ++ g_signal_connect( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "window-state-event", G_CALLBACK(signalWindowState), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "scroll-event", G_CALLBACK(signalScroll), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "leave-notify-event", G_CALLBACK(signalCrossing), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "enter-notify-event", G_CALLBACK(signalCrossing), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "visibility-notify-event", G_CALLBACK(signalVisibility), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "destroy", G_CALLBACK(signalDestroy), this ); ++ ++ // init members ++ m_pCurrentCursor = NULL; ++ m_nKeyModifiers = 0; ++ m_bFullscreen = false; ++ m_bSpanMonitorsWhenFullscreen = false; ++ m_nState = GDK_WINDOW_STATE_WITHDRAWN; ++ m_nVisibility = GDK_VISIBILITY_FULLY_OBSCURED; ++#if GTK_CHECK_VERSION(3,0,0) ++ m_nLastScrollEventTime = GDK_CURRENT_TIME; ++#endif ++ m_bSendModChangeOnRelease = false; ++ m_pIMHandler = NULL; ++ m_hBackgroundPixmap = None; ++ m_nSavedScreenSaverTimeout = 0; ++ m_nGSMCookie = 0; ++ m_nExtStyle = 0; ++ m_pRegion = NULL; ++ m_ePointerStyle = static_cast(0xffff); ++ m_bSetFocusOnMap = false; ++ m_pSalMenu = NULL; ++ m_nWatcherId = 0; ++ m_nMenuExportId = 0; ++ m_nAppMenuExportId = 0; ++ m_nActionGroupExportId = 0; ++ m_nAppActionGroupExportId = 0; ++ m_nHudAwarenessId = 0; ++ ++ gtk_widget_add_events( m_pWindow, ++ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | ++ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | ++ GDK_VISIBILITY_NOTIFY_MASK | GDK_SCROLL_MASK ++ ); ++ ++ // show the widgets ++#if GTK_CHECK_VERSION(3,0,0) ++ gtk_widget_show_all( GTK_WIDGET(m_pEventBox) ); ++#else ++ gtk_widget_show_all( GTK_WIDGET(m_pFixedContainer) ); ++#endif ++ ++ // realize the window, we need an XWindow id ++ gtk_widget_realize( m_pWindow ); ++ ++ //system data ++ m_aSystemData.nSize = sizeof( SystemEnvData ); ++#if !GTK_CHECK_VERSION(3,0,0) ++ GtkSalDisplay* pDisp = GetGtkSalData()->GetGtkDisplay(); ++ m_aSystemData.pDisplay = pDisp->GetDisplay(); ++ m_aSystemData.pVisual = pDisp->GetVisual( m_nXScreen ).GetVisual(); ++ m_aSystemData.nDepth = pDisp->GetVisual( m_nXScreen ).GetDepth(); ++ m_aSystemData.aColormap = pDisp->GetColormap( m_nXScreen ).GetXColormap(); ++ m_aSystemData.aWindow = widget_get_xid(m_pWindow); ++ m_aSystemData.aShellWindow = m_aSystemData.aWindow; ++#else ++ static int nWindow = 0; ++ m_aSystemData.aWindow = nWindow; ++ m_aSystemData.aShellWindow = nWindow; ++ ++nWindow; ++#endif ++ m_aSystemData.pSalFrame = this; ++ m_aSystemData.pWidget = m_pWindow; ++ m_aSystemData.nScreen = m_nXScreen.getXScreen(); ++ m_aSystemData.pAppContext = NULL; ++ m_aSystemData.pShellWidget = m_aSystemData.pWidget; ++ ++ // fake an initial geometry, gets updated via configure event or SetPosSize ++ if( m_bDefaultPos || m_bDefaultSize ) ++ { ++ Size aDefSize = calcDefaultSize(); ++ maGeometry.nX = -1; ++ maGeometry.nY = -1; ++ maGeometry.nWidth = aDefSize.Width(); ++ maGeometry.nHeight = aDefSize.Height(); ++ if( m_pParent ) ++ { ++ // approximation ++ maGeometry.nTopDecoration = m_pParent->maGeometry.nTopDecoration; ++ maGeometry.nBottomDecoration = m_pParent->maGeometry.nBottomDecoration; ++ maGeometry.nLeftDecoration = m_pParent->maGeometry.nLeftDecoration; ++ maGeometry.nRightDecoration = m_pParent->maGeometry.nRightDecoration; ++ } ++ else ++ { ++ maGeometry.nTopDecoration = 0; ++ maGeometry.nBottomDecoration = 0; ++ maGeometry.nLeftDecoration = 0; ++ maGeometry.nRightDecoration = 0; ++ } ++ } ++ else ++ { ++ resizeWindow( maGeometry.nWidth, maGeometry.nHeight ); ++ moveWindow( maGeometry.nX, maGeometry.nY ); ++ } ++ updateScreenNumber(); ++ ++ SetIcon(1); ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ m_nWorkArea = pDisp->getWMAdaptor()->getCurrentWorkArea(); ++ /* #i64117# gtk sets a nice background pixmap ++ * but we actually don't really want that, so save ++ * some time on the Xserver as well as prevent ++ * some paint issues ++ */ ++ XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), ++ widget_get_xid(m_pWindow), ++ m_hBackgroundPixmap ); ++#endif ++} ++ ++/* Sadly gtk_window_set_accept_focus exists only since gtk 2.4 ++ * for achieving the same effect we will remove the WM_TAKE_FOCUS ++ * protocol from the window and set the input hint to false. ++ * But gtk_window_set_accept_focus needs to be called before ++ * window realization whereas the removal obviously can only happen ++ * after realization. ++ */ ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++extern "C" { ++ typedef void(*setAcceptFn)( GtkWindow*, gboolean ); ++ static setAcceptFn p_gtk_window_set_accept_focus = NULL; ++ static bool bGetAcceptFocusFn = true; ++ ++ typedef void(*setUserTimeFn)( GdkWindow*, guint32 ); ++ static setUserTimeFn p_gdk_x11_window_set_user_time = NULL; ++ static bool bGetSetUserTimeFn = true; ++} ++#endif ++ ++static void lcl_set_accept_focus( GtkWindow* pWindow, gboolean bAccept, bool bBeforeRealize ) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( bGetAcceptFocusFn ) ++ { ++ bGetAcceptFocusFn = false; ++ p_gtk_window_set_accept_focus = reinterpret_cast(osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gtk_window_set_accept_focus" )); ++ } ++ if( p_gtk_window_set_accept_focus && bBeforeRealize ) ++ p_gtk_window_set_accept_focus( pWindow, bAccept ); ++ else if( ! bBeforeRealize ) ++ { ++ Display* pDisplay = GetGtkSalData()->GetGtkDisplay()->GetDisplay(); ++ ::Window aWindow = widget_get_xid(GTK_WIDGET(pWindow)); ++ XWMHints* pHints = XGetWMHints( pDisplay, aWindow ); ++ if( ! pHints ) ++ { ++ pHints = XAllocWMHints(); ++ pHints->flags = 0; ++ } ++ pHints->flags |= InputHint; ++ pHints->input = bAccept ? True : False; ++ XSetWMHints( pDisplay, aWindow, pHints ); ++ XFree( pHints ); ++ ++ if (GetGtkSalData()->GetGtkDisplay()->getWMAdaptor()->getWindowManagerName() == "compiz") ++ return; ++ ++ /* remove WM_TAKE_FOCUS protocol; this would usually be the ++ * right thing, but gtk handles it internally whereas we ++ * want to handle it ourselves (as to sometimes not get ++ * the focus) ++ */ ++ Atom* pProtocols = NULL; ++ int nProtocols = 0; ++ XGetWMProtocols( pDisplay, ++ aWindow, ++ &pProtocols, &nProtocols ); ++ if( pProtocols ) ++ { ++ bool bSet = false; ++ Atom nTakeFocus = XInternAtom( pDisplay, "WM_TAKE_FOCUS", True ); ++ if( nTakeFocus ) ++ { ++ for( int i = 0; i < nProtocols; i++ ) ++ { ++ if( pProtocols[i] == nTakeFocus ) ++ { ++ for( int n = i; n < nProtocols-1; n++ ) ++ pProtocols[n] = pProtocols[n+1]; ++ nProtocols--; ++ i--; ++ bSet = true; ++ } ++ } ++ } ++ if( bSet ) ++ XSetWMProtocols( pDisplay, aWindow, pProtocols, nProtocols ); ++ XFree( pProtocols ); ++ } ++ } ++#else ++ gtk_window_set_accept_focus(pWindow, bAccept); ++ (void)bBeforeRealize; ++#endif ++} ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++static void lcl_set_user_time( GtkWindow* i_pWindow, guint32 i_nTime ) ++{ ++ if( bGetSetUserTimeFn ) ++ { ++ bGetSetUserTimeFn = false; ++ p_gdk_x11_window_set_user_time = reinterpret_cast(osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_x11_window_set_user_time" )); ++ } ++ bool bSet = false; ++ if( p_gdk_x11_window_set_user_time ) ++ { ++ GdkWindow* pWin = widget_get_window(GTK_WIDGET(i_pWindow)); ++ if( pWin ) // only if the window is realized. ++ { ++ p_gdk_x11_window_set_user_time( pWin, i_nTime ); ++ bSet = true; ++ } ++ } ++ if( !bSet ) ++ { ++ Display* pDisplay = GetGtkSalData()->GetGtkDisplay()->GetDisplay(); ++ Atom nUserTime = XInternAtom( pDisplay, "_NET_WM_USER_TIME", True ); ++ if( nUserTime ) ++ { ++ XChangeProperty( pDisplay, widget_get_xid(GTK_WIDGET(i_pWindow)), ++ nUserTime, XA_CARDINAL, 32, ++ PropModeReplace, reinterpret_cast(&i_nTime), 1 ); ++ } ++ } ++}; ++#endif ++ ++GtkSalFrame *GtkSalFrame::getFromWindow( GtkWindow *pWindow ) ++{ ++ return static_cast(g_object_get_data( G_OBJECT( pWindow ), "SalFrame" )); ++} ++ ++void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) ++{ ++ if( nStyle & SAL_FRAME_STYLE_DEFAULT ) // ensure default style ++ { ++ nStyle |= SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE; ++ nStyle &= ~SAL_FRAME_STYLE_FLOAT; ++ } ++ ++ m_pParent = static_cast(pParent); ++ m_pForeignParent = NULL; ++ m_aForeignParentWindow = None; ++ m_pForeignTopLevel = NULL; ++ m_aForeignTopLevelWindow = None; ++ m_nStyle = nStyle; ++ ++ GtkWindowType eWinType = ( (nStyle & SAL_FRAME_STYLE_FLOAT) && ++ ! (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION| ++ SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ++ ) ++ ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL; ++ ++ if( nStyle & SAL_FRAME_STYLE_SYSTEMCHILD ) ++ { ++ m_pWindow = gtk_event_box_new(); ++ if( m_pParent ) ++ { ++ // insert into container ++ gtk_fixed_put( m_pParent->getFixedContainer(), ++ m_pWindow, 0, 0 ); ++ ++ } ++ } ++ else ++ { ++ m_pWindow = gtk_widget_new( GTK_TYPE_WINDOW, "type", eWinType, ++ "visible", FALSE, NULL ); ++ } ++ g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", this ); ++ g_object_set_data( G_OBJECT( m_pWindow ), "libo-version", (gpointer)LIBO_VERSION_DOTTED); ++ ++ // force wm class hint ++ m_nExtStyle = ~0; ++ if (m_pParent) ++ m_sWMClass = m_pParent->m_sWMClass; ++ SetExtendedFrameStyle( 0 ); ++ ++ if( m_pParent && m_pParent->m_pWindow && ! isChild() ) ++ gtk_window_set_screen( GTK_WINDOW(m_pWindow), gtk_window_get_screen( GTK_WINDOW(m_pParent->m_pWindow) ) ); ++ ++ if (m_pParent) ++ { ++ if (!(m_pParent->m_nStyle & SAL_FRAME_STYLE_PLUG)) ++ gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) ); ++ m_pParent->m_aChildren.push_back( this ); ++ } ++ ++ InitCommon(); ++ ++ // set window type ++ bool bDecoHandling = ++ ! isChild() && ++ ( ! (nStyle & SAL_FRAME_STYLE_FLOAT) || ++ (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ); ++ ++ if( bDecoHandling ) ++ { ++ GdkWindowTypeHint eType = GDK_WINDOW_TYPE_HINT_NORMAL; ++ if( (nStyle & SAL_FRAME_STYLE_DIALOG) && m_pParent != 0 ) ++ eType = GDK_WINDOW_TYPE_HINT_DIALOG; ++ if( (nStyle & SAL_FRAME_STYLE_INTRO) ) ++ { ++ gtk_window_set_role( GTK_WINDOW(m_pWindow), "splashscreen" ); ++ eType = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN; ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ) ) ++ { ++ eType = GDK_WINDOW_TYPE_HINT_UTILITY; ++ gtk_window_set_skip_taskbar_hint( GTK_WINDOW(m_pWindow), true ); ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) ++ { ++ eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; ++ lcl_set_accept_focus( GTK_WINDOW(m_pWindow), false, true ); ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ++ { ++ eType = GDK_WINDOW_TYPE_HINT_UTILITY; ++ } ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ++ && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) ++ { ++ eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; ++ gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); ++ } ++#endif ++ gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); ++ gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_FLOAT) ) ++ { ++ gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_POPUP_MENU ); ++ } ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( eWinType == GTK_WINDOW_TOPLEVEL ) ++ { ++#ifdef ENABLE_GMENU_INTEGRATION ++ // Enable DBus native menu if available. ++ ensure_dbus_setup( this ); ++#endif ++ ++ guint32 nUserTime = 0; ++ if( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_TOOLWINDOW)) == 0 ) ++ { ++ nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); ++ } ++ lcl_set_user_time(GTK_WINDOW(m_pWindow), nUserTime); ++ } ++#endif ++ ++ if( bDecoHandling ) ++ { ++ gtk_window_set_resizable( GTK_WINDOW(m_pWindow), (nStyle & SAL_FRAME_STYLE_SIZEABLE) != 0 ); ++ if( ( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) ) ) ++ lcl_set_accept_focus( GTK_WINDOW(m_pWindow), false, false ); ++ } ++} ++ ++GdkNativeWindow GtkSalFrame::findTopLevelSystemWindow( GdkNativeWindow aWindow ) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ ::Window aRoot, aParent; ++ ::Window* pChildren; ++ unsigned int nChildren; ++ bool bBreak = false; ++ do ++ { ++ pChildren = NULL; ++ nChildren = 0; ++ aParent = aRoot = None; ++ XQueryTree( getDisplay()->GetDisplay(), aWindow, ++ &aRoot, &aParent, &pChildren, &nChildren ); ++ XFree( pChildren ); ++ if( aParent != aRoot ) ++ aWindow = aParent; ++ int nCount = 0; ++ Atom* pProps = XListProperties( getDisplay()->GetDisplay(), ++ aWindow, ++ &nCount ); ++ for( int i = 0; i < nCount && ! bBreak; ++i ) ++ bBreak = (pProps[i] == XA_WM_HINTS); ++ if( pProps ) ++ XFree( pProps ); ++ } while( aParent != aRoot && ! bBreak ); ++ ++ return aWindow; ++#else ++ (void)aWindow; ++ //FIXME: no findToplevelSystemWindow ++ return 0; ++#endif ++} ++ ++void GtkSalFrame::Init( SystemParentData* pSysData ) ++{ ++ m_pParent = NULL; ++ m_aForeignParentWindow = (GdkNativeWindow)pSysData->aWindow; ++ m_pForeignParent = NULL; ++ m_aForeignTopLevelWindow = findTopLevelSystemWindow( (GdkNativeWindow)pSysData->aWindow ); ++ m_pForeignTopLevel = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignTopLevelWindow ); ++ gdk_window_set_events( m_pForeignTopLevel, GDK_STRUCTURE_MASK ); ++ ++ if( pSysData->nSize > sizeof(pSysData->nSize)+sizeof(pSysData->aWindow) && pSysData->bXEmbedSupport ) ++ { ++#if GTK_CHECK_VERSION(3,0,0) ++ m_pWindow = gtk_plug_new_for_display( getGdkDisplay(), pSysData->aWindow ); ++#else ++ m_pWindow = gtk_plug_new( pSysData->aWindow ); ++#endif ++ m_bWindowIsGtkPlug = true; ++ widget_set_can_default( m_pWindow, true ); ++ widget_set_can_focus( m_pWindow, true ); ++ gtk_widget_set_sensitive( m_pWindow, true ); ++ } ++ else ++ { ++ m_pWindow = gtk_window_new( GTK_WINDOW_POPUP ); ++ m_bWindowIsGtkPlug = false; ++ } ++ m_nStyle = SAL_FRAME_STYLE_PLUG; ++ InitCommon(); ++ ++ m_pForeignParent = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignParentWindow ); ++ gdk_window_set_events( m_pForeignParent, GDK_STRUCTURE_MASK ); ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ int x_ret, y_ret; ++ unsigned int w, h, bw, d; ++ ::Window aRoot; ++ XGetGeometry( getDisplay()->GetDisplay(), pSysData->aWindow, ++ &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d ); ++ maGeometry.nWidth = w; ++ maGeometry.nHeight = h; ++ window_resize(w, h); ++ gtk_window_move( GTK_WINDOW(m_pWindow), 0, 0 ); ++ if( ! m_bWindowIsGtkPlug ) ++ { ++ XReparentWindow( getDisplay()->GetDisplay(), ++ widget_get_xid(m_pWindow), ++ (::Window)pSysData->aWindow, ++ 0, 0 ); ++ } ++#else ++ //FIXME: Handling embedded windows, is going to be fun ... ++#endif ++} ++ ++void GtkSalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode ) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ XEvent aEvent; ++ ++ memset( &aEvent, 0, sizeof(aEvent) ); ++ aEvent.xclient.window = m_aForeignParentWindow; ++ aEvent.xclient.type = ClientMessage; ++ aEvent.xclient.message_type = getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ); ++ aEvent.xclient.format = 32; ++ aEvent.xclient.data.l[0] = i_nTimeCode ? i_nTimeCode : CurrentTime; ++ aEvent.xclient.data.l[1] = 3; // XEMBED_REQUEST_FOCUS ++ aEvent.xclient.data.l[2] = 0; ++ aEvent.xclient.data.l[3] = 0; ++ aEvent.xclient.data.l[4] = 0; ++ ++ GetGenericData()->ErrorTrapPush(); ++ XSendEvent( getDisplay()->GetDisplay(), ++ m_aForeignParentWindow, ++ False, NoEventMask, &aEvent ); ++ GetGenericData()->ErrorTrapPop(); ++#else ++ (void) this; // loplugin:staticmethods ++ (void)i_nTimeCode; ++ //FIXME: no askForXEmbedFocus for gtk3 yet ++#endif ++} ++ ++void GtkSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) ++{ ++ if( nStyle != m_nExtStyle && ! isChild() ) ++ { ++ m_nExtStyle = nStyle; ++ updateWMClass(); ++ } ++} ++ ++SalGraphics* GtkSalFrame::AcquireGraphics() ++{ ++ if( m_pWindow ) ++ { ++ for( int i = 0; i < nMaxGraphics; i++ ) ++ { ++ if( ! m_aGraphics[i].bInUse ) ++ { ++ m_aGraphics[i].bInUse = true; ++ if( ! m_aGraphics[i].pGraphics ) ++ { ++#if GTK_CHECK_VERSION(3,0,0) ++ m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow ); ++ if( !m_aFrame.get() ) ++ { ++ AllocateFrame(); ++ TriggerPaintEvent(); ++ } ++ m_aGraphics[i].pGraphics->setDevice( m_aFrame ); ++#else // common case: ++ m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow, m_nXScreen ); ++#endif ++ } ++ return m_aGraphics[i].pGraphics; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++void GtkSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) ++{ ++ for( int i = 0; i < nMaxGraphics; i++ ) ++ { ++ if( m_aGraphics[i].pGraphics == pGraphics ) ++ { ++ m_aGraphics[i].bInUse = false; ++ break; ++ } ++ } ++} ++ ++bool GtkSalFrame::PostEvent( void* pData ) ++{ ++ getDisplay()->SendInternalEvent( this, pData ); ++ return true; ++} ++ ++void GtkSalFrame::SetTitle( const OUString& rTitle ) ++{ ++ m_aTitle = rTitle; ++ if( m_pWindow && ! isChild() ) ++ gtk_window_set_title( GTK_WINDOW(m_pWindow), OUStringToOString( rTitle, RTL_TEXTENCODING_UTF8 ).getStr() ); ++} ++ ++static inline sal_uInt8 * ++getRow( BitmapBuffer *pBuffer, sal_uLong nRow ) ++{ ++ if( BMP_SCANLINE_ADJUSTMENT( pBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) ++ return pBuffer->mpBits + nRow * pBuffer->mnScanlineSize; ++ else ++ return pBuffer->mpBits + ( pBuffer->mnHeight - nRow - 1 ) * pBuffer->mnScanlineSize; ++} ++ ++static GdkPixbuf * ++bitmapToPixbuf( SalBitmap *pSalBitmap, SalBitmap *pSalAlpha ) ++{ ++ g_return_val_if_fail( pSalBitmap != NULL, NULL ); ++ g_return_val_if_fail( pSalAlpha != NULL, NULL ); ++ ++ BitmapBuffer *pBitmap = pSalBitmap->AcquireBuffer( BITMAP_READ_ACCESS ); ++ g_return_val_if_fail( pBitmap != NULL, NULL ); ++ g_return_val_if_fail( pBitmap->mnBitCount == 24 || pBitmap->mnBitCount == 32, NULL ); ++ ++ BitmapBuffer *pAlpha = pSalAlpha->AcquireBuffer( BITMAP_READ_ACCESS ); ++ g_return_val_if_fail( pAlpha != NULL, NULL ); ++ g_return_val_if_fail( pAlpha->mnBitCount == 8, NULL ); ++ ++ Size aSize = pSalBitmap->GetSize(); ++ g_return_val_if_fail( pSalAlpha->GetSize() == aSize, NULL ); ++ ++ int nX, nY; ++ guchar *pPixbufData = static_cast(g_malloc (4 * aSize.Width() * aSize.Height() )); ++ guchar *pDestData = pPixbufData; ++ ++ for( nY = 0; nY < pBitmap->mnHeight; nY++ ) ++ { ++ sal_uInt8 *pData = getRow( pBitmap, nY ); ++ sal_uInt8 *pAlphaData = getRow( pAlpha, nY ); ++ ++ for( nX = 0; nX < pBitmap->mnWidth; nX++ ) ++ { ++ BitmapColor aColor; ++ if (pBitmap->mnFormat == BMP_FORMAT_24BIT_TC_BGR) ++ { ++ aColor = BitmapColor(pData[2], pData[1], pData[0]); ++ pData += 3; ++ } ++ else if (pBitmap->mnFormat == BMP_FORMAT_24BIT_TC_RGB) ++ { ++ aColor = BitmapColor(pData[0], pData[1], pData[2]); ++ pData += 3; ++ } ++ else ++ { ++ pBitmap->maColorMask.GetColorFor32Bit(aColor, pData); ++ pData += 4; ++ } ++ *pDestData++ = aColor.GetRed(); ++ *pDestData++ = aColor.GetGreen(); ++ *pDestData++ = aColor.GetBlue(); ++ *pDestData++ = 255 - *pAlphaData++; ++ } ++ } ++ ++ pSalBitmap->ReleaseBuffer( pBitmap, BITMAP_READ_ACCESS ); ++ pSalAlpha->ReleaseBuffer( pAlpha, BITMAP_READ_ACCESS ); ++ ++ return gdk_pixbuf_new_from_data( pPixbufData, ++ GDK_COLORSPACE_RGB, true, 8, ++ aSize.Width(), aSize.Height(), ++ aSize.Width() * 4, ++ reinterpret_cast(g_free), ++ NULL ); ++} ++ ++void GtkSalFrame::SetIcon( sal_uInt16 nIcon ) ++{ ++ if( (m_nStyle & (SAL_FRAME_STYLE_PLUG|SAL_FRAME_STYLE_SYSTEMCHILD|SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_INTRO|SAL_FRAME_STYLE_OWNERDRAWDECORATION)) ++ || ! m_pWindow ) ++ return; ++ ++ if( !ImplGetResMgr() ) ++ return; ++ ++ GdkPixbuf *pBuf; ++ GList *pIcons = NULL; ++ ++ sal_uInt16 nOffsets[2] = { SV_ICON_SMALL_START, SV_ICON_LARGE_START }; ++ sal_uInt16 nIndex; ++ ++ for( nIndex = 0; nIndex < sizeof(nOffsets)/ sizeof(sal_uInt16); nIndex++ ) ++ { ++ // #i44723# workaround gcc temporary problem ++ ResId aResId( nOffsets[nIndex] + nIcon, *ImplGetResMgr() ); ++ BitmapEx aIcon( aResId ); ++ ++ // #i81083# convert to 24bit/8bit alpha bitmap ++ Bitmap aBmp = aIcon.GetBitmap(); ++ if( aBmp.GetBitCount() != 24 || ! aIcon.IsAlpha() ) ++ { ++ if( aBmp.GetBitCount() != 24 ) ++ aBmp.Convert( BMP_CONVERSION_24BIT ); ++ AlphaMask aMask; ++ if( ! aIcon.IsAlpha() ) ++ { ++ switch( aIcon.GetTransparentType() ) ++ { ++ case TRANSPARENT_NONE: ++ { ++ sal_uInt8 nTrans = 0; ++ aMask = AlphaMask( aBmp.GetSizePixel(), &nTrans ); ++ } ++ break; ++ case TRANSPARENT_COLOR: ++ aMask = AlphaMask( aBmp.CreateMask( aIcon.GetTransparentColor() ) ); ++ break; ++ case TRANSPARENT_BITMAP: ++ aMask = AlphaMask( aIcon.GetMask() ); ++ break; ++ default: ++ OSL_FAIL( "unhandled transparent type" ); ++ break; ++ } ++ } ++ else ++ aMask = aIcon.GetAlpha(); ++ aIcon = BitmapEx( aBmp, aMask ); ++ } ++ ++ ImpBitmap *pIconImpBitmap = aIcon.ImplGetBitmapImpBitmap(); ++ ImpBitmap *pIconImpMask = aIcon.ImplGetMaskImpBitmap(); ++ ++ if( pIconImpBitmap && pIconImpMask ) ++ { ++ SalBitmap *pIconBitmap = ++ pIconImpBitmap->ImplGetSalBitmap(); ++ SalBitmap *pIconMask = ++ pIconImpMask->ImplGetSalBitmap(); ++ ++ if( ( pBuf = bitmapToPixbuf( pIconBitmap, pIconMask ) ) ) ++ pIcons = g_list_prepend( pIcons, pBuf ); ++ } ++ } ++ ++ gtk_window_set_icon_list( GTK_WINDOW(m_pWindow), pIcons ); ++ ++ g_list_foreach( pIcons, reinterpret_cast(g_object_unref), NULL ); ++ g_list_free( pIcons ); ++} ++ ++void GtkSalFrame::SetMenu( SalMenu* pSalMenu ) ++{ ++// if(m_pSalMenu) ++// { ++// static_cast(m_pSalMenu)->DisconnectFrame(); ++// } ++ m_pSalMenu = pSalMenu; ++} ++ ++SalMenu* GtkSalFrame::GetMenu() ++{ ++ return m_pSalMenu; ++} ++ ++void GtkSalFrame::DrawMenuBar() ++{ ++} ++ ++void GtkSalFrame::Center() ++{ ++ long nX, nY; ++ ++ if( m_pParent ) ++ { ++ nX = ((long)m_pParent->maGeometry.nWidth - (long)maGeometry.nWidth)/2; ++ nY = ((long)m_pParent->maGeometry.nHeight - (long)maGeometry.nHeight)/2; ++ } ++ else ++ { ++ GdkScreen *pScreen = NULL; ++ gint px, py; ++ GdkModifierType nMask; ++ gdk_display_get_pointer( getGdkDisplay(), &pScreen, &px, &py, &nMask ); ++ if( !pScreen ) ++ pScreen = gtk_widget_get_screen( m_pWindow ); ++ ++ gint nMonitor; ++ nMonitor = gdk_screen_get_monitor_at_point( pScreen, px, py ); ++ ++ GdkRectangle aMonitor; ++ gdk_screen_get_monitor_geometry( pScreen, nMonitor, &aMonitor ); ++ ++ nX = aMonitor.x + (aMonitor.width - (long)maGeometry.nWidth)/2; ++ nY = aMonitor.y + (aMonitor.height - (long)maGeometry.nHeight)/2; ++ } ++ SetPosSize( nX, nY, 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); ++} ++ ++Size GtkSalFrame::calcDefaultSize() ++{ ++ return bestmaxFrameSizeForScreenSize(getDisplay()->GetScreenSize(GetDisplayScreen())); ++} ++ ++void GtkSalFrame::SetDefaultSize() ++{ ++ Size aDefSize = calcDefaultSize(); ++ ++ SetPosSize( 0, 0, aDefSize.Width(), aDefSize.Height(), ++ SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); ++ ++ if( (m_nStyle & SAL_FRAME_STYLE_DEFAULT) && m_pWindow ) ++ gtk_window_maximize( GTK_WINDOW(m_pWindow) ); ++} ++ ++static void initClientId() ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ static bool bOnce = false; ++ if (!bOnce) ++ { ++ bOnce = true; ++ const OString& rID = SessionManagerClient::getSessionID(); ++ if (!rID.isEmpty()) ++ gdk_set_sm_client_id(rID.getStr()); ++ } ++#else ++ // No session management support for gtk3+ - this is now legacy. ++#endif ++} ++ ++void GtkSalFrame::Show( bool bVisible, bool bNoActivate ) ++{ ++ if( m_pWindow ) ++ { ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) ++ && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) ++ gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), bVisible ); ++#endif ++ if( bVisible ) ++ { ++ initClientId(); ++ getDisplay()->startupNotificationCompleted(); ++ ++ if( m_bDefaultPos ) ++ Center(); ++ if( m_bDefaultSize ) ++ SetDefaultSize(); ++ setMinMaxSize(); ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ // #i45160# switch to desktop where a dialog with parent will appear ++ if( m_pParent && m_pParent->m_nWorkArea != m_nWorkArea && IS_WIDGET_MAPPED(m_pParent->m_pWindow) ) ++ getDisplay()->getWMAdaptor()->switchToWorkArea( m_pParent->m_nWorkArea ); ++#endif ++ ++ if( isFloatGrabWindow() && ++ m_pParent && ++ m_nFloats == 0 && ++ ! getDisplay()->GetCaptureFrame() ) ++ { ++ /* #i63086# ++ * outsmart Metacity's "focus:mouse" mode ++ * which insists on taking the focus from the document ++ * to the new float. Grab focus to parent frame BEFORE ++ * showing the float (cannot grab it to the float ++ * before show). ++ */ ++ m_pParent->grabPointer( true, true ); ++ } ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ guint32 nUserTime = 0; ++ if( ! bNoActivate && (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_TOOLWINDOW)) == 0 ) ++ nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); ++ ++ //For these floating windows we don't want the main window to lose focus, and metacity has... ++ // metacity-2.24.0/src/core/window.c ++ ++ // if ((focus_window != NULL) && XSERVER_TIME_IS_BEFORE (compare, focus_window->net_wm_user_time)) ++ // "compare" window focus prevented by other activity ++ ++ // where "compare" is this window ++ ++ // which leads to... ++ ++ // /* This happens for error dialogs or alerts; these need to remain on ++ // * top, but it would be confusing to have its ancestor remain ++ // * focused. ++ // */ ++ // if (meta_window_is_ancestor_of_transient (focus_window, window)) ++ // "The focus window %s is an ancestor of the newly mapped " ++ // "window %s which isn't being focused. Unfocusing the " ++ // "ancestor.\n", ++ ++ // i.e. having a time < that of the toplevel frame means that the toplevel frame gets unfocused. ++ // awesome. ++ if( nUserTime == 0 ) ++ { ++ nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); ++ } ++ lcl_set_user_time(GTK_WINDOW(m_pWindow), nUserTime ); ++#endif ++ ++ if( ! bNoActivate && (m_nStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) ++ m_bSetFocusOnMap = true; ++ ++ gtk_widget_show( m_pWindow ); ++ ++ if( isFloatGrabWindow() ) ++ { ++ m_nFloats++; ++ if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 ) ++ { ++ grabPointer(true, true); ++ GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; ++ pKeyboardFrame->grabKeyboard(true); ++ } ++ // #i44068# reset parent's IM context ++ if( m_pParent ) ++ m_pParent->EndExtTextInput(0); ++ } ++ if( m_bWindowIsGtkPlug ) ++ askForXEmbedFocus( 0 ); ++ } ++ else ++ { ++ if( isFloatGrabWindow() ) ++ { ++ m_nFloats--; ++ if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 0) ++ { ++ GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; ++ pKeyboardFrame->grabKeyboard(false); ++ grabPointer(false); ++ } ++ } ++ gtk_widget_hide( m_pWindow ); ++ if( m_pIMHandler ) ++ m_pIMHandler->focusChanged( false ); ++ // flush here; there may be a very seldom race between ++ // the display connection used for clipboard and our connection ++ Flush(); ++ } ++ CallCallback( SALEVENT_RESIZE, NULL ); ++ TriggerPaintEvent(); ++ } ++} ++ ++void GtkSalFrame::setMinMaxSize() ++{ ++ /* #i34504# metacity (and possibly others) do not treat ++ * _NET_WM_STATE_FULLSCREEN and max_width/height independently; ++ * whether they should is undefined. So don't set the max size hint ++ * for a full screen window. ++ */ ++ if( m_pWindow && ! isChild() ) ++ { ++ GdkGeometry aGeo; ++ int aHints = 0; ++ if( m_nStyle & SAL_FRAME_STYLE_SIZEABLE ) ++ { ++ if( m_aMinSize.Width() && m_aMinSize.Height() && ! m_bFullscreen ) ++ { ++ aGeo.min_width = m_aMinSize.Width(); ++ aGeo.min_height = m_aMinSize.Height(); ++ aHints |= GDK_HINT_MIN_SIZE; ++ } ++ if( m_aMaxSize.Width() && m_aMaxSize.Height() && ! m_bFullscreen ) ++ { ++ aGeo.max_width = m_aMaxSize.Width(); ++ aGeo.max_height = m_aMaxSize.Height(); ++ aHints |= GDK_HINT_MAX_SIZE; ++ } ++ } ++ else ++ { ++ if( ! m_bFullscreen ) ++ { ++ aGeo.min_width = maGeometry.nWidth; ++ aGeo.min_height = maGeometry.nHeight; ++ aHints |= GDK_HINT_MIN_SIZE; ++ ++ aGeo.max_width = maGeometry.nWidth; ++ aGeo.max_height = maGeometry.nHeight; ++ aHints |= GDK_HINT_MAX_SIZE; ++ } ++ } ++ if( m_bFullscreen && m_aMaxSize.Width() && m_aMaxSize.Height() ) ++ { ++ aGeo.max_width = m_aMaxSize.Width(); ++ aGeo.max_height = m_aMaxSize.Height(); ++ aHints |= GDK_HINT_MAX_SIZE; ++ } ++ if( aHints ) ++ { ++ gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), ++ NULL, ++ &aGeo, ++ GdkWindowHints( aHints ) ); ++ } ++ } ++} ++ ++void GtkSalFrame::SetMaxClientSize( long nWidth, long nHeight ) ++{ ++ if( ! isChild() ) ++ { ++ m_aMaxSize = Size( nWidth, nHeight ); ++ // Show does a setMinMaxSize ++ if( IS_WIDGET_MAPPED( m_pWindow ) ) ++ setMinMaxSize(); ++ } ++} ++void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) ++{ ++ if( ! isChild() ) ++ { ++ m_aMinSize = Size( nWidth, nHeight ); ++ if( m_pWindow ) ++ { ++ widget_set_size_request(nWidth, nHeight ); ++ // Show does a setMinMaxSize ++ if( IS_WIDGET_MAPPED( m_pWindow ) ) ++ setMinMaxSize(); ++ } ++ } ++} ++ ++// FIXME: we should really be an SvpSalFrame sub-class, and ++// share their AllocateFrame ! ++void GtkSalFrame::AllocateFrame() ++{ ++#if GTK_CHECK_VERSION(3,0,0) ++ basegfx::B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight ); ++ if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize ) ++ { ++ if( aFrameSize.getX() == 0 ) ++ aFrameSize.setX( 1 ); ++ if( aFrameSize.getY() == 0 ) ++ aFrameSize.setY( 1 ); ++ m_aFrame = basebmp::createBitmapDevice(aFrameSize, true, ++ basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX); ++ m_aFrame->setDamageTracker( ++ basebmp::IBitmapDeviceDamageTrackerSharedPtr(new DamageTracker(*this)) ); ++ SAL_INFO("vcl.gtk3", "allocated m_aFrame size of " << maGeometry.nWidth << " x " << maGeometry.nHeight); ++ ++#if OSL_DEBUG_LEVEL > 0 // set background to orange ++ m_aFrame->clear( basebmp::Color( 255, 127, 0 ) ); ++#endif ++ ++ // update device in existing graphics ++ for( unsigned int i = 0; i < SAL_N_ELEMENTS( m_aGraphics ); ++i ) ++ { ++ if( !m_aGraphics[i].pGraphics ) ++ continue; ++ m_aGraphics[i].pGraphics->setDevice( m_aFrame ); ++ } ++ } ++#endif ++} ++ ++void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) ++{ ++ if( !m_pWindow || isChild( true, false ) ) ++ return; ++ ++ bool bSized = false, bMoved = false; ++ ++ if( (nFlags & ( SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT )) && ++ (nWidth > 0 && nHeight > 0 ) // sometimes stupid things happen ++ ) ++ { ++ m_bDefaultSize = false; ++ ++ if( (unsigned long)nWidth != maGeometry.nWidth || (unsigned long)nHeight != maGeometry.nHeight ) ++ bSized = true; ++ maGeometry.nWidth = nWidth; ++ maGeometry.nHeight = nHeight; ++ ++ if( isChild( false, true ) ) ++ widget_set_size_request(nWidth, nHeight); ++ else if( ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ) ++ window_resize(nWidth, nHeight); ++ setMinMaxSize(); ++ } ++ else if( m_bDefaultSize ) ++ SetDefaultSize(); ++ ++ m_bDefaultSize = false; ++ ++ if( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) ) ++ { ++ if( m_pParent ) ++ { ++ if( AllSettings::GetLayoutRTL() ) ++ nX = m_pParent->maGeometry.nWidth-maGeometry.nWidth-1-nX; ++ nX += m_pParent->maGeometry.nX; ++ nY += m_pParent->maGeometry.nY; ++ } ++ ++ if( nX != maGeometry.nX || nY != maGeometry.nY ) ++ bMoved = true; ++ maGeometry.nX = nX; ++ maGeometry.nY = nY; ++ ++ m_bDefaultPos = false; ++ ++ moveWindow( maGeometry.nX, maGeometry.nY ); ++ ++ updateScreenNumber(); ++ } ++ else if( m_bDefaultPos ) ++ Center(); ++ ++ m_bDefaultPos = false; ++ ++ if( bSized ) ++ AllocateFrame(); ++ ++ if( bSized && ! bMoved ) ++ CallCallback( SALEVENT_RESIZE, NULL ); ++ else if( bMoved && ! bSized ) ++ CallCallback( SALEVENT_MOVE, NULL ); ++ else if( bMoved && bSized ) ++ CallCallback( SALEVENT_MOVERESIZE, NULL ); ++ ++ if (bSized) ++ TriggerPaintEvent(); ++} ++ ++void GtkSalFrame::GetClientSize( long& rWidth, long& rHeight ) ++{ ++ if( m_pWindow && !(m_nState & GDK_WINDOW_STATE_ICONIFIED) ) ++ { ++ rWidth = maGeometry.nWidth; ++ rHeight = maGeometry.nHeight; ++ } ++ else ++ rWidth = rHeight = 0; ++} ++ ++void GtkSalFrame::GetWorkArea( Rectangle& rRect ) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ rRect = GetGtkSalData()->GetGtkDisplay()->getWMAdaptor()->getWorkArea( 0 ); ++#else ++ GdkScreen *pScreen = gtk_window_get_screen(GTK_WINDOW(m_pWindow)); ++ Rectangle aRetRect; ++ int max = gdk_screen_get_n_monitors (pScreen); ++ for (int i = 0; i < max; ++i) ++ { ++ GdkRectangle aRect; ++ gdk_screen_get_monitor_workarea(pScreen, i, &aRect); ++ Rectangle aMonitorRect(aRect.x, aRect.y, aRect.x+aRect.width, aRect.y+aRect.height); ++ aRetRect.Union(aMonitorRect); ++ } ++ rRect = aRetRect; ++#endif ++} ++ ++SalFrame* GtkSalFrame::GetParent() const ++{ ++ return m_pParent; ++} ++ ++void GtkSalFrame::SetWindowState( const SalFrameState* pState ) ++{ ++ if( ! m_pWindow || ! pState || isChild( true, false ) ) ++ return; ++ ++ const sal_uLong nMaxGeometryMask = ++ WINDOWSTATE_MASK_X | WINDOWSTATE_MASK_Y | ++ WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT | ++ WINDOWSTATE_MASK_MAXIMIZED_X | WINDOWSTATE_MASK_MAXIMIZED_Y | ++ WINDOWSTATE_MASK_MAXIMIZED_WIDTH | WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; ++ ++ if( (pState->mnMask & WINDOWSTATE_MASK_STATE) && ++ ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) && ++ (pState->mnState & WINDOWSTATE_STATE_MAXIMIZED) && ++ (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask ) ++ { ++ resizeWindow( pState->mnWidth, pState->mnHeight ); ++ moveWindow( pState->mnX, pState->mnY ); ++ m_bDefaultPos = m_bDefaultSize = false; ++ ++ maGeometry.nX = pState->mnMaximizedX; ++ maGeometry.nY = pState->mnMaximizedY; ++ maGeometry.nWidth = pState->mnMaximizedWidth; ++ maGeometry.nHeight = pState->mnMaximizedHeight; ++ updateScreenNumber(); ++ ++ m_nState = GdkWindowState( m_nState | GDK_WINDOW_STATE_MAXIMIZED ); ++ m_aRestorePosSize = Rectangle( Point( pState->mnX, pState->mnY ), ++ Size( pState->mnWidth, pState->mnHeight ) ); ++ CallCallback( SALEVENT_RESIZE, NULL ); ++ } ++ else if( pState->mnMask & (WINDOWSTATE_MASK_X | WINDOWSTATE_MASK_Y | ++ WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ) ) ++ { ++ sal_uInt16 nPosSizeFlags = 0; ++ long nX = pState->mnX - (m_pParent ? m_pParent->maGeometry.nX : 0); ++ long nY = pState->mnY - (m_pParent ? m_pParent->maGeometry.nY : 0); ++ if( pState->mnMask & WINDOWSTATE_MASK_X ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_X; ++ else ++ nX = maGeometry.nX - (m_pParent ? m_pParent->maGeometry.nX : 0); ++ if( pState->mnMask & WINDOWSTATE_MASK_Y ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_Y; ++ else ++ nY = maGeometry.nY - (m_pParent ? m_pParent->maGeometry.nY : 0); ++ if( pState->mnMask & WINDOWSTATE_MASK_WIDTH ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH; ++ if( pState->mnMask & WINDOWSTATE_MASK_HEIGHT ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT; ++ SetPosSize( nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags ); ++ } ++ if( pState->mnMask & WINDOWSTATE_MASK_STATE && ! isChild() ) ++ { ++ if( pState->mnState & WINDOWSTATE_STATE_MAXIMIZED ) ++ gtk_window_maximize( GTK_WINDOW(m_pWindow) ); ++ else ++ gtk_window_unmaximize( GTK_WINDOW(m_pWindow) ); ++ /* #i42379# there is no rollup state in GDK; and rolled up windows are ++ * (probably depending on the WM) reported as iconified. If we iconify a ++ * window here that was e.g. a dialog, then it will be unmapped but still ++ * not be displayed in the task list, so it's an iconified window that ++ * the user cannot get out of this state. So do not set the iconified state ++ * on windows with a parent (that is transient frames) since these tend ++ * to not be represented in an icon task list. ++ */ ++ if( (pState->mnState & WINDOWSTATE_STATE_MINIMIZED) ++ && ! m_pParent ) ++ gtk_window_iconify( GTK_WINDOW(m_pWindow) ); ++ else ++ gtk_window_deiconify( GTK_WINDOW(m_pWindow) ); ++ } ++ TriggerPaintEvent(); ++} ++ ++bool GtkSalFrame::GetWindowState( SalFrameState* pState ) ++{ ++ pState->mnState = WINDOWSTATE_STATE_NORMAL; ++ pState->mnMask = WINDOWSTATE_MASK_STATE; ++ // rollup ? gtk 2.2 does not seem to support the shaded state ++ if( (m_nState & GDK_WINDOW_STATE_ICONIFIED) ) ++ pState->mnState |= WINDOWSTATE_STATE_MINIMIZED; ++ if( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ++ { ++ pState->mnState |= WINDOWSTATE_STATE_MAXIMIZED; ++ pState->mnX = m_aRestorePosSize.Left(); ++ pState->mnY = m_aRestorePosSize.Top(); ++ pState->mnWidth = m_aRestorePosSize.GetWidth(); ++ pState->mnHeight = m_aRestorePosSize.GetHeight(); ++ pState->mnMaximizedX = maGeometry.nX; ++ pState->mnMaximizedY = maGeometry.nY; ++ pState->mnMaximizedWidth = maGeometry.nWidth; ++ pState->mnMaximizedHeight = maGeometry.nHeight; ++ pState->mnMask |= WINDOWSTATE_MASK_MAXIMIZED_X | ++ WINDOWSTATE_MASK_MAXIMIZED_Y | ++ WINDOWSTATE_MASK_MAXIMIZED_WIDTH | ++ WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; ++ } ++ else ++ { ++ pState->mnX = maGeometry.nX; ++ pState->mnY = maGeometry.nY; ++ pState->mnWidth = maGeometry.nWidth; ++ pState->mnHeight = maGeometry.nHeight; ++ } ++ pState->mnMask |= WINDOWSTATE_MASK_X | ++ WINDOWSTATE_MASK_Y | ++ WINDOWSTATE_MASK_WIDTH | ++ WINDOWSTATE_MASK_HEIGHT; ++ ++ return true; ++} ++ ++typedef enum { ++ SET_RETAIN_SIZE, ++ SET_FULLSCREEN, ++ SET_UN_FULLSCREEN ++} SetType; ++ ++void GtkSalFrame::SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSize ) ++{ ++ if( !m_pWindow ) ++ return; ++ ++ if (maGeometry.nDisplayScreenNumber == nNewScreen && eType == SET_RETAIN_SIZE) ++ return; ++ ++ GdkScreen *pScreen = NULL; ++ GdkRectangle aNewMonitor; ++ ++ bool bSpanAllScreens = nNewScreen == (unsigned int)-1; ++ m_bSpanMonitorsWhenFullscreen = bSpanAllScreens && getDisplay()->getSystem()->GetDisplayScreenCount() > 1; ++ ++ if (m_bSpanMonitorsWhenFullscreen) //span all screens ++ { ++ pScreen = gtk_widget_get_screen( m_pWindow ); ++ aNewMonitor.x = 0; ++ aNewMonitor.y = 0; ++ aNewMonitor.width = gdk_screen_get_width(pScreen); ++ aNewMonitor.height = gdk_screen_get_height(pScreen); ++ } ++ else ++ { ++ gint nMonitor; ++ bool bSameMonitor = false; ++ ++ if (!bSpanAllScreens) ++ { ++ pScreen = getDisplay()->getSystem()->getScreenMonitorFromIdx( nNewScreen, nMonitor ); ++ if (!pScreen) ++ { ++ g_warning ("Attempt to move GtkSalFrame to invalid screen %d => " ++ "fallback to current\n", nNewScreen); ++ } ++ } ++ ++ if (!pScreen) ++ { ++ pScreen = gtk_widget_get_screen( m_pWindow ); ++ bSameMonitor = true; ++ } ++ ++ // Heavy lifting, need to move screen ... ++ if( pScreen != gtk_widget_get_screen( m_pWindow )) ++ gtk_window_set_screen( GTK_WINDOW( m_pWindow ), pScreen ); ++ ++ gint nOldMonitor = gdk_screen_get_monitor_at_window( ++ pScreen, widget_get_window( m_pWindow ) ); ++ if (bSameMonitor) ++ nMonitor = nOldMonitor; ++ ++ #if OSL_DEBUG_LEVEL > 1 ++ if( nMonitor == nOldMonitor ) ++ g_warning( "An apparently pointless SetScreen - should we elide it ?" ); ++ #endif ++ ++ GdkRectangle aOldMonitor; ++ gdk_screen_get_monitor_geometry( pScreen, nOldMonitor, &aOldMonitor ); ++ gdk_screen_get_monitor_geometry( pScreen, nMonitor, &aNewMonitor ); ++ ++ maGeometry.nX = aNewMonitor.x + maGeometry.nX - aOldMonitor.x; ++ maGeometry.nY = aNewMonitor.y + maGeometry.nY - aOldMonitor.y; ++ } ++ ++ bool bResize = false; ++ bool bVisible = IS_WIDGET_MAPPED( m_pWindow ); ++ if( bVisible ) ++ Show( false ); ++ ++ if( eType == SET_FULLSCREEN ) ++ { ++ maGeometry.nX = aNewMonitor.x; ++ maGeometry.nY = aNewMonitor.y; ++ maGeometry.nWidth = aNewMonitor.width; ++ maGeometry.nHeight = aNewMonitor.height; ++ m_nStyle |= SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; ++ bResize = true; ++ ++ // #i110881# for the benefit of compiz set a max size here ++ // else setting to fullscreen fails for unknown reasons ++ m_aMaxSize.Width() = aNewMonitor.width; ++ m_aMaxSize.Height() = aNewMonitor.height; ++ } ++ ++ if( pSize && eType == SET_UN_FULLSCREEN ) ++ { ++ maGeometry.nX = pSize->Left(); ++ maGeometry.nY = pSize->Top(); ++ maGeometry.nWidth = pSize->GetWidth(); ++ maGeometry.nHeight = pSize->GetHeight(); ++ m_nStyle &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; ++ bResize = true; ++ } ++ ++ if (bResize) ++ { ++ // temporarily re-sizeable ++ if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) ++ gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); ++ window_resize(maGeometry.nWidth, maGeometry.nHeight); ++ //I wonder if we should instead leave maGeometry alone and rely on ++ //configure-event to trigger signalConfigure and set it there ++ AllocateFrame(); ++ TriggerPaintEvent(); ++ } ++ ++ gtk_window_move( GTK_WINDOW( m_pWindow ), maGeometry.nX, maGeometry.nY ); ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) ++ if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) ++#endif ++ { ++#if GTK_CHECK_VERSION(3,8,0) ++ gdk_window_set_fullscreen_mode( widget_get_window(m_pWindow), m_bSpanMonitorsWhenFullscreen ++ ? GDK_FULLSCREEN_ON_ALL_MONITORS : GDK_FULLSCREEN_ON_CURRENT_MONITOR ); ++#endif ++ if( eType == SET_FULLSCREEN ) ++ gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); ++ else if( eType == SET_UN_FULLSCREEN ) ++ gtk_window_unfullscreen( GTK_WINDOW( m_pWindow ) ); ++ } ++ ++ if( eType == SET_UN_FULLSCREEN && ++ !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) ++ gtk_window_set_resizable( GTK_WINDOW( m_pWindow ), FALSE ); ++ ++ // FIXME: we should really let gtk+ handle our widget hierarchy ... ++ if( m_pParent && gtk_widget_get_screen( m_pParent->m_pWindow ) != pScreen ) ++ SetParent( NULL ); ++ std::list< GtkSalFrame* > aChildren = m_aChildren; ++ for( std::list< GtkSalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it ) ++ (*it)->SetScreen( nNewScreen, SET_RETAIN_SIZE ); ++ ++ m_bDefaultPos = m_bDefaultSize = false; ++ updateScreenNumber(); ++ CallCallback( SALEVENT_MOVERESIZE, NULL ); ++ ++ if( bVisible ) ++ Show( true ); ++} ++ ++void GtkSalFrame::SetScreenNumber( unsigned int nNewScreen ) ++{ ++ SetScreen( nNewScreen, SET_RETAIN_SIZE ); ++} ++ ++void GtkSalFrame::updateWMClass() ++{ ++ OString aResClass = OUStringToOString(m_sWMClass, RTL_TEXTENCODING_ASCII_US); ++ const char *pResClass = !aResClass.isEmpty() ? aResClass.getStr() : ++ SalGenericSystem::getFrameClassName(); ++ Display *display; ++ ++ if (!getDisplay()->IsX11Display()) ++ return; ++ ++#if GTK_CHECK_VERSION(3,0,0) ++ display = GDK_DISPLAY_XDISPLAY(getGdkDisplay()); ++#else ++ display = getDisplay()->GetDisplay(); ++#endif ++ ++ if( IS_WIDGET_REALIZED( m_pWindow ) ) ++ { ++ XClassHint* pClass = XAllocClassHint(); ++ OString aResName = SalGenericSystem::getFrameResName(); ++ pClass->res_name = const_cast(aResName.getStr()); ++ pClass->res_class = const_cast(pResClass); ++ XSetClassHint( display, ++ widget_get_xid(m_pWindow), ++ pClass ); ++ XFree( pClass ); ++ } ++} ++ ++void GtkSalFrame::SetApplicationID( const OUString &rWMClass ) ++{ ++ if( rWMClass != m_sWMClass && ! isChild() ) ++ { ++ m_sWMClass = rWMClass; ++ updateWMClass(); ++ ++ for( std::list< GtkSalFrame* >::iterator it = m_aChildren.begin(); it != m_aChildren.end(); ++it ) ++ (*it)->SetApplicationID(rWMClass); ++ } ++} ++ ++void GtkSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen ) ++{ ++ m_bFullscreen = bFullScreen; ++ ++ if( !m_pWindow || isChild() ) ++ return; ++ ++ if( bFullScreen ) ++ { ++ m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), ++ Size( maGeometry.nWidth, maGeometry.nHeight ) ); ++ SetScreen( nScreen, SET_FULLSCREEN ); ++ } ++ else ++ { ++ SetScreen( nScreen, SET_UN_FULLSCREEN, ++ !m_aRestorePosSize.IsEmpty() ? &m_aRestorePosSize : NULL ); ++ m_aRestorePosSize = Rectangle(); ++ } ++} ++ ++/* definitions from xautolock.c (pl15) */ ++#define XAUTOLOCK_DISABLE 1 ++#define XAUTOLOCK_ENABLE 2 ++ ++void GtkSalFrame::setAutoLock( bool bLock ) ++{ ++ if( isChild() || !getDisplay()->IsX11Display() ) ++ return; ++ ++ GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(m_pWindow) ); ++ GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); ++ GdkWindow *pRootWin = gdk_screen_get_root_window( pScreen ); ++ ++ Atom nAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( pDisplay ), ++ "XAUTOLOCK_MESSAGE", False ); ++ ++ int nMessage = bLock ? XAUTOLOCK_ENABLE : XAUTOLOCK_DISABLE; ++ ++ XChangeProperty( GDK_DISPLAY_XDISPLAY( pDisplay ), ++ GDK_WINDOW_XID( pRootWin ), ++ nAtom, XA_INTEGER, ++ 8, PropModeReplace, ++ reinterpret_cast(&nMessage), ++ sizeof( nMessage ) ); ++} ++ ++#ifdef ENABLE_DBUS ++/** cookie is returned as an unsigned integer */ ++static guint ++dbus_inhibit_gsm (const gchar *appname, ++ const gchar *reason, ++ guint xid) ++{ ++ gboolean res; ++ guint cookie; ++ GError *error = NULL; ++ DBusGProxy *proxy = NULL; ++ ++ /* get the DBUS session connection */ ++ DBusGConnection *session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); ++ if (error != NULL) { ++ g_debug ("DBUS cannot connect : %s", error->message); ++ g_error_free (error); ++ return -1; ++ } ++ ++ /* get the proxy with gnome-session-manager */ ++ proxy = dbus_g_proxy_new_for_name (session_connection, ++ GSM_DBUS_SERVICE, ++ GSM_DBUS_PATH, ++ GSM_DBUS_INTERFACE); ++ if (proxy == NULL) { ++ g_debug ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); ++ return -1; ++ } ++ ++ res = dbus_g_proxy_call (proxy, ++ "Inhibit", &error, ++ G_TYPE_STRING, appname, ++ G_TYPE_UINT, xid, ++ G_TYPE_STRING, reason, ++ G_TYPE_UINT, 8, //Inhibit the session being marked as idle ++ G_TYPE_INVALID, ++ G_TYPE_UINT, &cookie, ++ G_TYPE_INVALID); ++ ++ /* check the return value */ ++ if (! res) { ++ cookie = -1; ++ g_debug ("Inhibit method failed"); ++ } ++ ++ /* check the error value */ ++ if (error != NULL) { ++ g_debug ("Inhibit problem : %s", error->message); ++ g_error_free (error); ++ cookie = -1; ++ } ++ ++ g_object_unref (G_OBJECT (proxy)); ++ return cookie; ++} ++ ++static void ++dbus_uninhibit_gsm (guint cookie) ++{ ++ gboolean res; ++ GError *error = NULL; ++ DBusGProxy *proxy = NULL; ++ DBusGConnection *session_connection = NULL; ++ ++ if (cookie == guint(-1)) { ++ g_debug ("Invalid cookie"); ++ return; ++ } ++ ++ /* get the DBUS session connection */ ++ session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); ++ if (error) { ++ g_debug ("DBUS cannot connect : %s", error->message); ++ g_error_free (error); ++ return; ++ } ++ ++ /* get the proxy with gnome-session-manager */ ++ proxy = dbus_g_proxy_new_for_name (session_connection, ++ GSM_DBUS_SERVICE, ++ GSM_DBUS_PATH, ++ GSM_DBUS_INTERFACE); ++ if (proxy == NULL) { ++ g_debug ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); ++ return; ++ } ++ ++ res = dbus_g_proxy_call (proxy, ++ "Uninhibit", ++ &error, ++ G_TYPE_UINT, cookie, ++ G_TYPE_INVALID, ++ G_TYPE_INVALID); ++ ++ /* check the return value */ ++ if (! res) { ++ g_debug ("Uninhibit method failed"); ++ } ++ ++ /* check the error value */ ++ if (error != NULL) { ++ g_debug ("Uninhibit problem : %s", error->message); ++ g_error_free (error); ++ cookie = -1; ++ } ++ g_object_unref (G_OBJECT (proxy)); ++} ++#endif ++ ++void GtkSalFrame::StartPresentation( bool bStart ) ++{ ++ setAutoLock( !bStart ); ++ ++ if( !getDisplay()->IsX11Display() ) ++ return; ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ Display *pDisplay = GDK_DISPLAY_XDISPLAY( getGdkDisplay() ); ++ ++ int nTimeout, nInterval, bPreferBlanking, bAllowExposures; ++ XGetScreenSaver( pDisplay, &nTimeout, &nInterval, ++ &bPreferBlanking, &bAllowExposures ); ++#endif ++ if( bStart ) ++ { ++#if !GTK_CHECK_VERSION(3,0,0) ++ if ( nTimeout ) ++ { ++ m_nSavedScreenSaverTimeout = nTimeout; ++ XResetScreenSaver( pDisplay ); ++ XSetScreenSaver( pDisplay, 0, nInterval, ++ bPreferBlanking, bAllowExposures ); ++ } ++#endif ++#ifdef ENABLE_DBUS ++ m_nGSMCookie = dbus_inhibit_gsm(g_get_application_name(), "presentation", ++ widget_get_xid(m_pWindow)); ++#endif ++ } ++ else ++ { ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( m_nSavedScreenSaverTimeout ) ++ XSetScreenSaver( pDisplay, m_nSavedScreenSaverTimeout, ++ nInterval, bPreferBlanking, ++ bAllowExposures ); ++#endif ++ m_nSavedScreenSaverTimeout = 0; ++#ifdef ENABLE_DBUS ++ dbus_uninhibit_gsm(m_nGSMCookie); ++#endif ++ } ++} ++ ++void GtkSalFrame::SetAlwaysOnTop( bool bOnTop ) ++{ ++ if( m_pWindow ) ++ gtk_window_set_keep_above( GTK_WINDOW( m_pWindow ), bOnTop ); ++} ++ ++void GtkSalFrame::ToTop( sal_uInt16 nFlags ) ++{ ++ if( m_pWindow ) ++ { ++ if( isChild( false, true ) ) ++ gtk_widget_grab_focus( m_pWindow ); ++ else if( IS_WIDGET_MAPPED( m_pWindow ) ) ++ { ++ if( ! (nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY) ) ++ gtk_window_present( GTK_WINDOW(m_pWindow) ); ++ else ++ { ++#if !GTK_CHECK_VERSION(3,0,0) ++ guint32 nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); ++#else ++ guint32 nUserTime = GDK_CURRENT_TIME; ++#endif ++ gdk_window_focus( widget_get_window(m_pWindow), nUserTime ); ++ } ++#if !GTK_CHECK_VERSION(3,0,0) ++ /* need to do an XSetInputFocus here because ++ * gdk_window_focus will ask a EWMH compliant WM to put the focus ++ * to our window - which it of course won't since our input hint ++ * is set to false. ++ */ ++ if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ) ++ { ++ // sad but true: this can cause an XError, we need to catch that ++ // to do this we need to synchronize with the XServer ++ GetGenericData()->ErrorTrapPush(); ++ XSetInputFocus( getDisplay()->GetDisplay(), widget_get_xid(m_pWindow), RevertToParent, CurrentTime ); ++ // fdo#46687 - an XSync should not be necessary - but for some reason it is. ++ XSync( getDisplay()->GetDisplay(), False ); ++ GetGenericData()->ErrorTrapPop(); ++ } ++#endif ++ } ++ else ++ { ++ if( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) ++ gtk_window_present( GTK_WINDOW(m_pWindow) ); ++ } ++ } ++} ++ ++void GtkSalFrame::SetPointer( PointerStyle ePointerStyle ) ++{ ++ if( m_pWindow && ePointerStyle != m_ePointerStyle ) ++ { ++ m_ePointerStyle = ePointerStyle; ++ GdkCursor *pCursor = getDisplay()->getCursor( ePointerStyle ); ++ gdk_window_set_cursor( widget_get_window(m_pWindow), pCursor ); ++ m_pCurrentCursor = pCursor; ++ ++ // #i80791# use grabPointer the same way as CaptureMouse, respective float grab ++ if( getDisplay()->MouseCaptured( this ) ) ++ grabPointer( true, false ); ++ else if( m_nFloats > 0 ) ++ grabPointer( true, true ); ++ } ++} ++ ++void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents ) ++{ ++ static const char* pEnv = getenv( "SAL_NO_MOUSEGRABS" ); ++ if (pEnv && *pEnv) ++ return; ++ ++ if (!m_pWindow) ++ return; ++ ++ const int nMask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); ++ ++#if GTK_CHECK_VERSION(3,0,0) ++ GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay()); ++ GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager); ++ if (bGrab) ++ gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, GDK_CURRENT_TIME); ++ else ++ gdk_device_ungrab(pPointer, GDK_CURRENT_TIME); ++#else ++ if( bGrab ) ++ { ++ bool bUseGdkGrab = true; ++ const std::list< SalFrame* >& rFrames = getDisplay()->getFrames(); ++ for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it ) ++ { ++ const GtkSalFrame* pFrame = static_cast< const GtkSalFrame* >(*it); ++ if( pFrame->m_bWindowIsGtkPlug ) ++ { ++ bUseGdkGrab = false; ++ break; ++ } ++ } ++ if( bUseGdkGrab ) ++ { ++ gdk_pointer_grab( widget_get_window( m_pWindow ), bOwnerEvents, ++ (GdkEventMask) nMask, NULL, m_pCurrentCursor, ++ GDK_CURRENT_TIME ); ++ } ++ else ++ { ++ // FIXME: for some unknown reason gdk_pointer_grab does not ++ // really produce owner events for GtkPlug windows ++ // the cause is yet unknown ++ ++ // this is of course a bad hack, especially as we cannot ++ // set the right cursor this way ++ XGrabPointer( getDisplay()->GetDisplay(), ++ widget_get_xid( m_pWindow ), ++ bOwnerEvents, ++ PointerMotionMask | ButtonPressMask | ButtonReleaseMask, ++ GrabModeAsync, ++ GrabModeAsync, ++ None, ++ None, ++ CurrentTime ++ ); ++ } ++ } ++ else ++ { ++ // Two GdkDisplays may be open ++ gdk_display_pointer_ungrab( getGdkDisplay(), GDK_CURRENT_TIME); ++ } ++#endif ++} ++ ++void GtkSalFrame::grabKeyboard( bool bGrab ) ++{ ++ if (!m_pWindow) ++ return; ++ ++#if GTK_CHECK_VERSION(3,0,0) ++ GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay()); ++ GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager); ++ GdkDevice* pKeyboard = gdk_device_get_associated_device(pPointer); ++ if (bGrab) ++ { ++ gdk_device_grab(pKeyboard, widget_get_window(m_pWindow), GDK_OWNERSHIP_NONE, ++ true, (GdkEventMask)(GDK_KEY_PRESS | GDK_KEY_RELEASE), NULL, GDK_CURRENT_TIME); ++ } ++ else ++ { ++ gdk_device_ungrab(pKeyboard, GDK_CURRENT_TIME); ++ } ++#else ++ if( bGrab ) ++ { ++ gdk_keyboard_grab(widget_get_window(m_pWindow), true, ++ GDK_CURRENT_TIME); ++ } ++ else ++ { ++ gdk_keyboard_ungrab(GDK_CURRENT_TIME); ++ } ++#endif ++} ++ ++void GtkSalFrame::CaptureMouse( bool bCapture ) ++{ ++ getDisplay()->CaptureMouse( bCapture ? this : NULL ); ++} ++ ++void GtkSalFrame::SetPointerPos( long nX, long nY ) ++{ ++ GtkSalFrame* pFrame = this; ++ while( pFrame && pFrame->isChild( false, true ) ) ++ pFrame = pFrame->m_pParent; ++ if( ! pFrame ) ++ return; ++ ++ GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(pFrame->m_pWindow) ); ++ GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); ++ ++ /* when the application tries to center the mouse in the dialog the ++ * window isn't mapped already. So use coordinates relative to the root window. ++ */ ++ unsigned int nWindowLeft = maGeometry.nX + nX; ++ unsigned int nWindowTop = maGeometry.nY + nY; ++ ++ XWarpPointer( GDK_DISPLAY_XDISPLAY (pDisplay), None, ++ GDK_WINDOW_XID (gdk_screen_get_root_window( pScreen ) ), ++ 0, 0, 0, 0, nWindowLeft, nWindowTop); ++ // #i38648# ask for the next motion hint ++ gint x, y; ++ GdkModifierType mask; ++ gdk_window_get_pointer( widget_get_window(pFrame->m_pWindow) , &x, &y, &mask ); ++} ++ ++void GtkSalFrame::Flush() ++{ ++#if GTK_CHECK_VERSION(3,0,0) ++ gdk_display_flush( getGdkDisplay() ); ++#else ++ XFlush (GDK_DISPLAY_XDISPLAY (getGdkDisplay())); ++#endif ++} ++ ++void GtkSalFrame::Sync() ++{ ++ gdk_display_sync( getGdkDisplay() ); ++} ++ ++#ifndef GDK_Open ++#define GDK_Open 0x1008ff6b ++#endif ++#ifndef GDK_Paste ++#define GDK_Paste 0x1008ff6d ++#endif ++#ifndef GDK_Copy ++#define GDK_Copy 0x1008ff57 ++#endif ++#ifndef GDK_Cut ++#define GDK_Cut 0x1008ff58 ++#endif ++ ++void GtkSalFrame::KeyCodeToGdkKey(const vcl::KeyCode& rKeyCode, ++ guint* pGdkKeyCode, GdkModifierType *pGdkModifiers) ++{ ++ if ( pGdkKeyCode == NULL || pGdkModifiers == NULL ) ++ return; ++ ++ // Get GDK key modifiers ++ GdkModifierType nModifiers = (GdkModifierType) 0; ++ ++ if ( rKeyCode.IsShift() ) ++ nModifiers = (GdkModifierType) ( nModifiers | GDK_SHIFT_MASK ); ++ ++ if ( rKeyCode.IsMod1() ) ++ nModifiers = (GdkModifierType) ( nModifiers | GDK_CONTROL_MASK ); ++ ++ if ( rKeyCode.IsMod2() ) ++ nModifiers = (GdkModifierType) ( nModifiers | GDK_MOD1_MASK ); ++ ++ *pGdkModifiers = nModifiers; ++ ++ // Get GDK keycode. ++ guint nKeyCode = 0; ++ ++ guint nCode = rKeyCode.GetCode(); ++ ++ if ( nCode >= KEY_0 && nCode <= KEY_9 ) ++ nKeyCode = ( nCode - KEY_0 ) + GDK_0; ++ else if ( nCode >= KEY_A && nCode <= KEY_Z ) ++ nKeyCode = ( nCode - KEY_A ) + GDK_A; ++ else if ( nCode >= KEY_F1 && nCode <= KEY_F26 ) ++ nKeyCode = ( nCode - KEY_F1 ) + GDK_F1; ++ else ++ { ++ switch( nCode ) ++ { ++ case KEY_DOWN: nKeyCode = GDK_Down; break; ++ case KEY_UP: nKeyCode = GDK_Up; break; ++ case KEY_LEFT: nKeyCode = GDK_Left; break; ++ case KEY_RIGHT: nKeyCode = GDK_Right; break; ++ case KEY_HOME: nKeyCode = GDK_Home; break; ++ case KEY_END: nKeyCode = GDK_End; break; ++ case KEY_PAGEUP: nKeyCode = GDK_Page_Up; break; ++ case KEY_PAGEDOWN: nKeyCode = GDK_Page_Down; break; ++ case KEY_RETURN: nKeyCode = GDK_Return; break; ++ case KEY_ESCAPE: nKeyCode = GDK_Escape; break; ++ case KEY_TAB: nKeyCode = GDK_Tab; break; ++ case KEY_BACKSPACE: nKeyCode = GDK_BackSpace; break; ++ case KEY_SPACE: nKeyCode = GDK_space; break; ++ case KEY_INSERT: nKeyCode = GDK_Insert; break; ++ case KEY_DELETE: nKeyCode = GDK_Delete; break; ++ case KEY_ADD: nKeyCode = GDK_plus; break; ++ case KEY_SUBTRACT: nKeyCode = GDK_minus; break; ++ case KEY_MULTIPLY: nKeyCode = GDK_asterisk; break; ++ case KEY_DIVIDE: nKeyCode = GDK_slash; break; ++ case KEY_POINT: nKeyCode = GDK_period; break; ++ case KEY_COMMA: nKeyCode = GDK_comma; break; ++ case KEY_LESS: nKeyCode = GDK_less; break; ++ case KEY_GREATER: nKeyCode = GDK_greater; break; ++ case KEY_EQUAL: nKeyCode = GDK_equal; break; ++ case KEY_FIND: nKeyCode = GDK_Find; break; ++ case KEY_CONTEXTMENU: nKeyCode = GDK_Menu; break; ++ case KEY_HELP: nKeyCode = GDK_Help; break; ++ case KEY_UNDO: nKeyCode = GDK_Undo; break; ++ case KEY_REPEAT: nKeyCode = GDK_Redo; break; ++ case KEY_DECIMAL: nKeyCode = GDK_KP_Decimal; break; ++ case KEY_TILDE: nKeyCode = GDK_asciitilde; break; ++ case KEY_QUOTELEFT: nKeyCode = GDK_quoteleft; break; ++ case KEY_BRACKETLEFT: nKeyCode = GDK_bracketleft; break; ++ case KEY_BRACKETRIGHT: nKeyCode = GDK_bracketright; break; ++ case KEY_SEMICOLON: nKeyCode = GDK_semicolon; break; ++ case KEY_QUOTERIGHT: nKeyCode = GDK_quoteright; break; ++ ++ // Special cases ++ case KEY_COPY: nKeyCode = GDK_Copy; break; ++ case KEY_CUT: nKeyCode = GDK_Cut; break; ++ case KEY_PASTE: nKeyCode = GDK_Paste; break; ++ case KEY_OPEN: nKeyCode = GDK_Open; break; ++ } ++ } ++ ++ *pGdkKeyCode = nKeyCode; ++} ++ ++OUString GtkSalFrame::GetKeyName( sal_uInt16 nKeyCode ) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ return getDisplay()->GetKeyName( nKeyCode ); ++#else ++ guint nGtkKeyCode; ++ GdkModifierType nGtkModifiers; ++ KeyCodeToGdkKey(nKeyCode, &nGtkKeyCode, &nGtkModifiers ); ++ ++ gchar* pName = gtk_accelerator_get_label(nGtkKeyCode, nGtkModifiers); ++ OUString aRet(pName, rtl_str_getLength(pName), RTL_TEXTENCODING_UTF8); ++ g_free(pName); ++ return aRet; ++#endif ++} ++ ++GdkDisplay *GtkSalFrame::getGdkDisplay() ++{ ++ return GetGtkSalData()->GetGdkDisplay(); ++} ++ ++GtkSalDisplay *GtkSalFrame::getDisplay() ++{ ++ return GetGtkSalData()->GetGtkDisplay(); ++} ++ ++SalFrame::SalPointerState GtkSalFrame::GetPointerState() ++{ ++ SalPointerState aState; ++ GdkScreen* pScreen; ++ gint x, y; ++ GdkModifierType aMask; ++ gdk_display_get_pointer( getGdkDisplay(), &pScreen, &x, &y, &aMask ); ++ aState.maPos = Point( x - maGeometry.nX, y - maGeometry.nY ); ++ aState.mnState = GetMouseModCode( aMask ); ++ return aState; ++} ++ ++KeyIndicatorState GtkSalFrame::GetIndicatorState() ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ return GetGtkSalData()->GetGtkDisplay()->GetIndicatorState(); ++#else ++ KeyIndicatorState nState = KeyIndicatorState::NONE; ++ ++ GdkKeymap *pKeyMap = gdk_keymap_get_for_display(getGdkDisplay()); ++ ++ if (gdk_keymap_get_caps_lock_state(pKeyMap)) ++ nState |= KeyIndicatorState::CAPSLOCK; ++ if (gdk_keymap_get_num_lock_state(pKeyMap)) ++ nState |= KeyIndicatorState::NUMLOCK; ++#if GTK_CHECK_VERSION(3,18,0) ++ if (gdk_keymap_get_scroll_lock_state(pKeyMap)) ++ nState |= KeyIndicatorState::SCROLLLOCK; ++#endif ++ return nState; ++#endif ++} ++ ++void GtkSalFrame::SimulateKeyPress( sal_uInt16 nKeyCode ) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ GetGtkSalData()->GetGtkDisplay()->SimulateKeyPress(nKeyCode); ++#else ++ g_warning ("missing simulate keypress %d", nKeyCode); ++#endif ++} ++ ++void GtkSalFrame::SetInputContext( SalInputContext* pContext ) ++{ ++ if( ! pContext ) ++ return; ++ ++ if( ! (pContext->mnOptions & InputContextFlags::Text) ) ++ return; ++ ++ // create a new im context ++ if( ! m_pIMHandler ) ++ m_pIMHandler = new IMHandler( this ); ++} ++ ++void GtkSalFrame::EndExtTextInput( sal_uInt16 nFlags ) ++{ ++ if( m_pIMHandler ) ++ m_pIMHandler->endExtTextInput( nFlags ); ++} ++ ++bool GtkSalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , vcl::KeyCode& ) ++{ ++ // not supported yet ++ return false; ++} ++ ++LanguageType GtkSalFrame::GetInputLanguage() ++{ ++ return LANGUAGE_DONTKNOW; ++} ++ ++void GtkSalFrame::UpdateSettings( AllSettings& rSettings ) ++{ ++ if( ! m_pWindow ) ++ return; ++ ++ GtkSalGraphics* pGraphics = static_cast(m_aGraphics[0].pGraphics); ++ bool bFreeGraphics = false; ++ if( ! pGraphics ) ++ { ++ pGraphics = static_cast(AcquireGraphics()); ++ if ( !pGraphics ) ++ { ++ SAL_WARN("vcl", "Could not get graphics - unable to update settings"); ++ return; ++ } ++ bFreeGraphics = true; ++ } ++ ++ pGraphics->updateSettings( rSettings ); ++ ++ if( bFreeGraphics ) ++ ReleaseGraphics( pGraphics ); ++} ++ ++void GtkSalFrame::Beep() ++{ ++ gdk_display_beep( getGdkDisplay() ); ++} ++ ++const SystemEnvData* GtkSalFrame::GetSystemData() const ++{ ++ return &m_aSystemData; ++} ++ ++void GtkSalFrame::SetParent( SalFrame* pNewParent ) ++{ ++ if( m_pParent ) ++ m_pParent->m_aChildren.remove( this ); ++ m_pParent = static_cast(pNewParent); ++ if( m_pParent ) ++ m_pParent->m_aChildren.push_back( this ); ++ if( ! isChild() ) ++ gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), ++ (m_pParent && ! m_pParent->isChild(true,false)) ? GTK_WINDOW(m_pParent->m_pWindow) : NULL ++ ); ++} ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ ++void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Screen nXScreen ) ++{ ++ bool bWasVisible = m_pWindow && IS_WIDGET_MAPPED(m_pWindow); ++ if( bWasVisible ) ++ Show( false ); ++ ++ if( (int)nXScreen.getXScreen() >= getDisplay()->GetXScreenCount() ) ++ nXScreen = m_nXScreen; ++ ++ SystemParentData aParentData; ++ aParentData.aWindow = aNewParent; ++ aParentData.bXEmbedSupport = bXEmbed; ++ if( aNewParent == None ) ++ { ++ aNewParent = getDisplay()->GetRootWindow(nXScreen); ++ aParentData.aWindow = None; ++ aParentData.bXEmbedSupport = false; ++ } ++ else ++ { ++ // is new parent a root window ? ++ Display* pDisp = getDisplay()->GetDisplay(); ++ int nScreens = getDisplay()->GetXScreenCount(); ++ for( int i = 0; i < nScreens; i++ ) ++ { ++ if( aNewParent == RootWindow( pDisp, i ) ) ++ { ++ nXScreen = SalX11Screen( i ); ++ aParentData.aWindow = None; ++ aParentData.bXEmbedSupport = false; ++ break; ++ } ++ } ++ } ++ ++ // free xrender resources ++ for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ ) ++ if( m_aGraphics[i].bInUse ) ++ m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen ); ++ ++ // first deinit frame ++ if( m_pIMHandler ) ++ { ++ delete m_pIMHandler; ++ m_pIMHandler = NULL; ++ } ++ if( m_pRegion ) ++ { ++ gdk_region_destroy( m_pRegion ); ++ } ++ ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ for (auto handler_id : m_aMouseSignalIds) ++ g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); ++ if( m_pFixedContainer ) ++ gtk_widget_destroy( GTK_WIDGET(m_pFixedContainer) ); ++ if( m_pEventBox ) ++ gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); ++ if( m_pWindow ) ++ gtk_widget_destroy( m_pWindow ); ++ if( m_pForeignParent ) ++ g_object_unref( G_OBJECT( m_pForeignParent ) ); ++ if( m_pForeignTopLevel ) ++ g_object_unref( G_OBJECT( m_pForeignTopLevel ) ); ++ ++ // init new window ++ m_bDefaultPos = m_bDefaultSize = false; ++ if( aParentData.aWindow != None ) ++ { ++ m_nStyle |= SAL_FRAME_STYLE_PLUG; ++ Init( &aParentData ); ++ } ++ else ++ { ++ m_nStyle &= ~SAL_FRAME_STYLE_PLUG; ++ Init( (m_pParent && m_pParent->m_nXScreen == m_nXScreen) ? m_pParent : NULL, m_nStyle ); ++ } ++ ++ // update graphics ++ for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ ) ++ { ++ if( m_aGraphics[i].bInUse ) ++ { ++ m_aGraphics[i].pGraphics->SetDrawable( widget_get_xid(m_pWindow), m_nXScreen ); ++ m_aGraphics[i].pGraphics->SetWindow( m_pWindow ); ++ } ++ } ++ ++ if( ! m_aTitle.isEmpty() ) ++ SetTitle( m_aTitle ); ++ ++ if( bWasVisible ) ++ Show( true ); ++ ++ std::list< GtkSalFrame* > aChildren = m_aChildren; ++ m_aChildren.clear(); ++ for( std::list< GtkSalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it ) ++ (*it)->createNewWindow( None, false, m_nXScreen ); ++ ++ // FIXME: SalObjects ++} ++#endif ++ ++bool GtkSalFrame::SetPluginParent( SystemParentData* pSysParent ) ++{ ++#if !GTK_CHECK_VERSION(3,0,0) ++ GetGenericData()->ErrorTrapPush(); // permanantly ignore unruly children's errors ++ createNewWindow( pSysParent->aWindow, (pSysParent->nSize > sizeof(long)) && pSysParent->bXEmbedSupport, m_nXScreen ); ++ return true; ++#else ++ (void)pSysParent; ++ //FIXME: no SetPluginParent impl. for gtk3 ++ return false; ++#endif ++} ++ ++void GtkSalFrame::ResetClipRegion() ++{ ++ if( m_pWindow ) ++ gdk_window_shape_combine_region( widget_get_window( m_pWindow ), NULL, 0, 0 ); ++} ++ ++void GtkSalFrame::BeginSetClipRegion( sal_uLong ) ++{ ++#if GTK_CHECK_VERSION(3,0,0) ++ if( m_pRegion ) ++ cairo_region_destroy( m_pRegion ); ++ m_pRegion = cairo_region_create(); ++#else ++ if( m_pRegion ) ++ gdk_region_destroy( m_pRegion ); ++ m_pRegion = gdk_region_new(); ++#endif ++} ++ ++void GtkSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) ++{ ++ if( m_pRegion ) ++ { ++ GdkRectangle aRect; ++ aRect.x = nX; ++ aRect.y = nY; ++ aRect.width = nWidth; ++ aRect.height = nHeight; ++#if GTK_CHECK_VERSION(3,0,0) ++ cairo_region_union_rectangle( m_pRegion, &aRect ); ++#else ++ gdk_region_union_with_rect( m_pRegion, &aRect ); ++#endif ++ } ++} ++ ++void GtkSalFrame::EndSetClipRegion() ++{ ++ if( m_pWindow && m_pRegion ) ++ gdk_window_shape_combine_region( widget_get_window(m_pWindow), m_pRegion, 0, 0 ); ++} ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++bool GtkSalFrame::Dispatch( const XEvent* pEvent ) ++{ ++ bool bContinueDispatch = true; ++ ++ if( pEvent->type == PropertyNotify ) ++ { ++ vcl_sal::WMAdaptor* pAdaptor = getDisplay()->getWMAdaptor(); ++ Atom nDesktopAtom = pAdaptor->getAtom( vcl_sal::WMAdaptor::NET_WM_DESKTOP ); ++ if( pEvent->xproperty.atom == nDesktopAtom && ++ pEvent->xproperty.state == PropertyNewValue ) ++ { ++ m_nWorkArea = pAdaptor->getWindowWorkArea( widget_get_xid(m_pWindow) ); ++ } ++ } ++ else if( pEvent->type == ConfigureNotify ) ++ { ++ if( m_pForeignParent && pEvent->xconfigure.window == m_aForeignParentWindow ) ++ { ++ bContinueDispatch = false; ++ gtk_window_resize( GTK_WINDOW(m_pWindow), pEvent->xconfigure.width, pEvent->xconfigure.height ); ++ if( ( sal::static_int_cast< int >(maGeometry.nWidth) != ++ pEvent->xconfigure.width ) || ++ ( sal::static_int_cast< int >(maGeometry.nHeight) != ++ pEvent->xconfigure.height ) ) ++ { ++ maGeometry.nWidth = pEvent->xconfigure.width; ++ maGeometry.nHeight = pEvent->xconfigure.height; ++ setMinMaxSize(); ++ getDisplay()->SendInternalEvent( this, NULL, SALEVENT_RESIZE ); ++ } ++ } ++ else if( m_pForeignTopLevel && pEvent->xconfigure.window == m_aForeignTopLevelWindow ) ++ { ++ bContinueDispatch = false; ++ // update position ++ int x = 0, y = 0; ++ ::Window aChild; ++ XTranslateCoordinates( getDisplay()->GetDisplay(), ++ widget_get_xid(m_pWindow), ++ getDisplay()->GetRootWindow( getDisplay()->GetDefaultXScreen() ), ++ 0, 0, ++ &x, &y, ++ &aChild ); ++ if( x != maGeometry.nX || y != maGeometry.nY ) ++ { ++ maGeometry.nX = x; ++ maGeometry.nY = y; ++ getDisplay()->SendInternalEvent( this, NULL, SALEVENT_MOVE ); ++ } ++ } ++ } ++ else if( pEvent->type == ClientMessage && ++ pEvent->xclient.message_type == getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ) && ++ pEvent->xclient.window == widget_get_xid(m_pWindow) && ++ m_bWindowIsGtkPlug ++ ) ++ { ++ // FIXME: this should not be necessary, GtkPlug should do this ++ // transparently for us ++ if( pEvent->xclient.data.l[1] == 1 || // XEMBED_WINDOW_ACTIVATE ++ pEvent->xclient.data.l[1] == 2 // XEMBED_WINDOW_DEACTIVATE ++ ) ++ { ++ GdkEventFocus aEvent; ++ aEvent.type = GDK_FOCUS_CHANGE; ++ aEvent.window = widget_get_window( m_pWindow ); ++ aEvent.send_event = gint8(TRUE); ++ aEvent.in = gint16(pEvent->xclient.data.l[1] == 1); ++ signalFocus( m_pWindow, &aEvent, this ); ++ } ++ } ++ ++ return bContinueDispatch; ++} ++#endif ++ ++gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalMouseEvent aEvent; ++ sal_uInt16 nEventType = 0; ++ switch( pEvent->type ) ++ { ++ case GDK_BUTTON_PRESS: ++ nEventType = SALEVENT_MOUSEBUTTONDOWN; ++ break; ++ case GDK_BUTTON_RELEASE: ++ nEventType = SALEVENT_MOUSEBUTTONUP; ++ break; ++ default: ++ return false; ++ } ++ switch( pEvent->button ) ++ { ++ case 1: aEvent.mnButton = MOUSE_LEFT; break; ++ case 2: aEvent.mnButton = MOUSE_MIDDLE; break; ++ case 3: aEvent.mnButton = MOUSE_RIGHT; break; ++ default: return false; ++ } ++ aEvent.mnTime = pEvent->time; ++ aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; ++ aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; ++ aEvent.mnCode = GetMouseModCode( pEvent->state ); ++ ++ bool bClosePopups = false; ++ if( pEvent->type == GDK_BUTTON_PRESS && ++ (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) == 0 ++ ) ++ { ++ if( m_nFloats > 0 ) ++ { ++ // close popups if user clicks outside our application ++ gint x, y; ++ bClosePopups = (gdk_display_get_window_at_pointer( GtkSalFrame::getGdkDisplay(), &x, &y ) == NULL); ++ } ++ /* #i30306# release implicit pointer grab if no popups are open; else ++ * Drag cannot grab the pointer and will fail. ++ */ ++ if( m_nFloats < 1 || bClosePopups ) ++ gdk_display_pointer_ungrab( GtkSalFrame::getGdkDisplay(), GDK_CURRENT_TIME ); ++ } ++ ++ if( pThis->m_bWindowIsGtkPlug && ++ pEvent->type == GDK_BUTTON_PRESS && ++ pEvent->button == 1 ) ++ { ++ pThis->askForXEmbedFocus( pEvent->time ); ++ } ++ ++ // --- RTL --- (mirror mouse pos) ++ if( AllSettings::GetLayoutRTL() ) ++ aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; ++ ++ vcl::DeletionListener aDel( pThis ); ++ ++ pThis->CallCallback( nEventType, &aEvent ); ++ ++ if( ! aDel.isDeleted() ) ++ { ++ if( bClosePopups ) ++ { ++ ImplSVData* pSVData = ImplGetSVData(); ++ if ( pSVData->maWinData.mpFirstFloat ) ++ { ++ static const char* pEnv = getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" ); ++ if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose) && !(pEnv && *pEnv) ) ++ pSVData->maWinData.mpFirstFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll ); ++ } ++ } ++ ++ if( ! aDel.isDeleted() ) ++ { ++ int frame_x = (int)(pEvent->x_root - pEvent->x); ++ int frame_y = (int)(pEvent->y_root - pEvent->y); ++ if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) ++ { ++ pThis->maGeometry.nX = frame_x; ++ pThis->maGeometry.nY = frame_y; ++ pThis->CallCallback( SALEVENT_MOVE, NULL ); ++ } ++ } ++ } ++ ++ return true; ++} ++ ++#if GTK_CHECK_VERSION(3,0,0) ++void GtkSalFrame::signalFlagsChanged( GtkWidget* , GtkStateFlags state, gpointer frame ) ++{ ++ //TO-DO: This isn't as helpful as I'd like it to be. The color selector puts the main ++ //windows into the backdrop, disabling everything, and the floating navigator window ++ //is also problematic. ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ bool bOldBackDrop = state & GTK_STATE_FLAG_BACKDROP; ++ bool bNewBackDrop = (gtk_widget_get_state_flags(GTK_WIDGET(pThis->m_pWindow)) & GTK_STATE_FLAG_BACKDROP); ++ if (bNewBackDrop && !bOldBackDrop) ++ { ++ pThis->GetWindow()->Disable(); ++ } ++ else if (bOldBackDrop && !bNewBackDrop) ++ { ++ pThis->GetWindow()->Enable(); ++ } ++} ++#endif ++ ++gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ GdkEventScroll* pSEvent = reinterpret_cast(pEvent); ++ ++#if GTK_CHECK_VERSION(3,0,0) ++ // gnome#726878 check for duplicate legacy scroll event ++ if (pSEvent->direction != GDK_SCROLL_SMOOTH && ++ pThis->m_nLastScrollEventTime == pSEvent->time) ++ { ++ return true; ++ } ++#endif ++ ++ SalWheelMouseEvent aEvent; ++ ++ aEvent.mnTime = pSEvent->time; ++ aEvent.mnX = (sal_uLong)pSEvent->x; ++ aEvent.mnY = (sal_uLong)pSEvent->y; ++ aEvent.mnCode = GetMouseModCode( pSEvent->state ); ++ aEvent.mnScrollLines = 3; ++ ++ switch (pSEvent->direction) ++ { ++#if GTK_CHECK_VERSION(3,0,0) ++ case GDK_SCROLL_SMOOTH: ++ { ++ double delta_x, delta_y; ++ gdk_event_get_scroll_deltas(pEvent, &delta_x, &delta_y); ++ //pick the bigger one I guess ++ aEvent.mbHorz = fabs(delta_x) > fabs(delta_y); ++ if (aEvent.mbHorz) ++ aEvent.mnDelta = -delta_x; ++ else ++ aEvent.mnDelta = -delta_y; ++ aEvent.mnScrollLines = 1; ++ pThis->m_nLastScrollEventTime = pSEvent->time; ++ break; ++ } ++#endif ++ case GDK_SCROLL_UP: ++ aEvent.mnDelta = 120; ++ aEvent.mbHorz = false; ++ break; ++ case GDK_SCROLL_DOWN: ++ aEvent.mnDelta = -120; ++ aEvent.mbHorz = false; ++ break; ++ case GDK_SCROLL_LEFT: ++ aEvent.mbHorz = true; ++ aEvent.mnDelta = 120; ++ break; ++ case GDK_SCROLL_RIGHT: ++ aEvent.mnDelta = -120; ++ aEvent.mbHorz = true; ++ break; ++ }; ++ ++ aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : 1; ++ ++ // --- RTL --- (mirror mouse pos) ++ if( AllSettings::GetLayoutRTL() ) ++ aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; ++ ++ pThis->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); ++ ++ return true; ++} ++ ++#if GTK_CHECK_VERSION(3,14,0) ++void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame) ++{ ++ gdouble x, y; ++ GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); ++ //I feel I want the first point of the sequence, not the last point which ++ //the docs say this gives, but for the moment assume we start and end ++ //within the same vcl window ++ if (gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y)) ++ { ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalSwipeEvent aEvent; ++ aEvent.mnVelocityX = velocity_x; ++ aEvent.mnVelocityY = velocity_y; ++ aEvent.mnX = x; ++ aEvent.mnY = y; ++ ++ pThis->CallCallback(SALEVENT_SWIPE, &aEvent); ++ } ++} ++ ++void GtkSalFrame::gestureLongPress(GtkGestureLongPress* gesture, gpointer frame) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ if(pThis) ++ { ++ SalLongPressEvent aEvent; ++ ++ gdouble x, y; ++ GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); ++ gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y); ++ aEvent.mnX = x; ++ aEvent.mnY = y; ++ ++ pThis->CallCallback(SALEVENT_LONGPRESS, &aEvent); ++ } ++} ++ ++#endif ++ ++gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalMouseEvent aEvent; ++ aEvent.mnTime = pEvent->time; ++ aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; ++ aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; ++ aEvent.mnCode = GetMouseModCode( pEvent->state ); ++ aEvent.mnButton = 0; ++ ++ // --- RTL --- (mirror mouse pos) ++ if( AllSettings::GetLayoutRTL() ) ++ aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; ++ ++ vcl::DeletionListener aDel( pThis ); ++ ++ pThis->CallCallback( SALEVENT_MOUSEMOVE, &aEvent ); ++ ++ if( ! aDel.isDeleted() ) ++ { ++ int frame_x = (int)(pEvent->x_root - pEvent->x); ++ int frame_y = (int)(pEvent->y_root - pEvent->y); ++ if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) ++ { ++ pThis->maGeometry.nX = frame_x; ++ pThis->maGeometry.nY = frame_y; ++ pThis->CallCallback( SALEVENT_MOVE, NULL ); ++ } ++ ++ if( ! aDel.isDeleted() ) ++ { ++ // ask for the next hint ++ gint x, y; ++ GdkModifierType mask; ++ gdk_window_get_pointer( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &x, &y, &mask ); ++ } ++ } ++ ++ return true; ++} ++ ++gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ SalMouseEvent aEvent; ++ aEvent.mnTime = pEvent->time; ++ aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; ++ aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; ++ aEvent.mnCode = GetMouseModCode( pEvent->state ); ++ aEvent.mnButton = 0; ++ ++ pThis->CallCallback( (pEvent->type == GDK_ENTER_NOTIFY) ? SALEVENT_MOUSEMOVE : SALEVENT_MOUSELEAVE, &aEvent ); ++ ++ return true; ++} ++ ++#if GTK_CHECK_VERSION(3,0,0) ++ ++cairo_t* GtkSalFrame::getCairoContext() const ++{ ++ cairo_t* cr = SvpSalGraphics::createCairoContext(m_aFrame); ++ assert(cr); ++ return cr; ++} ++ ++void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect) ++{ ++#if OSL_DEBUG_LEVEL > 1 ++ long long area = rDamageRect.getWidth() * rDamageRect.getHeight(); ++ if( area > 32 * 1024 ) ++ { ++ fprintf( stderr, "bitmap damaged %d %d (%dx%d) area %lld widget\n", ++ (int) rDamageRect.getMinX(), ++ (int) rDamageRect.getMinY(), ++ (int) rDamageRect.getWidth(), ++ (int) rDamageRect.getHeight(), ++ area ); ++ } ++#endif ++ ++ if (dumpframes) ++ { ++ static int frame; ++ OString tmp("/tmp/frame" + OString::number(frame++) + ".png"); ++ cairo_t* cr = getCairoContext(); ++ cairo_surface_write_to_png(cairo_get_target(cr), tmp.getStr()); ++ cairo_destroy(cr); ++ } ++ ++ gtk_widget_queue_draw_area(GTK_WIDGET(m_pFixedContainer), ++ rDamageRect.getMinX(), ++ rDamageRect.getMinY(), ++ rDamageRect.getWidth(), ++ rDamageRect.getHeight()); ++} ++ ++// blit our backing basebmp buffer to the target cairo context cr ++gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ cairo_save(cr); ++ ++ cairo_t* source = pThis->getCairoContext(); ++ cairo_surface_t *pSurface = cairo_get_target(source); ++ ++ cairo_set_operator( cr, CAIRO_OPERATOR_OVER ); ++ cairo_set_source_surface(cr, pSurface, 0, 0); ++ cairo_paint(cr); ++ ++ cairo_destroy(source); ++ ++ cairo_restore(cr); ++ ++ cairo_surface_flush(cairo_get_target(cr)); ++ ++ return false; ++} ++ ++void GtkSalFrame::sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer frame) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ bool bSized = false; ++ ++ if( pThis->m_bFullscreen || (pThis->m_nStyle & (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_PLUG)) == SAL_FRAME_STYLE_SIZEABLE ) ++ { ++ if( pAllocation->width != (int)pThis->maGeometry.nWidth || pAllocation->height != (int)pThis->maGeometry.nHeight ) ++ { ++ bSized = true; ++ pThis->maGeometry.nWidth = pAllocation->width; ++ pThis->maGeometry.nHeight = pAllocation->height; ++ } ++ } ++ ++ if( bSized ) ++ { ++ pThis->AllocateFrame(); ++ pThis->CallCallback( SALEVENT_RESIZE, nullptr ); ++ pThis->TriggerPaintEvent(); ++ } ++} ++ ++gboolean GtkSalFrame::signalConfigure(GtkWidget*, GdkEventConfigure* pEvent, gpointer frame) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ pThis->m_bPaintsBlocked = false; ++ ++ bool bMoved = false; ++ int x = pEvent->x, y = pEvent->y; ++ ++ /* HACK: during sizing/moving a toolbar pThis->maGeometry is actually ++ * already exact; even worse: due to the asynchronicity of configure ++ * events the borderwindow which would evaluate this event ++ * would size/move based on wrong data if we would actually evaluate ++ * this event. So let's swallow it. ++ */ ++ if( (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && ++ GtkSalFrame::getDisplay()->GetCaptureFrame() == pThis ) ++ return false; ++ ++ /* #i31785# claims we cannot trust the x,y members of the event; ++ * they are e.g. not set correctly on maximize/demaximize; ++ * yet the gdkdisplay-x11.c code handling configure_events has ++ * done this XTranslateCoordinates work since the day ~zero. ++ */ ++ if( x != pThis->maGeometry.nX || y != pThis->maGeometry.nY ) ++ { ++ bMoved = true; ++ pThis->maGeometry.nX = x; ++ pThis->maGeometry.nY = y; ++ } ++ ++ // update decoration hints ++ if( ! (pThis->m_nStyle & SAL_FRAME_STYLE_PLUG) ) ++ { ++ GdkRectangle aRect; ++ gdk_window_get_frame_extents( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &aRect ); ++ pThis->maGeometry.nTopDecoration = y - aRect.y; ++ pThis->maGeometry.nBottomDecoration = aRect.y + aRect.height - y - pEvent->height; ++ pThis->maGeometry.nLeftDecoration = x - aRect.x; ++ pThis->maGeometry.nRightDecoration = aRect.x + aRect.width - x - pEvent->width; ++ } ++ else ++ { ++ pThis->maGeometry.nTopDecoration = ++ pThis->maGeometry.nBottomDecoration = ++ pThis->maGeometry.nLeftDecoration = ++ pThis->maGeometry.nRightDecoration = 0; ++ } ++ ++ pThis->updateScreenNumber(); ++ ++ if (bMoved) ++ pThis->CallCallback(SALEVENT_MOVE, nullptr); ++ ++ return false; ++} ++#else ++gboolean GtkSalFrame::signalExpose( GtkWidget*, GdkEventExpose* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ pThis->m_bPaintsBlocked = false; ++ ++ struct SalPaintEvent aEvent( pEvent->area.x, pEvent->area.y, pEvent->area.width, pEvent->area.height ); ++ ++ pThis->CallCallback( SALEVENT_PAINT, &aEvent ); ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalConfigure( GtkWidget*, GdkEventConfigure* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ pThis->m_bPaintsBlocked = false; ++ ++ bool bMoved = false, bSized = false; ++ int x = pEvent->x, y = pEvent->y; ++ ++ /* HACK: during sizing/moving a toolbar pThis->maGeometry is actually ++ * already exact; even worse: due to the asynchronicity of configure ++ * events the borderwindow which would evaluate this event ++ * would size/move based on wrong data if we would actually evaluate ++ * this event. So let's swallow it. ++ */ ++ if( (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && ++ GtkSalFrame::getDisplay()->GetCaptureFrame() == pThis ) ++ return false; ++ ++ /* #i31785# claims we cannot trust the x,y members of the event; ++ * they are e.g. not set correctly on maximize/demaximize; ++ * yet the gdkdisplay-x11.c code handling configure_events has ++ * done this XTranslateCoordinates work since the day ~zero. ++ */ ++ if( x != pThis->maGeometry.nX || y != pThis->maGeometry.nY ) ++ { ++ bMoved = true; ++ pThis->maGeometry.nX = x; ++ pThis->maGeometry.nY = y; ++ } ++ /* #i86302# ++ * for non sizeable windows we set the min and max hint for the window manager to ++ * achieve correct sizing. However this is asynchronous and e.g. on Compiz ++ * it sometimes happens that the window gets resized to another size (some default) ++ * if we update the size here, subsequent setMinMaxSize will use this wrong size ++ * - which is not good since the window manager will now size the window back to this ++ * wrong size at some point. ++ */ ++ if( pThis->m_bFullscreen || (pThis->m_nStyle & (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_PLUG)) == SAL_FRAME_STYLE_SIZEABLE ) ++ { ++ if( pEvent->width != (int)pThis->maGeometry.nWidth || pEvent->height != (int)pThis->maGeometry.nHeight ) ++ { ++ bSized = true; ++ pThis->maGeometry.nWidth = pEvent->width; ++ pThis->maGeometry.nHeight = pEvent->height; ++ } ++ } ++ ++ // update decoration hints ++ if( ! (pThis->m_nStyle & SAL_FRAME_STYLE_PLUG) ) ++ { ++ GdkRectangle aRect; ++ gdk_window_get_frame_extents( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &aRect ); ++ pThis->maGeometry.nTopDecoration = y - aRect.y; ++ pThis->maGeometry.nBottomDecoration = aRect.y + aRect.height - y - pEvent->height; ++ pThis->maGeometry.nLeftDecoration = x - aRect.x; ++ pThis->maGeometry.nRightDecoration = aRect.x + aRect.width - x - pEvent->width; ++ } ++ else ++ { ++ pThis->maGeometry.nTopDecoration = ++ pThis->maGeometry.nBottomDecoration = ++ pThis->maGeometry.nLeftDecoration = ++ pThis->maGeometry.nRightDecoration = 0; ++ } ++ ++ pThis->updateScreenNumber(); ++ if( bSized ) ++ pThis->AllocateFrame(); ++ ++ if( bMoved && bSized ) ++ pThis->CallCallback( SALEVENT_MOVERESIZE, nullptr ); ++ else if( bMoved ) ++ pThis->CallCallback( SALEVENT_MOVE, nullptr ); ++ else if( bSized ) ++ pThis->CallCallback( SALEVENT_RESIZE, nullptr ); ++ ++ if (bSized) ++ pThis->TriggerPaintEvent(); ++ return false; ++} ++ ++#endif // GTK_CHECK_VERSION(3,0,0) ++ ++void GtkSalFrame::TriggerPaintEvent() ++{ ++ //Under gtk2 we can basically paint directly into the XWindow and on ++ //additional "expose-event" events we can re-render the missing pieces ++ // ++ //Under gtk3 we have to keep our own buffer up to date and flush it into ++ //the given cairo context on "draw". So we emit a paint event on ++ //opportune resize trigger events to initially fill our backbuffer and then ++ //keep it up to date with our direct paints and tell gtk those regions ++ //have changed and then blit them into the provided cairo context when ++ //we get the "draw" ++ // ++ //The other alternative was to always paint everything on "draw", but ++ //that duplicates the amount of drawing and is hideously slow ++#if GTK_CHECK_VERSION(3,0,0) ++ SAL_INFO("vcl.gtk3", "force painting" << 0 << "," << 0 << " " << maGeometry.nWidth << "x" << maGeometry.nHeight); ++ SalPaintEvent aPaintEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight, true); ++ CallCallback(SALEVENT_PAINT, &aPaintEvt); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pFixedContainer)); ++#endif ++} ++ ++gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalGenericInstance *pSalInstance = ++ static_cast< SalGenericInstance* >(GetSalData()->m_pInstance); ++ ++ // check if printers have changed (analogous to salframe focus handler) ++ pSalInstance->updatePrinterUpdate(); ++ ++ if( !pEvent->in ) ++ { ++ pThis->m_nKeyModifiers = 0; ++ pThis->m_bSendModChangeOnRelease = false; ++ } ++ ++ if( pThis->m_pIMHandler ) ++ pThis->m_pIMHandler->focusChanged( pEvent->in ); ++ ++ // ask for changed printers like generic implementation ++ if( pEvent->in && pSalInstance->isPrinterInit() ) ++ pSalInstance->updatePrinterUpdate(); ++ ++ // FIXME: find out who the hell steals the focus from our frame ++ // while we have the pointer grabbed, this should not come from ++ // the window manager. Is this an event that was still queued ? ++ // The focus does not seem to get set inside our process ++ ++ // in the meantime do not propagate focus get/lose if floats are open ++ if( m_nFloats == 0 ) ++ pThis->CallCallback( pEvent->in ? SALEVENT_GETFOCUS : SALEVENT_LOSEFOCUS, NULL ); ++ ++ return false; ++} ++ ++#if !GTK_CHECK_VERSION(3,8,0) ++static OString getDisplayString() ++{ ++ int nParams = rtl_getAppCommandArgCount(); ++ OUString aParam; ++ for( int i = 0; i < nParams; i++ ) ++ { ++ rtl_getAppCommandArg( i, &aParam.pData ); ++ if( i < nParams-1 && (aParam == "-display" || aParam == "--display" ) ) ++ { ++ rtl_getAppCommandArg( i+1, &aParam.pData ); ++ return OUStringToOString( aParam, osl_getThreadTextEncoding() ); ++ } ++ } ++ return OString(); ++} ++#endif ++ ++gboolean GtkSalFrame::signalMap( GtkWidget *pWidget, GdkEvent*, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++#if !GTK_CHECK_VERSION(3,8,0) ++ //Spawn off a helper program that will attempt to set this fullscreen ++ //window to span all displays. ++ if (pThis->m_bFullscreen && pThis->m_bSpanMonitorsWhenFullscreen) ++ { ++ GdkWindow* gdkwin = widget_get_window(pThis->m_pWindow); ++ if (gdkwin) ++ { ++ OUString sProgramURL( "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER "/xid-fullscreen-on-all-monitors"); ++ rtl::Bootstrap::expandMacros(sProgramURL); ++ OUString sProgram; ++ if (osl::FileBase::getSystemPathFromFileURL(sProgramURL, sProgram) == osl::File::E_None) ++ { ++ OString sFinalProgram(OUStringToOString(sProgram, osl_getThreadTextEncoding()) ++ + " " + OString::number((int)GDK_WINDOW_XID(gdkwin))); ++ OString sDisplay(getDisplayString()); ++ if (!sDisplay.isEmpty()) ++ { ++ sFinalProgram += "--display " + sDisplay; ++ } ++ int returnValue = system(sFinalProgram.getStr()); ++ (void)returnValue; ++ } ++ } ++ } ++#endif ++ ++ bool bSetFocus = pThis->m_bSetFocusOnMap; ++ pThis->m_bSetFocusOnMap = false; ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ if( bSetFocus ) ++ { ++ GetGenericData()->ErrorTrapPush(); ++ XSetInputFocus( GtkSalFrame::getDisplay()->GetDisplay(), ++ widget_get_xid(pWidget), ++ RevertToParent, CurrentTime ); ++ XSync( GtkSalFrame::getDisplay()->GetDisplay(), False ); ++ GetGenericData()->ErrorTrapPop(); ++ } ++#else ++ (void)pWidget; (void)bSetFocus; ++ //FIXME: no set input focus ... ++#endif ++ ++ pThis->CallCallback( SALEVENT_RESIZE, NULL ); ++ pThis->TriggerPaintEvent(); ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ pThis->CallCallback( SALEVENT_RESIZE, NULL ); ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ vcl::DeletionListener aDel( pThis ); ++ ++ if( pThis->m_pIMHandler ) ++ { ++ if( pThis->m_pIMHandler->handleKeyEvent( pEvent ) ) ++ return true; ++ } ++ ++ // handle modifiers ++ if( pEvent->keyval == GDK_Shift_L || pEvent->keyval == GDK_Shift_R || ++ pEvent->keyval == GDK_Control_L || pEvent->keyval == GDK_Control_R || ++ pEvent->keyval == GDK_Alt_L || pEvent->keyval == GDK_Alt_R || ++ pEvent->keyval == GDK_Meta_L || pEvent->keyval == GDK_Meta_R || ++ pEvent->keyval == GDK_Super_L || pEvent->keyval == GDK_Super_R ) ++ { ++ SalKeyModEvent aModEvt; ++ ++ sal_uInt16 nModCode = GetKeyModCode( pEvent->state ); ++ ++ aModEvt.mnModKeyCode = 0; // emit no MODKEYCHANGE events ++ if( pEvent->type == GDK_KEY_PRESS && !pThis->m_nKeyModifiers ) ++ pThis->m_bSendModChangeOnRelease = true; ++ ++ else if( pEvent->type == GDK_KEY_RELEASE && ++ pThis->m_bSendModChangeOnRelease ) ++ { ++ aModEvt.mnModKeyCode = pThis->m_nKeyModifiers; ++ pThis->m_nKeyModifiers = 0; ++ } ++ ++ sal_uInt16 nExtModMask = 0; ++ sal_uInt16 nModMask = 0; ++ // pressing just the ctrl key leads to a keysym of XK_Control but ++ // the event state does not contain ControlMask. In the release ++ // event its the other way round: it does contain the Control mask. ++ // The modifier mode therefore has to be adapted manually. ++ switch( pEvent->keyval ) ++ { ++ case GDK_Control_L: ++ nExtModMask = MODKEY_LMOD1; ++ nModMask = KEY_MOD1; ++ break; ++ case GDK_Control_R: ++ nExtModMask = MODKEY_RMOD1; ++ nModMask = KEY_MOD1; ++ break; ++ case GDK_Alt_L: ++ nExtModMask = MODKEY_LMOD2; ++ nModMask = KEY_MOD2; ++ break; ++ case GDK_Alt_R: ++ nExtModMask = MODKEY_RMOD2; ++ nModMask = KEY_MOD2; ++ break; ++ case GDK_Shift_L: ++ nExtModMask = MODKEY_LSHIFT; ++ nModMask = KEY_SHIFT; ++ break; ++ case GDK_Shift_R: ++ nExtModMask = MODKEY_RSHIFT; ++ nModMask = KEY_SHIFT; ++ break; ++ // Map Meta/Super to MOD3 modifier on all Unix systems ++ // except Mac OS X ++ case GDK_Meta_L: ++ case GDK_Super_L: ++ nExtModMask = MODKEY_LMOD3; ++ nModMask = KEY_MOD3; ++ break; ++ case GDK_Meta_R: ++ case GDK_Super_R: ++ nExtModMask = MODKEY_RMOD3; ++ nModMask = KEY_MOD3; ++ break; ++ } ++ if( pEvent->type == GDK_KEY_RELEASE ) ++ { ++ nModCode &= ~nModMask; ++ pThis->m_nKeyModifiers &= ~nExtModMask; ++ } ++ else ++ { ++ nModCode |= nModMask; ++ pThis->m_nKeyModifiers |= nExtModMask; ++ } ++ ++ aModEvt.mnCode = nModCode; ++ aModEvt.mnTime = pEvent->time; ++ ++ pThis->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt ); ++ ++ } ++ else ++ { ++ pThis->doKeyCallback( pEvent->state, ++ pEvent->keyval, ++ pEvent->hardware_keycode, ++ pEvent->group, ++ pEvent->time, ++ sal_Unicode(gdk_keyval_to_unicode( pEvent->keyval )), ++ (pEvent->type == GDK_KEY_PRESS), ++ false ); ++ if( ! aDel.isDeleted() ) ++ pThis->m_bSendModChangeOnRelease = false; ++ } ++ ++ if( !aDel.isDeleted() && pThis->m_pIMHandler ) ++ pThis->m_pIMHandler->updateIMSpotLocation(); ++ ++ return true; ++} ++ ++gboolean GtkSalFrame::signalDelete( GtkWidget*, GdkEvent*, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++#if GTK_CHECK_VERSION(3,0,0) ++ //If we went into the backdrop we disabled the toplevel window, if we ++ //receive a delete here, re-enable so we can process it ++ bool bBackDrop = (gtk_widget_get_state_flags(GTK_WIDGET(pThis->m_pWindow)) & GTK_STATE_FLAG_BACKDROP); ++ if (bBackDrop) ++ pThis->GetWindow()->Enable(); ++#endif ++ ++ pThis->CallCallback( SALEVENT_CLOSE, NULL ); ++ ++ return true; ++} ++ ++void GtkSalFrame::signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ // every frame gets an initial style set on creation ++ // do not post these as the whole application tends to ++ // redraw itself to adjust to the new style ++ // where there IS no new style resulting in tremendous unnecessary flickering ++ if( pPrevious != NULL ) ++ { ++ // signalStyleSet does NOT usually have the gdk lock ++ // so post user event to safely dispatch the SALEVENT_SETTINGSCHANGED ++ // note: settings changed for multiple frames is avoided in winproc.cxx ImplHandleSettings ++ GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_SETTINGSCHANGED ); ++ GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_FONTCHANGED ); ++ } ++ ++#if !GTK_CHECK_VERSION(3,0,0) ++ /* #i64117# gtk sets a nice background pixmap ++ * but we actually don't really want that, so save ++ * some time on the Xserver as well as prevent ++ * some paint issues ++ */ ++ GdkWindow* pWin = widget_get_window(GTK_WIDGET(pThis->getWindow())); ++ if( pWin ) ++ { ++ ::Window aWin = GDK_WINDOW_XWINDOW(pWin); ++ if( aWin != None ) ++ XSetWindowBackgroundPixmap( GtkSalFrame::getDisplay()->GetDisplay(), ++ aWin, ++ pThis->m_hBackgroundPixmap ); ++ } ++ if( ! pThis->m_pParent ) ++ { ++ // signalize theme changed for NWF caches ++ // FIXME: should be called only once for a style change ++ GtkSalGraphics::bThemeChanged = true; ++ } ++#endif ++} ++ ++gboolean GtkSalFrame::signalWindowState( GtkWidget*, GdkEvent* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ if( (pThis->m_nState & GDK_WINDOW_STATE_ICONIFIED) != (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED ) ) ++ { ++ GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_RESIZE ); ++ pThis->TriggerPaintEvent(); ++ } ++ ++ if( (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) && ++ ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) ) ++ { ++ pThis->m_aRestorePosSize = ++ Rectangle( Point( pThis->maGeometry.nX, pThis->maGeometry.nY ), ++ Size( pThis->maGeometry.nWidth, pThis->maGeometry.nHeight ) ); ++ } ++ pThis->m_nState = pEvent->window_state.new_window_state; ++ ++ #if OSL_DEBUG_LEVEL > 1 ++ if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) ++ { ++ fprintf( stderr, "window %p %s full screen state\n", ++ pThis, ++ (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); ++ } ++ #endif ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalVisibility( GtkWidget*, GdkEventVisibility* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ pThis->m_nVisibility = pEvent->state; ++ return true; ++} ++ ++void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ if( pObj == pThis->m_pWindow ) ++ { ++ pThis->m_pFixedContainer = NULL; ++ pThis->m_pEventBox = NULL; ++ pThis->m_pWindow = NULL; ++ pThis->InvalidateGraphics(); ++ } ++} ++ ++// GtkSalFrame::IMHandler ++ ++GtkSalFrame::IMHandler::IMHandler( GtkSalFrame* pFrame ) ++: m_pFrame(pFrame), ++ m_nPrevKeyPresses( 0 ), ++ m_pIMContext( NULL ), ++ m_bFocused( true ), ++ m_bPreeditJustChanged( false ) ++{ ++ m_aInputEvent.mpTextAttr = NULL; ++ createIMContext(); ++} ++ ++GtkSalFrame::IMHandler::~IMHandler() ++{ ++ // cancel an eventual event posted to begin preedit again ++ GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ deleteIMContext(); ++} ++ ++void GtkSalFrame::IMHandler::createIMContext() ++{ ++ if( ! m_pIMContext ) ++ { ++ m_pIMContext = gtk_im_multicontext_new (); ++ g_signal_connect( m_pIMContext, "commit", ++ G_CALLBACK (signalIMCommit), this ); ++ g_signal_connect( m_pIMContext, "preedit_changed", ++ G_CALLBACK (signalIMPreeditChanged), this ); ++ g_signal_connect( m_pIMContext, "retrieve_surrounding", ++ G_CALLBACK (signalIMRetrieveSurrounding), this ); ++ g_signal_connect( m_pIMContext, "delete_surrounding", ++ G_CALLBACK (signalIMDeleteSurrounding), this ); ++ g_signal_connect( m_pIMContext, "preedit_start", ++ G_CALLBACK (signalIMPreeditStart), this ); ++ g_signal_connect( m_pIMContext, "preedit_end", ++ G_CALLBACK (signalIMPreeditEnd), this ); ++ ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_set_client_window( m_pIMContext, widget_get_window(GTK_WIDGET(m_pFrame->m_pWindow)) ); ++ gtk_im_context_focus_in( m_pIMContext ); ++ GetGenericData()->ErrorTrapPop(); ++ m_bFocused = true; ++ } ++} ++ ++void GtkSalFrame::IMHandler::deleteIMContext() ++{ ++ if( m_pIMContext ) ++ { ++ // first give IC a chance to deinitialize ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_set_client_window( m_pIMContext, NULL ); ++ GetGenericData()->ErrorTrapPop(); ++ // destroy old IC ++ g_object_unref( m_pIMContext ); ++ m_pIMContext = NULL; ++ } ++} ++ ++void GtkSalFrame::IMHandler::doCallEndExtTextInput() ++{ ++ m_aInputEvent.mpTextAttr = NULL; ++ m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); ++} ++ ++void GtkSalFrame::IMHandler::updateIMSpotLocation() ++{ ++ SalExtTextInputPosEvent aPosEvent; ++ m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvent ); ++ GdkRectangle aArea; ++ aArea.x = aPosEvent.mnX; ++ aArea.y = aPosEvent.mnY; ++ aArea.width = aPosEvent.mnWidth; ++ aArea.height = aPosEvent.mnHeight; ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_set_cursor_location( m_pIMContext, &aArea ); ++ GetGenericData()->ErrorTrapPop(); ++} ++ ++void GtkSalFrame::IMHandler::sendEmptyCommit() ++{ ++ vcl::DeletionListener aDel( m_pFrame ); ++ ++ SalExtTextInputEvent aEmptyEv; ++ aEmptyEv.mnTime = 0; ++ aEmptyEv.mpTextAttr = 0; ++ aEmptyEv.maText.clear(); ++ aEmptyEv.mnCursorPos = 0; ++ aEmptyEv.mnCursorFlags = 0; ++ aEmptyEv.mbOnlyCursor = False; ++ m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEmptyEv ); ++ if( ! aDel.isDeleted() ) ++ m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); ++} ++ ++void GtkSalFrame::IMHandler::endExtTextInput( sal_uInt16 /*nFlags*/ ) ++{ ++ gtk_im_context_reset ( m_pIMContext ); ++ ++ if( m_aInputEvent.mpTextAttr ) ++ { ++ vcl::DeletionListener aDel( m_pFrame ); ++ // delete preedit in sal (commit an empty string) ++ sendEmptyCommit(); ++ if( ! aDel.isDeleted() ) ++ { ++ // mark previous preedit state again (will e.g. be sent at focus gain) ++ m_aInputEvent.mpTextAttr = &m_aInputFlags[0]; ++ if( m_bFocused ) ++ { ++ // begin preedit again ++ GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ } ++ } ++ } ++} ++ ++void GtkSalFrame::IMHandler::focusChanged( bool bFocusIn ) ++{ ++ m_bFocused = bFocusIn; ++ if( bFocusIn ) ++ { ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_focus_in( m_pIMContext ); ++ GetGenericData()->ErrorTrapPop(); ++ if( m_aInputEvent.mpTextAttr ) ++ { ++ sendEmptyCommit(); ++ // begin preedit again ++ GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ } ++ } ++ else ++ { ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_focus_out( m_pIMContext ); ++ GetGenericData()->ErrorTrapPop(); ++ // cancel an eventual event posted to begin preedit again ++ GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ } ++} ++ ++bool GtkSalFrame::IMHandler::handleKeyEvent( GdkEventKey* pEvent ) ++{ ++ vcl::DeletionListener aDel( m_pFrame ); ++ ++ if( pEvent->type == GDK_KEY_PRESS ) ++ { ++ // Add this key press event to the list of previous key presses ++ // to which we compare key release events. If a later key release ++ // event has a matching key press event in this list, we swallow ++ // the key release because some GTK Input Methods don't swallow it ++ // for us. ++ m_aPrevKeyPresses.push_back( PreviousKeyPress(pEvent) ); ++ m_nPrevKeyPresses++; ++ ++ // Also pop off the earliest key press event if there are more than 10 ++ // already. ++ while (m_nPrevKeyPresses > 10) ++ { ++ m_aPrevKeyPresses.pop_front(); ++ m_nPrevKeyPresses--; ++ } ++ ++ GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); ++ ++ // #i51353# update spot location on every key input since we cannot ++ // know which key may activate a preedit choice window ++ updateIMSpotLocation(); ++ if( aDel.isDeleted() ) ++ return true; ++ ++ gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); ++ g_object_unref( pRef ); ++ ++ if( aDel.isDeleted() ) ++ return true; ++ ++ m_bPreeditJustChanged = false; ++ ++ if( bResult ) ++ return true; ++ else ++ { ++ DBG_ASSERT( m_nPrevKeyPresses > 0, "key press has vanished !" ); ++ if( ! m_aPrevKeyPresses.empty() ) // sanity check ++ { ++ // event was not swallowed, do not filter a following ++ // key release event ++ // note: this relies on gtk_im_context_filter_keypress ++ // returning without calling a handler (in the "not swallowed" ++ // case ) which might change the previous key press list so ++ // we would pop the wrong event here ++ m_aPrevKeyPresses.pop_back(); ++ m_nPrevKeyPresses--; ++ } ++ } ++ } ++ ++ // Determine if we got an earlier key press event corresponding to this key release ++ if (pEvent->type == GDK_KEY_RELEASE) ++ { ++ GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); ++ gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); ++ g_object_unref( pRef ); ++ ++ if( aDel.isDeleted() ) ++ return true; ++ ++ m_bPreeditJustChanged = false; ++ ++ std::list::iterator iter = m_aPrevKeyPresses.begin(); ++ std::list::iterator iter_end = m_aPrevKeyPresses.end(); ++ while (iter != iter_end) ++ { ++ // If we found a corresponding previous key press event, swallow the release ++ // and remove the earlier key press from our list ++ if (*iter == pEvent) ++ { ++ m_aPrevKeyPresses.erase(iter); ++ m_nPrevKeyPresses--; ++ return true; ++ } ++ ++iter; ++ } ++ ++ if( bResult ) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* FIXME: ++* #122282# still more hacking: some IMEs never start a preedit but simply commit ++* in this case we cannot commit a single character. Workaround: do not do the ++* single key hack for enter or space if the unicode committed does not match ++*/ ++ ++static bool checkSingleKeyCommitHack( guint keyval, sal_Unicode cCode ) ++{ ++ bool bRet = true; ++ switch( keyval ) ++ { ++ case GDK_KP_Enter: ++ case GDK_Return: ++ if( cCode != '\n' && cCode != '\r' ) ++ bRet = false; ++ break; ++ case GDK_space: ++ case GDK_KP_Space: ++ if( cCode != ' ' ) ++ bRet = false; ++ break; ++ default: ++ break; ++ } ++ return bRet; ++} ++ ++void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* pContext, gchar* pText, gpointer im_handler ) ++{ ++ GtkSalFrame::IMHandler* pThis = static_cast(im_handler); ++ ++ SolarMutexGuard aGuard; ++ vcl::DeletionListener aDel( pThis->m_pFrame ); ++ { ++ const bool bWasPreedit = ++ (pThis->m_aInputEvent.mpTextAttr != 0) || ++ pThis->m_bPreeditJustChanged; ++ ++ pThis->m_aInputEvent.mnTime = 0; ++ pThis->m_aInputEvent.mpTextAttr = 0; ++ pThis->m_aInputEvent.maText = OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ); ++ pThis->m_aInputEvent.mnCursorPos = pThis->m_aInputEvent.maText.getLength(); ++ pThis->m_aInputEvent.mnCursorFlags = 0; ++ pThis->m_aInputEvent.mbOnlyCursor = False; ++ ++ pThis->m_aInputFlags.clear(); ++ ++ /* necessary HACK: all keyboard input comes in here as soon as a IMContext is set ++ * which is logical and consequent. But since even simple input like ++ * comes through the commit signal instead of signalKey ++ * and all kinds of windows only implement KeyInput (e.g. PushButtons, ++ * RadioButtons and a lot of other Controls), will send a single ++ * KeyInput/KeyUp sequence instead of an ExtText event if there ++ * never was a preedit and the text is only one character. ++ * ++ * In this case there the last ExtText event must have been ++ * SALEVENT_ENDEXTTEXTINPUT, either because of a regular commit ++ * or because there never was a preedit. ++ */ ++ bool bSingleCommit = false; ++ if( ! bWasPreedit ++ && pThis->m_aInputEvent.maText.getLength() == 1 ++ && ! pThis->m_aPrevKeyPresses.empty() ++ ) ++ { ++ const PreviousKeyPress& rKP = pThis->m_aPrevKeyPresses.back(); ++ sal_Unicode aOrigCode = pThis->m_aInputEvent.maText[0]; ++ ++ if( checkSingleKeyCommitHack( rKP.keyval, aOrigCode ) ) ++ { ++ pThis->m_pFrame->doKeyCallback( rKP.state, rKP.keyval, rKP.hardware_keycode, rKP.group, rKP.time, aOrigCode, true, true ); ++ bSingleCommit = true; ++ } ++ } ++ if( ! bSingleCommit ) ++ { ++ pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); ++ if( ! aDel.isDeleted() ) ++ pThis->doCallEndExtTextInput(); ++ } ++ if( ! aDel.isDeleted() ) ++ { ++ // reset input event ++ pThis->m_aInputEvent.maText.clear(); ++ pThis->m_aInputEvent.mnCursorPos = 0; ++ pThis->updateIMSpotLocation(); ++ } ++ } ++#ifdef SOLARIS ++ // #i51356# workaround a solaris IIIMP bug ++ // in case of partial commits the preedit changed signal ++ // and commit signal come in wrong order ++ if( ! aDel.isDeleted() ) ++ signalIMPreeditChanged( pContext, im_handler ); ++#else ++ (void) pContext; ++#endif ++} ++ ++void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_handler ) ++{ ++ GtkSalFrame::IMHandler* pThis = static_cast(im_handler); ++ ++ char* pText = NULL; ++ PangoAttrList* pAttrs = NULL; ++ gint nCursorPos = 0; ++ ++ gtk_im_context_get_preedit_string( pThis->m_pIMContext, ++ &pText, ++ &pAttrs, ++ &nCursorPos ); ++ if( pText && ! *pText ) // empty string ++ { ++ // change from nothing to nothing -> do not start preedit ++ // e.g. this will activate input into a calc cell without ++ // user input ++ if( pThis->m_aInputEvent.maText.getLength() == 0 ) ++ { ++ g_free( pText ); ++ pango_attr_list_unref( pAttrs ); ++ return; ++ } ++ } ++ ++ pThis->m_bPreeditJustChanged = true; ++ ++ bool bEndPreedit = (!pText || !*pText) && pThis->m_aInputEvent.mpTextAttr != NULL; ++ pThis->m_aInputEvent.mnTime = 0; ++ pThis->m_aInputEvent.maText = pText ? OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ) : OUString(); ++ pThis->m_aInputEvent.mnCursorPos = nCursorPos; ++ pThis->m_aInputEvent.mnCursorFlags = 0; ++ pThis->m_aInputEvent.mbOnlyCursor = False; ++ ++ pThis->m_aInputFlags = std::vector( std::max( 1, (int)pThis->m_aInputEvent.maText.getLength() ), 0 ); ++ ++ PangoAttrIterator *iter = pango_attr_list_get_iterator(pAttrs); ++ do ++ { ++ GSList *attr_list = NULL; ++ GSList *tmp_list = NULL; ++ gint start, end; ++ guint sal_attr = 0; ++ ++ pango_attr_iterator_range (iter, &start, &end); ++ if (end == G_MAXINT) ++ end = pText ? strlen (pText) : 0; ++ if (end == start) ++ continue; ++ ++ start = g_utf8_pointer_to_offset (pText, pText + start); ++ end = g_utf8_pointer_to_offset (pText, pText + end); ++ ++ tmp_list = attr_list = pango_attr_iterator_get_attrs (iter); ++ while (tmp_list) ++ { ++ PangoAttribute *pango_attr = static_cast(tmp_list->data); ++ ++ switch (pango_attr->klass->type) ++ { ++ case PANGO_ATTR_BACKGROUND: ++ sal_attr |= (EXTTEXTINPUT_ATTR_HIGHLIGHT | EXTTEXTINPUT_CURSOR_INVISIBLE); ++ break; ++ case PANGO_ATTR_UNDERLINE: ++ sal_attr |= EXTTEXTINPUT_ATTR_UNDERLINE; ++ break; ++ case PANGO_ATTR_STRIKETHROUGH: ++ sal_attr |= EXTTEXTINPUT_ATTR_REDTEXT; ++ break; ++ default: ++ break; ++ } ++ pango_attribute_destroy (pango_attr); ++ tmp_list = tmp_list->next; ++ } ++ if (sal_attr == 0) ++ sal_attr |= EXTTEXTINPUT_ATTR_UNDERLINE; ++ g_slist_free (attr_list); ++ ++ // Set the sal attributes on our text ++ for (int i = start; i < end; ++i) ++ { ++ SAL_WARN_IF(i >= static_cast(pThis->m_aInputFlags.size()), ++ "vcl.gtk", "pango attrib out of range. Broken range: " ++ << start << "," << end << " Legal range: 0," ++ << pThis->m_aInputFlags.size()); ++ if (i >= static_cast(pThis->m_aInputFlags.size())) ++ continue; ++ pThis->m_aInputFlags[i] |= sal_attr; ++ } ++ } while (pango_attr_iterator_next (iter)); ++ pango_attr_iterator_destroy(iter); ++ ++ pThis->m_aInputEvent.mpTextAttr = &pThis->m_aInputFlags[0]; ++ ++ g_free( pText ); ++ pango_attr_list_unref( pAttrs ); ++ ++ SolarMutexGuard aGuard; ++ vcl::DeletionListener aDel( pThis->m_pFrame ); ++ ++ pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); ++ if( bEndPreedit && ! aDel.isDeleted() ) ++ pThis->doCallEndExtTextInput(); ++ if( ! aDel.isDeleted() ) ++ pThis->updateIMSpotLocation(); ++} ++ ++void GtkSalFrame::IMHandler::signalIMPreeditStart( GtkIMContext*, gpointer /*im_handler*/ ) ++{ ++} ++ ++void GtkSalFrame::IMHandler::signalIMPreeditEnd( GtkIMContext*, gpointer im_handler ) ++{ ++ GtkSalFrame::IMHandler* pThis = static_cast(im_handler); ++ ++ pThis->m_bPreeditJustChanged = true; ++ ++ SolarMutexGuard aGuard; ++ vcl::DeletionListener aDel( pThis->m_pFrame ); ++ pThis->doCallEndExtTextInput(); ++ if( ! aDel.isDeleted() ) ++ pThis->updateIMSpotLocation(); ++} ++ ++uno::Reference ++ FindFocus(uno::Reference< accessibility::XAccessibleContext > xContext) ++{ ++ if (!xContext.is()) ++ uno::Reference< accessibility::XAccessibleEditableText >(); ++ ++ uno::Reference xState = xContext->getAccessibleStateSet(); ++ if (xState.is()) ++ { ++ if (xState->contains(accessibility::AccessibleStateType::FOCUSED)) ++ return uno::Reference(xContext, uno::UNO_QUERY); ++ } ++ ++ for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i) ++ { ++ uno::Reference< accessibility::XAccessible > xChild = xContext->getAccessibleChild(i); ++ if (!xChild.is()) ++ continue; ++ uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext(); ++ if (!xChildContext.is()) ++ continue; ++ uno::Reference< accessibility::XAccessibleEditableText > xText = FindFocus(xChildContext); ++ if (xText.is()) ++ return xText; ++ } ++ return uno::Reference< accessibility::XAccessibleEditableText >(); ++} ++ ++static uno::Reference lcl_GetxText(vcl::Window *pFocusWin) ++{ ++ uno::Reference xText; ++ try ++ { ++ uno::Reference< accessibility::XAccessible > xAccessible( pFocusWin->GetAccessible( true ) ); ++ if (xAccessible.is()) ++ xText = FindFocus(xAccessible->getAccessibleContext()); ++ } ++ catch(const uno::Exception& e) ++ { ++ SAL_WARN( "vcl.gtk", "Exception in getting input method surrounding text: " << e.Message); ++ } ++ return xText; ++} ++ ++gboolean GtkSalFrame::IMHandler::signalIMRetrieveSurrounding( GtkIMContext* pContext, gpointer /*im_handler*/ ) ++{ ++ vcl::Window *pFocusWin = Application::GetFocusWindow(); ++ if (!pFocusWin) ++ return true; ++ ++ uno::Reference xText = lcl_GetxText(pFocusWin); ++ if (xText.is()) ++ { ++ sal_Int32 nPosition = xText->getCaretPosition(); ++ OUString sAllText = xText->getText(); ++ OString sUTF = OUStringToOString(sAllText, RTL_TEXTENCODING_UTF8); ++ OUString sCursorText(sAllText.copy(0, nPosition)); ++ gtk_im_context_set_surrounding(pContext, sUTF.getStr(), sUTF.getLength(), ++ OUStringToOString(sCursorText, RTL_TEXTENCODING_UTF8).getLength()); ++ return true; ++ } ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::IMHandler::signalIMDeleteSurrounding( GtkIMContext*, gint offset, gint nchars, ++ gpointer /*im_handler*/ ) ++{ ++ vcl::Window *pFocusWin = Application::GetFocusWindow(); ++ if (!pFocusWin) ++ return true; ++ ++ uno::Reference xText = lcl_GetxText(pFocusWin); ++ if (xText.is()) ++ { ++ sal_Int32 nPosition = xText->getCaretPosition(); ++ // #i111768# range checking ++ sal_Int32 nDeletePos = nPosition + offset; ++ sal_Int32 nDeleteEnd = nDeletePos + nchars; ++ if (nDeletePos < 0) ++ nDeletePos = 0; ++ if (nDeleteEnd < 0) ++ nDeleteEnd = 0; ++ if (nDeleteEnd > xText->getCharacterCount()) ++ nDeleteEnd = xText->getCharacterCount(); ++ ++ xText->deleteText(nDeletePos, nDeleteEnd); ++ //tdf91641 adjust cursor if deleted chars shift it forward (normal case) ++ if (nDeletePos < nPosition) ++ { ++ if (nDeleteEnd <= nPosition) ++ nPosition = nPosition - (nDeleteEnd - nDeletePos); ++ else ++ nPosition = nDeletePos; ++ ++ if (xText->getCharacterCount() >= nPosition) ++ xText->setCaretPosition( nPosition ); ++ } ++ return true; ++ } ++ ++ return false; ++} ++ ++Size GtkSalDisplay::GetScreenSize( int nDisplayScreen ) ++{ ++ Rectangle aRect = m_pSys->GetDisplayScreenPosSizePixel( nDisplayScreen ); ++ return Size( aRect.GetWidth(), aRect.GetHeight() ); ++} ++ ++Window GtkSalFrame::GetX11Window() ++{ ++ return widget_get_xid(m_pWindow); ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx +deleted file mode 100644 +index 9e03f14..0000000 +--- a/vcl/unx/gtk/window/gtksalframe.cxx ++++ /dev/null +@@ -1,4883 +0,0 @@ +-/* -*- 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/. +- * +- * This file incorporates work covered by the following license notice: +- * +- * Licensed to the Apache Software Foundation (ASF) under one or more +- * contributor license agreements. See the NOTICE file distributed +- * with this work for additional information regarding copyright +- * ownership. The ASF licenses this file to you under the Apache +- * License, Version 2.0 (the "License"); you may not use this file +- * except in compliance with the License. You may obtain a copy of +- * the License at http://www.apache.org/licenses/LICENSE-2.0 . +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#if !GTK_CHECK_VERSION(3,0,0) +-# include +-#endif +-#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) +-# include +-#endif +-#if defined ENABLE_GMENU_INTEGRATION // defined in gtksalmenu.hxx above +-# include +-#endif +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#include +-#include +- +-#if OSL_DEBUG_LEVEL > 1 +-# include +-#endif +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#if GTK_CHECK_VERSION(3,0,0) +-# include +-#endif +- +-#ifdef ENABLE_DBUS +-#include +- +-#define GSM_DBUS_SERVICE "org.gnome.SessionManager" +-#define GSM_DBUS_PATH "/org/gnome/SessionManager" +-#define GSM_DBUS_INTERFACE "org.gnome.SessionManager" +-#endif +- +-#include +- +-#if GTK_CHECK_VERSION(3,0,0) +-#define IS_WIDGET_REALIZED gtk_widget_get_realized +-#define IS_WIDGET_MAPPED gtk_widget_get_mapped +-#else +-#define IS_WIDGET_REALIZED GTK_WIDGET_REALIZED +-#define IS_WIDGET_MAPPED GTK_WIDGET_MAPPED +-#endif +- +-#if !GTK_CHECK_VERSION(3,0,0) +-#define GDK_IS_X11_DISPLAY(foo) (true) +-#endif +- +-using namespace com::sun::star; +- +-int GtkSalFrame::m_nFloats = 0; +- +-#if defined ENABLE_GMENU_INTEGRATION +-static GDBusConnection* pSessionBus = NULL; +-#endif +- +-static sal_uInt16 GetKeyModCode( guint state ) +-{ +- sal_uInt16 nCode = 0; +- if( (state & GDK_SHIFT_MASK) ) +- nCode |= KEY_SHIFT; +- if( (state & GDK_CONTROL_MASK) ) +- nCode |= KEY_MOD1; +- if( (state & GDK_MOD1_MASK) ) +- nCode |= KEY_MOD2; +- +- // Map Meta/Super keys to MOD3 modifier on all Unix systems +- // except Mac OS X +- if ( (state & GDK_META_MASK ) || ( state & GDK_SUPER_MASK ) ) +- nCode |= KEY_MOD3; +- return nCode; +-} +- +-static sal_uInt16 GetMouseModCode( guint state ) +-{ +- sal_uInt16 nCode = GetKeyModCode( state ); +- if( (state & GDK_BUTTON1_MASK) ) +- nCode |= MOUSE_LEFT; +- if( (state & GDK_BUTTON2_MASK) ) +- nCode |= MOUSE_MIDDLE; +- if( (state & GDK_BUTTON3_MASK) ) +- nCode |= MOUSE_RIGHT; +- +- return nCode; +-} +- +-static sal_uInt16 GetKeyCode( guint keyval ) +-{ +- sal_uInt16 nCode = 0; +- if( keyval >= GDK_0 && keyval <= GDK_9 ) +- nCode = KEY_0 + (keyval-GDK_0); +- else if( keyval >= GDK_KP_0 && keyval <= GDK_KP_9 ) +- nCode = KEY_0 + (keyval-GDK_KP_0); +- else if( keyval >= GDK_A && keyval <= GDK_Z ) +- nCode = KEY_A + (keyval-GDK_A ); +- else if( keyval >= GDK_a && keyval <= GDK_z ) +- nCode = KEY_A + (keyval-GDK_a ); +- else if( keyval >= GDK_F1 && keyval <= GDK_F26 ) +- { +-#if !GTK_CHECK_VERSION(3,0,0) +- if( GetGtkSalData()->GetGtkDisplay()->IsNumLockFromXS() ) +- { +- nCode = KEY_F1 + (keyval-GDK_F1); +- } +- else +-#endif +- { +- switch( keyval ) +- { +- // - - - - - Sun keyboard, see vcl/unx/source/app/saldisp.cxx +- case GDK_L2: +-#if !GTK_CHECK_VERSION(3,0,0) +- if( GetGtkSalData()->GetGtkDisplay()->GetServerVendor() == vendor_sun ) +- nCode = KEY_REPEAT; +- else +-#endif +- nCode = KEY_F12; +- break; +- case GDK_L3: nCode = KEY_PROPERTIES; break; +- case GDK_L4: nCode = KEY_UNDO; break; +- case GDK_L6: nCode = KEY_COPY; break; // KEY_F16 +- case GDK_L8: nCode = KEY_PASTE; break; // KEY_F18 +- case GDK_L10: nCode = KEY_CUT; break; // KEY_F20 +- default: +- nCode = KEY_F1 + (keyval-GDK_F1); break; +- } +- } +- } +- else +- { +- switch( keyval ) +- { +- case GDK_KP_Down: +- case GDK_Down: nCode = KEY_DOWN; break; +- case GDK_KP_Up: +- case GDK_Up: nCode = KEY_UP; break; +- case GDK_KP_Left: +- case GDK_Left: nCode = KEY_LEFT; break; +- case GDK_KP_Right: +- case GDK_Right: nCode = KEY_RIGHT; break; +- case GDK_KP_Begin: +- case GDK_KP_Home: +- case GDK_Begin: +- case GDK_Home: nCode = KEY_HOME; break; +- case GDK_KP_End: +- case GDK_End: nCode = KEY_END; break; +- case GDK_KP_Page_Up: +- case GDK_Page_Up: nCode = KEY_PAGEUP; break; +- case GDK_KP_Page_Down: +- case GDK_Page_Down: nCode = KEY_PAGEDOWN; break; +- case GDK_KP_Enter: +- case GDK_Return: nCode = KEY_RETURN; break; +- case GDK_Escape: nCode = KEY_ESCAPE; break; +- case GDK_ISO_Left_Tab: +- case GDK_KP_Tab: +- case GDK_Tab: nCode = KEY_TAB; break; +- case GDK_BackSpace: nCode = KEY_BACKSPACE; break; +- case GDK_KP_Space: +- case GDK_space: nCode = KEY_SPACE; break; +- case GDK_KP_Insert: +- case GDK_Insert: nCode = KEY_INSERT; break; +- case GDK_KP_Delete: +- case GDK_Delete: nCode = KEY_DELETE; break; +- case GDK_plus: +- case GDK_KP_Add: nCode = KEY_ADD; break; +- case GDK_minus: +- case GDK_KP_Subtract: nCode = KEY_SUBTRACT; break; +- case GDK_asterisk: +- case GDK_KP_Multiply: nCode = KEY_MULTIPLY; break; +- case GDK_slash: +- case GDK_KP_Divide: nCode = KEY_DIVIDE; break; +- case GDK_period: nCode = KEY_POINT; break; +- case GDK_decimalpoint: nCode = KEY_POINT; break; +- case GDK_comma: nCode = KEY_COMMA; break; +- case GDK_less: nCode = KEY_LESS; break; +- case GDK_greater: nCode = KEY_GREATER; break; +- case GDK_KP_Equal: +- case GDK_equal: nCode = KEY_EQUAL; break; +- case GDK_Find: nCode = KEY_FIND; break; +- case GDK_Menu: nCode = KEY_CONTEXTMENU;break; +- case GDK_Help: nCode = KEY_HELP; break; +- case GDK_Undo: nCode = KEY_UNDO; break; +- case GDK_Redo: nCode = KEY_REPEAT; break; +- case GDK_KP_Decimal: +- case GDK_KP_Separator: nCode = KEY_DECIMAL; break; +- case GDK_asciitilde: nCode = KEY_TILDE; break; +- case GDK_leftsinglequotemark: +- case GDK_quoteleft: nCode = KEY_QUOTELEFT; break; +- case GDK_bracketleft: nCode = KEY_BRACKETLEFT; break; +- case GDK_bracketright: nCode = KEY_BRACKETRIGHT; break; +- case GDK_semicolon: nCode = KEY_SEMICOLON; break; +- case GDK_quoteright: nCode = KEY_QUOTERIGHT; break; +- // some special cases, also see saldisp.cxx +- // - - - - - - - - - - - - - Apollo - - - - - - - - - - - - - 0x1000 +- case 0x1000FF02: // apXK_Copy +- nCode = KEY_COPY; +- break; +- case 0x1000FF03: // apXK_Cut +- nCode = KEY_CUT; +- break; +- case 0x1000FF04: // apXK_Paste +- nCode = KEY_PASTE; +- break; +- case 0x1000FF14: // apXK_Repeat +- nCode = KEY_REPEAT; +- break; +- // Exit, Save +- // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000 +- case 0x1000FF00: +- nCode = KEY_DELETE; +- break; +- // - - - - - - - - - - - - - - H P - - - - - - - - - - - - - 0x1000 +- case 0x1000FF73: // hpXK_DeleteChar +- nCode = KEY_DELETE; +- break; +- case 0x1000FF74: // hpXK_BackTab +- case 0x1000FF75: // hpXK_KP_BackTab +- nCode = KEY_TAB; +- break; +- // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - - +- // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004 +- case 0x1004FF02: // osfXK_Copy +- nCode = KEY_COPY; +- break; +- case 0x1004FF03: // osfXK_Cut +- nCode = KEY_CUT; +- break; +- case 0x1004FF04: // osfXK_Paste +- nCode = KEY_PASTE; +- break; +- case 0x1004FF07: // osfXK_BackTab +- nCode = KEY_TAB; +- break; +- case 0x1004FF08: // osfXK_BackSpace +- nCode = KEY_BACKSPACE; +- break; +- case 0x1004FF1B: // osfXK_Escape +- nCode = KEY_ESCAPE; +- break; +- // Up, Down, Left, Right, PageUp, PageDown +- // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - - +- // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007 +- // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - - +- // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005 +- case 0x1005FF10: // SunXK_F36 +- nCode = KEY_F11; +- break; +- case 0x1005FF11: // SunXK_F37 +- nCode = KEY_F12; +- break; +- case 0x1005FF70: // SunXK_Props +- nCode = KEY_PROPERTIES; +- break; +- case 0x1005FF71: // SunXK_Front +- nCode = KEY_FRONT; +- break; +- case 0x1005FF72: // SunXK_Copy +- nCode = KEY_COPY; +- break; +- case 0x1005FF73: // SunXK_Open +- nCode = KEY_OPEN; +- break; +- case 0x1005FF74: // SunXK_Paste +- nCode = KEY_PASTE; +- break; +- case 0x1005FF75: // SunXK_Cut +- nCode = KEY_CUT; +- break; +- } +- } +- +- return nCode; +-} +- +-static guint GetKeyValFor(GdkKeymap* pKeyMap, guint16 hardware_keycode, guint8 group) +-{ +- guint updated_keyval = 0; +- gdk_keymap_translate_keyboard_state(pKeyMap, hardware_keycode, +- (GdkModifierType)0, group, &updated_keyval, NULL, NULL, NULL); +- return updated_keyval; +-} +- +-// F10 means either KEY_F10 or KEY_MENU, which has to be decided +-// in the independent part. +-struct KeyAlternate +-{ +- sal_uInt16 nKeyCode; +- sal_Unicode nCharCode; +- KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {} +- KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {} +-}; +- +-inline KeyAlternate +-GetAlternateKeyCode( const sal_uInt16 nKeyCode ) +-{ +- KeyAlternate aAlternate; +- +- switch( nKeyCode ) +- { +- case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break; +- case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break; +- } +- +- return aAlternate; +-} +- +-#if GTK_CHECK_VERSION(3,0,0) +- +-namespace { +-/// Decouple SalFrame lifetime from damagetracker lifetime +-struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker +-{ +- DamageTracker(GtkSalFrame& rFrame) : m_rFrame(rFrame) +- {} +- +- virtual ~DamageTracker() {} +- +- virtual void damaged(const basegfx::B2IBox& rDamageRect) const SAL_OVERRIDE +- { +- m_rFrame.damaged(rDamageRect); +- } +- +- GtkSalFrame& m_rFrame; +-}; +-} +- +-static bool dumpframes = false; +-#endif +- +-void GtkSalFrame::doKeyCallback( guint state, +- guint keyval, +- guint16 hardware_keycode, +- guint8 group, +- guint32 time, +- sal_Unicode aOrigCode, +- bool bDown, +- bool bSendRelease +- ) +-{ +- SalKeyEvent aEvent; +- +- aEvent.mnTime = time; +- aEvent.mnCharCode = aOrigCode; +- aEvent.mnRepeat = 0; +- +- vcl::DeletionListener aDel( this ); +- +-#if GTK_CHECK_VERSION(3,0,0) +-#if 0 +- // shift-zero forces a re-draw and event is swallowed +- if (keyval == GDK_0) +- { +- fprintf( stderr, "force widget_queue_draw\n"); +- gtk_widget_queue_draw (m_pFixedContainer); +- return; +- } +- else if (keyval == GDK_1) +- { +- fprintf( stderr, "force repaint all\n"); +- TriggerPaintEvent(); +- return; +- } +- else if (keyval == GDK_2) +- { +- dumpframes = !dumpframes; +- fprintf(stderr, "toggle dump frames to %d\n", dumpframes); +- return; +- } +-#endif +-#endif +- +- /* +- * #i42122# translate all keys with Ctrl and/or Alt to group 0 else +- * shortcuts (e.g. Ctrl-o) will not work but be inserted by the +- * application +- * +- * #i52338# do this for all keys that the independent part has no key code +- * for +- * +- * fdo#41169 rather than use group 0, detect if there is a group which can +- * be used to input Latin text and use that if possible +- */ +- aEvent.mnCode = GetKeyCode( keyval ); +- if( aEvent.mnCode == 0 ) +- { +- gint best_group = SAL_MAX_INT32; +- +- // Try and find Latin layout +- GdkKeymap* keymap = gdk_keymap_get_default(); +- GdkKeymapKey *keys; +- gint n_keys; +- if (gdk_keymap_get_entries_for_keyval(keymap, GDK_A, &keys, &n_keys)) +- { +- // Find the lowest group that supports Latin layout +- for (gint i = 0; i < n_keys; ++i) +- { +- if (keys[i].level != 0 && keys[i].level != 1) +- continue; +- best_group = std::min(best_group, keys[i].group); +- if (best_group == 0) +- break; +- } +- g_free(keys); +- } +- +- //Unavailable, go with original group then I suppose +- if (best_group == SAL_MAX_INT32) +- best_group = group; +- +- guint updated_keyval = GetKeyValFor(keymap, hardware_keycode, best_group); +- aEvent.mnCode = GetKeyCode(updated_keyval); +- } +- +- aEvent.mnCode |= GetKeyModCode( state ); +- +- if( bDown ) +- { +- bool bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); +- // #i46889# copy AlternatKeyCode handling from generic plugin +- if( ! bHandled ) +- { +- KeyAlternate aAlternate = GetAlternateKeyCode( aEvent.mnCode ); +- if( aAlternate.nKeyCode ) +- { +- aEvent.mnCode = aAlternate.nKeyCode; +- if( aAlternate.nCharCode ) +- aEvent.mnCharCode = aAlternate.nCharCode; +- bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); +- } +- } +- if( bSendRelease && ! aDel.isDeleted() ) +- { +- CallCallback( SALEVENT_KEYUP, &aEvent ); +- } +- } +- else +- CallCallback( SALEVENT_KEYUP, &aEvent ); +-} +- +-GtkSalFrame::GraphicsHolder::~GraphicsHolder() +-{ +- delete pGraphics; +-} +- +-GtkSalFrame::GtkSalFrame( SalFrame* pParent, sal_uLong nStyle ) +- : m_nXScreen( getDisplay()->GetDefaultXScreen() ) +-{ +- getDisplay()->registerFrame( this ); +- m_bDefaultPos = true; +- m_bDefaultSize = ( (nStyle & SAL_FRAME_STYLE_SIZEABLE) && ! pParent ); +- m_bWindowIsGtkPlug = false; +-#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) +- m_pLastSyncedDbusMenu = NULL; +-#endif +- Init( pParent, nStyle ); +-} +- +-GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) +- : m_nXScreen( getDisplay()->GetDefaultXScreen() ) +-{ +- getDisplay()->registerFrame( this ); +- // permanently ignore errors from our unruly children ... +- GetGenericData()->ErrorTrapPush(); +- m_bDefaultPos = true; +- m_bDefaultSize = true; +-#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) +- m_pLastSyncedDbusMenu = NULL; +-#endif +- Init( pSysData ); +-} +- +-#ifdef ENABLE_GMENU_INTEGRATION +- +-static void +-gdk_x11_window_set_utf8_property (GdkWindow *window, +- const gchar *name, +- const gchar *value) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- GdkDisplay* display = gdk_window_get_display (window); +- +- if (value != NULL) +- { +- XChangeProperty (GDK_DISPLAY_XDISPLAY (display), +- GDK_WINDOW_XID (window), +- gdk_x11_get_xatom_by_name_for_display (display, name), +- gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8, +- PropModeReplace, reinterpret_cast(value), strlen (value)); +- } +- else +- { +- XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), +- GDK_WINDOW_XID (window), +- gdk_x11_get_xatom_by_name_for_display (display, name)); +- } +-#endif +-} +- +-// AppMenu watch functions. +- +-static void ObjectDestroyedNotify( gpointer data ) +-{ +- if ( data ) { +- g_object_unref( data ); +- } +-} +- +-#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) +-void GtkSalFrame::EnsureDbusMenuSynced() +-{ +- GtkSalMenu* pSalMenu = static_cast(GetMenu()); +- if(m_pLastSyncedDbusMenu != pSalMenu) { +- m_pLastSyncedDbusMenu = pSalMenu; +- static_cast(pSalMenu)->Activate(); +- } +-} +-#endif +- +-static void hud_activated( gboolean hud_active, gpointer user_data ) +-{ +- if ( hud_active ) +- { +- SolarMutexGuard aGuard; +- GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); +- GtkSalMenu* pSalMenu = reinterpret_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); +- +- if ( pSalMenu ) +- pSalMenu->UpdateFull(); +- } +-} +- +-static void activate_uno(GSimpleAction *action, GVariant*, gpointer) +-{ +- uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext(); +- +- uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext ); +- +- uno::Reference < css::frame::XFrame > xFrame(xDesktop->getActiveFrame()); +- if (!xFrame.is()) +- xFrame = uno::Reference < css::frame::XFrame >(xDesktop, uno::UNO_QUERY); +- +- if (!xFrame.is()) +- return; +- +- uno::Reference< css::frame::XDispatchProvider > xDispatchProvider(xFrame, uno::UNO_QUERY); +- if (!xDispatchProvider.is()) +- return; +- +- gchar *strval = NULL; +- g_object_get(action, "name", &strval, NULL); +- if (!strval) +- return; +- +- if (strcmp(strval, "New") == 0) +- { +- uno::Reference xModuleManager(frame::ModuleManager::create(xContext)); +- OUString aModuleId(xModuleManager->identify(xFrame)); +- if (aModuleId.isEmpty()) +- return; +- +- comphelper::SequenceAsHashMap lModuleDescription(xModuleManager->getByName(aModuleId)); +- OUString sFactoryService; +- lModuleDescription[OUString("ooSetupFactoryEmptyDocumentURL")] >>= sFactoryService; +- if (sFactoryService.isEmpty()) +- return; +- +- uno::Sequence < css::beans::PropertyValue > args(0); +- xDesktop->loadComponentFromURL(sFactoryService, OUString("_blank"), 0, args); +- return; +- } +- +- OUString sCommand(".uno:"); +- sCommand += OUString(strval, strlen(strval), RTL_TEXTENCODING_UTF8); +- g_free(strval); +- +- css::util::URL aCommand; +- aCommand.Complete = sCommand; +- uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext); +- xParser->parseStrict(aCommand); +- +- uno::Reference< css::frame::XDispatch > xDisp = xDispatchProvider->queryDispatch(aCommand, OUString(), 0); +- +- if (!xDisp.is()) +- return; +- +- xDisp->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >()); +-} +- +-static const GActionEntry app_entries[] = { +- { "OptionsTreeDialog", activate_uno, NULL, NULL, NULL, {0} }, +- { "About", activate_uno, NULL, NULL, NULL, {0} }, +- { "HelpIndex", activate_uno, NULL, NULL, NULL, {0} }, +- { "Quit", activate_uno, NULL, NULL, NULL, {0} }, +- { "New", activate_uno, NULL, NULL, NULL, {0} } +-}; +- +-gboolean ensure_dbus_setup( gpointer data ) +-{ +- GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( data ); +- GdkWindow* gdkWindow = widget_get_window( pSalFrame->getWindow() ); +- +- if ( gdkWindow != NULL && g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) == NULL ) +- { +- // Get a DBus session connection. +- if(!pSessionBus) +- pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); +- if( !pSessionBus ) +- return FALSE; +- +- // Create menu model and action group attached to this frame. +- GMenuModel* pMenuModel = G_MENU_MODEL( g_lo_menu_new() ); +- GActionGroup* pActionGroup = reinterpret_cast(g_lo_action_group_new( static_cast< gpointer >( pSalFrame ) )); +- +- // Generate menu paths. +- ::Window windowId = GDK_WINDOW_XID( gdkWindow ); +- gchar* aDBusWindowPath = g_strdup_printf( "/org/libreoffice/window/%lu", windowId ); +- gchar* aDBusMenubarPath = g_strdup_printf( "/org/libreoffice/window/%lu/menus/menubar", windowId ); +- +- // Set window properties. +- g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", pMenuModel, ObjectDestroyedNotify ); +- g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", pActionGroup, ObjectDestroyedNotify ); +- +- gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_ID", "org.libreoffice" ); +- gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) ); +- gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", "/org/libreoffice" ); +- gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aDBusWindowPath ); +- gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); +- +- // Publish the menu model and the action group. +- SAL_INFO("vcl.unity", "exporting menu model at " << pMenuModel << " for window " << windowId); +- pSalFrame->m_nMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, NULL); +- SAL_INFO("vcl.unity", "exporting action group at " << pActionGroup << " for window " << windowId); +- pSalFrame->m_nActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, aDBusWindowPath, pActionGroup, NULL); +- pSalFrame->m_nHudAwarenessId = hud_awareness_register( pSessionBus, aDBusMenubarPath, hud_activated, pSalFrame, NULL, NULL ); +- +- // fdo#70885 we don't want app menu under Unity +- bool bDesktopIsUnity = (SalGetDesktopEnvironment() == "UNITY"); +- +- if (!bDesktopIsUnity) +- gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APP_MENU_OBJECT_PATH", "/org/libreoffice/menus/appmenu" ); +- +- //app menu, to-do translations, block normal menus when active, honor use appmenu settings +- ResMgr* pMgr = ImplGetResMgr(); +- if( pMgr && !bDesktopIsUnity ) +- { +- GMenu *menu = g_menu_new (); +- GMenuItem* item; +- +- GMenu *firstsubmenu = g_menu_new (); +- +- OString sNew(OUStringToOString(ResId(SV_BUTTONTEXT_NEW, *pMgr).toString(), +- RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); +- +- item = g_menu_item_new(sNew.getStr(), "app.New"); +- g_menu_append_item( firstsubmenu, item ); +- g_object_unref(item); +- +- g_menu_append_section( menu, NULL, G_MENU_MODEL(firstsubmenu)); +- g_object_unref(firstsubmenu); +- +- GMenu *secondsubmenu = g_menu_new (); +- +- OString sPreferences(OUStringToOString(ResId(SV_STDTEXT_PREFERENCES, *pMgr).toString(), +- RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); +- +- item = g_menu_item_new(sPreferences.getStr(), "app.OptionsTreeDialog"); +- g_menu_append_item( secondsubmenu, item ); +- g_object_unref(item); +- +- g_menu_append_section( menu, NULL, G_MENU_MODEL(secondsubmenu)); +- g_object_unref(secondsubmenu); +- +- GMenu *thirdsubmenu = g_menu_new (); +- +- OString sHelp(OUStringToOString(ResId(SV_BUTTONTEXT_HELP, *pMgr).toString(), +- RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); +- +- item = g_menu_item_new(sHelp.getStr(), "app.HelpIndex"); +- g_menu_append_item( thirdsubmenu, item ); +- g_object_unref(item); +- +- OString sAbout(OUStringToOString(ResId(SV_STDTEXT_ABOUT, *pMgr).toString(), +- RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); +- +- item = g_menu_item_new(sAbout.getStr(), "app.About"); +- g_menu_append_item( thirdsubmenu, item ); +- g_object_unref(item); +- +- OString sQuit(OUStringToOString(ResId(SV_MENU_MAC_QUITAPP, *pMgr).toString(), +- RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); +- +- item = g_menu_item_new(sQuit.getStr(), "app.Quit"); +- g_menu_append_item( thirdsubmenu, item ); +- g_object_unref(item); +- g_menu_append_section( menu, NULL, G_MENU_MODEL(thirdsubmenu)); +- g_object_unref(thirdsubmenu); +- +- GSimpleActionGroup *group = g_simple_action_group_new (); +-#if GLIB_CHECK_VERSION(2,38,0) // g_simple_action_group_add_entries is deprecated since 2.38 +- g_action_map_add_action_entries (G_ACTION_MAP (group), app_entries, G_N_ELEMENTS (app_entries), NULL); +-#else +- g_simple_action_group_add_entries (group, app_entries, G_N_ELEMENTS (app_entries), NULL); +-#endif +- GActionGroup* pAppActionGroup = G_ACTION_GROUP(group); +- +- pSalFrame->m_nAppActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, "/org/libreoffice", pAppActionGroup, NULL); +- g_object_unref(pAppActionGroup); +- pSalFrame->m_nAppMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, "/org/libreoffice/menus/appmenu", G_MENU_MODEL (menu), NULL); +- g_object_unref(menu); +- } +- +- g_free( aDBusMenubarPath ); +- g_free( aDBusWindowPath ); +- } +- +- return FALSE; +-} +- +-void on_registrar_available( GDBusConnection * /*connection*/, +- const gchar * /*name*/, +- const gchar * /*name_owner*/, +- gpointer user_data ) +-{ +- SolarMutexGuard aGuard; +- +- GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); +- +- SalMenu* pSalMenu = pSalFrame->GetMenu(); +- +- if ( pSalMenu != NULL ) +- { +- GtkSalMenu* pGtkSalMenu = static_cast(pSalMenu); +- pGtkSalMenu->Display( true ); +- pGtkSalMenu->UpdateFull(); +- } +-} +- +-// This is called when the registrar becomes unavailable. It shows the menubar. +-void on_registrar_unavailable( GDBusConnection * /*connection*/, +- const gchar * /*name*/, +- gpointer user_data ) +-{ +- SolarMutexGuard aGuard; +- +- SAL_INFO("vcl.unity", "on_registrar_unavailable"); +- +- //pSessionBus = NULL; +- GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); +- +- SalMenu* pSalMenu = pSalFrame->GetMenu(); +- +- if ( pSalMenu ) { +- GtkSalMenu* pGtkSalMenu = static_cast< GtkSalMenu* >( pSalMenu ); +- pGtkSalMenu->Display( false ); +- } +-} +-#endif +- +-void GtkSalFrame::EnsureAppMenuWatch() +-{ +-#ifdef ENABLE_GMENU_INTEGRATION +- if ( !m_nWatcherId ) +- { +- // Get a DBus session connection. +- if ( pSessionBus == NULL ) +- { +- pSessionBus = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, NULL ); +- +- if ( pSessionBus == NULL ) +- return; +- } +- +- // Publish the menu only if AppMenu registrar is available. +- m_nWatcherId = g_bus_watch_name_on_connection( pSessionBus, +- "com.canonical.AppMenu.Registrar", +- G_BUS_NAME_WATCHER_FLAGS_NONE, +- on_registrar_available, +- on_registrar_unavailable, +- static_cast(this), +- NULL ); +- } +- +- //ensure_dbus_setup( this ); +-#else +- (void) this; // loplugin:staticmethods +-#endif +-} +- +-void GtkSalFrame::InvalidateGraphics() +-{ +- for (unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); ++i) +- { +- if( !m_aGraphics[i].pGraphics ) +- continue; +-#if !GTK_CHECK_VERSION(3,0,0) +- m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen ); +- m_aGraphics[i].pGraphics->SetWindow(NULL); +-#endif +- m_aGraphics[i].bInUse = false; +- } +-} +- +-GtkSalFrame::~GtkSalFrame() +-{ +- InvalidateGraphics(); +- +- if( m_pParent ) +- m_pParent->m_aChildren.remove( this ); +- +- getDisplay()->deregisterFrame( this ); +- +- if( m_pRegion ) +- { +-#if GTK_CHECK_VERSION(3,0,0) +- cairo_region_destroy( m_pRegion ); +-#else +- gdk_region_destroy( m_pRegion ); +-#endif +- } +- +-#if !GTK_CHECK_VERSION(3,0,0) +- if( m_hBackgroundPixmap ) +- { +- XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), +- widget_get_xid(m_pWindow), +- None ); +- XFreePixmap( getDisplay()->GetDisplay(), m_hBackgroundPixmap ); +- } +-#endif +- +- if( m_pIMHandler ) +- delete m_pIMHandler; +- +- GtkWidget *pEventWidget = getMouseEventWidget(); +- for (auto handler_id : m_aMouseSignalIds) +- g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); +- if( m_pFixedContainer ) +- gtk_widget_destroy( GTK_WIDGET( m_pFixedContainer ) ); +- if( m_pEventBox ) +- gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); +- { +- SolarMutexGuard aGuard; +-#if defined ENABLE_GMENU_INTEGRATION +- if(m_nWatcherId) +- g_bus_unwatch_name(m_nWatcherId); +-#endif +- if( m_pWindow ) +- { +- g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", NULL ); +- +-#if defined ENABLE_GMENU_INTEGRATION +- if ( pSessionBus ) +- { +- if ( m_nHudAwarenessId ) +- hud_awareness_unregister( pSessionBus, m_nHudAwarenessId ); +- if ( m_nMenuExportId ) +- g_dbus_connection_unexport_menu_model( pSessionBus, m_nMenuExportId ); +- if ( m_nAppMenuExportId ) +- g_dbus_connection_unexport_menu_model( pSessionBus, m_nAppMenuExportId ); +- if ( m_nActionGroupExportId ) +- g_dbus_connection_unexport_action_group( pSessionBus, m_nActionGroupExportId ); +- if ( m_nAppActionGroupExportId ) +- g_dbus_connection_unexport_action_group( pSessionBus, m_nAppActionGroupExportId ); +- } +-#endif +- gtk_widget_destroy( m_pWindow ); +- } +- } +- if( m_pForeignParent ) +- g_object_unref( G_OBJECT( m_pForeignParent ) ); +- if( m_pForeignTopLevel ) +- g_object_unref( G_OBJECT( m_pForeignTopLevel) ); +-} +- +-void GtkSalFrame::moveWindow( long nX, long nY ) +-{ +- if( isChild( false, true ) ) +- { +- if( m_pParent ) +- gtk_fixed_move( m_pParent->getFixedContainer(), +- m_pWindow, +- nX - m_pParent->maGeometry.nX, nY - m_pParent->maGeometry.nY ); +- } +- else +- gtk_window_move( GTK_WINDOW(m_pWindow), nX, nY ); +-} +- +-void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- gint nOrigwidth, nOrigheight; +- gtk_window_get_size(GTK_WINDOW(m_pWindow), &nOrigwidth, &nOrigheight); +- if (nWidth > nOrigwidth || nHeight > nOrigheight) +- { +- m_bPaintsBlocked = true; +- } +- gtk_widget_set_size_request(m_pWindow, nWidth, nHeight ); +-#else +- gtk_widget_set_size_request(GTK_WIDGET(m_pFixedContainer), nWidth, nHeight ); +-#endif +-} +- +-void GtkSalFrame::window_resize(long nWidth, long nHeight) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- gint nOrigwidth, nOrigheight; +- gtk_window_get_size(GTK_WINDOW(m_pWindow), &nOrigwidth, &nOrigheight); +- if (nWidth > nOrigwidth || nHeight > nOrigheight) +- { +- m_bPaintsBlocked = true; +- } +-#endif +- gtk_window_resize(GTK_WINDOW(m_pWindow), nWidth, nHeight); +-} +- +-void GtkSalFrame::resizeWindow( long nWidth, long nHeight ) +-{ +- if( isChild( false, true ) ) +- { +- widget_set_size_request(nWidth, nHeight); +- } +- else if( ! isChild( true, false ) ) +- window_resize(nWidth, nHeight); +-} +- +-#if GTK_CHECK_VERSION(3,2,0) +- +-static void +-ooo_fixed_class_init(GtkFixedClass *klass) +-{ +- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); +- widget_class->get_accessible = ooo_fixed_get_accessible; +-} +- +-#endif +- +-/* +- * Always use a sub-class of GtkFixed we can tag for a11y. This allows us to +- * utilize GAIL for the toplevel window and toolkit implementation incl. +- * key event listener support .. +- */ +- +-GType +-ooo_fixed_get_type() +-{ +- static GType type = 0; +- +- if (!type) { +- static const GTypeInfo tinfo = +- { +- sizeof (GtkFixedClass), +- nullptr, /* base init */ +- nullptr, /* base finalize */ +-#if GTK_CHECK_VERSION(3,2,0) +- reinterpret_cast(ooo_fixed_class_init), /* class init */ +-#else +- nullptr, /* class init */ +-#endif +- nullptr, /* class finalize */ +- NULL, /* class data */ +- sizeof (GtkFixed), /* instance size */ +- 0, /* nb preallocs */ +- (GInstanceInitFunc) NULL, /* instance init */ +- NULL /* value table */ +- }; +- +- type = g_type_register_static( GTK_TYPE_FIXED, "OOoFixed", +- &tinfo, (GTypeFlags) 0); +- } +- +- return type; +-} +- +-void GtkSalFrame::updateScreenNumber() +-{ +- int nScreen = 0; +- GdkScreen *pScreen = gtk_widget_get_screen( m_pWindow ); +- if( pScreen ) +- nScreen = getDisplay()->getSystem()->getScreenMonitorIdx( pScreen, maGeometry.nX, maGeometry.nY ); +- maGeometry.nDisplayScreenNumber = nScreen; +-} +- +-GtkWidget *GtkSalFrame::getMouseEventWidget() const +-{ +-#if GTK_CHECK_VERSION(3,0,0) +- return GTK_WIDGET(m_pEventBox); +-#else +- return m_pWindow; +-#endif +-} +- +-void GtkSalFrame::InitCommon() +-{ +-#if GTK_CHECK_VERSION(3,0,0) +- m_pEventBox = GTK_EVENT_BOX(gtk_event_box_new()); +- gtk_widget_add_events( GTK_WIDGET(m_pEventBox), +- GDK_ALL_EVENTS_MASK ); +- gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pEventBox) ); +- +- // add the fixed container child, +- // fixed is needed since we have to position plugin windows +- m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); +- gtk_container_add( GTK_CONTAINER(m_pEventBox), GTK_WIDGET(m_pFixedContainer) ); +-#else +- m_pEventBox = 0; +- // add the fixed container child, +- // fixed is needed since we have to position plugin windows +- m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); +- gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pFixedContainer) ); +-#endif +- +- GtkWidget *pEventWidget = getMouseEventWidget(); +- +- gtk_widget_set_app_paintable(GTK_WIDGET(m_pFixedContainer), true); +- /*non-X11 displays won't show anything at all without double-buffering +- enabled*/ +- if (GDK_IS_X11_DISPLAY(getGdkDisplay())) +- gtk_widget_set_double_buffered(GTK_WIDGET(m_pFixedContainer), false); +- gtk_widget_set_redraw_on_allocate(GTK_WIDGET(m_pFixedContainer), false); +- +- +- // connect signals +- g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this ); +- m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-press-event", G_CALLBACK(signalButton), this )); +- m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this )); +- m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this )); +-#if GTK_CHECK_VERSION(3,0,0) +- g_signal_connect( G_OBJECT(m_pFixedContainer), "draw", G_CALLBACK(signalDraw), this ); +- g_signal_connect( G_OBJECT(m_pFixedContainer), "size-allocate", G_CALLBACK(sizeAllocated), this ); +-// g_signal_connect( G_OBJECT(m_pWindow), "state-flags-changed", G_CALLBACK(signalFlagsChanged), this ); +-#if GTK_CHECK_VERSION(3,14,0) +- GtkGesture *pSwipe = gtk_gesture_swipe_new(pEventWidget); +- g_signal_connect(pSwipe, "swipe", G_CALLBACK(gestureSwipe), this); +- gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pSwipe), GTK_PHASE_TARGET); +- g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pSwipe); +- +- GtkGesture *pLongPress = gtk_gesture_long_press_new(pEventWidget); +- g_signal_connect(pLongPress, "pressed", G_CALLBACK(gestureLongPress), this); +- gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pLongPress), GTK_PHASE_TARGET); +- g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pLongPress); +- +-#endif +- +-#else +- g_signal_connect( G_OBJECT(m_pFixedContainer), "expose-event", G_CALLBACK(signalExpose), this ); +-#endif +- g_signal_connect( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "window-state-event", G_CALLBACK(signalWindowState), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "scroll-event", G_CALLBACK(signalScroll), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "leave-notify-event", G_CALLBACK(signalCrossing), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "enter-notify-event", G_CALLBACK(signalCrossing), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "visibility-notify-event", G_CALLBACK(signalVisibility), this ); +- g_signal_connect( G_OBJECT(m_pWindow), "destroy", G_CALLBACK(signalDestroy), this ); +- +- // init members +- m_pCurrentCursor = NULL; +- m_nKeyModifiers = 0; +- m_bFullscreen = false; +- m_bSpanMonitorsWhenFullscreen = false; +- m_nState = GDK_WINDOW_STATE_WITHDRAWN; +- m_nVisibility = GDK_VISIBILITY_FULLY_OBSCURED; +-#if GTK_CHECK_VERSION(3,0,0) +- m_nLastScrollEventTime = GDK_CURRENT_TIME; +-#endif +- m_bSendModChangeOnRelease = false; +- m_pIMHandler = NULL; +- m_hBackgroundPixmap = None; +- m_nSavedScreenSaverTimeout = 0; +- m_nGSMCookie = 0; +- m_nExtStyle = 0; +- m_pRegion = NULL; +- m_ePointerStyle = static_cast(0xffff); +- m_bSetFocusOnMap = false; +- m_pSalMenu = NULL; +- m_nWatcherId = 0; +- m_nMenuExportId = 0; +- m_nAppMenuExportId = 0; +- m_nActionGroupExportId = 0; +- m_nAppActionGroupExportId = 0; +- m_nHudAwarenessId = 0; +- +- gtk_widget_add_events( m_pWindow, +- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | +- GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | +- GDK_VISIBILITY_NOTIFY_MASK | GDK_SCROLL_MASK +- ); +- +- // show the widgets +-#if GTK_CHECK_VERSION(3,0,0) +- gtk_widget_show_all( GTK_WIDGET(m_pEventBox) ); +-#else +- gtk_widget_show_all( GTK_WIDGET(m_pFixedContainer) ); +-#endif +- +- // realize the window, we need an XWindow id +- gtk_widget_realize( m_pWindow ); +- +- //system data +- m_aSystemData.nSize = sizeof( SystemEnvData ); +-#if !GTK_CHECK_VERSION(3,0,0) +- GtkSalDisplay* pDisp = GetGtkSalData()->GetGtkDisplay(); +- m_aSystemData.pDisplay = pDisp->GetDisplay(); +- m_aSystemData.pVisual = pDisp->GetVisual( m_nXScreen ).GetVisual(); +- m_aSystemData.nDepth = pDisp->GetVisual( m_nXScreen ).GetDepth(); +- m_aSystemData.aColormap = pDisp->GetColormap( m_nXScreen ).GetXColormap(); +- m_aSystemData.aWindow = widget_get_xid(m_pWindow); +- m_aSystemData.aShellWindow = m_aSystemData.aWindow; +-#else +- static int nWindow = 0; +- m_aSystemData.aWindow = nWindow; +- m_aSystemData.aShellWindow = nWindow; +- ++nWindow; +-#endif +- m_aSystemData.pSalFrame = this; +- m_aSystemData.pWidget = m_pWindow; +- m_aSystemData.nScreen = m_nXScreen.getXScreen(); +- m_aSystemData.pAppContext = NULL; +- m_aSystemData.pShellWidget = m_aSystemData.pWidget; +- +- // fake an initial geometry, gets updated via configure event or SetPosSize +- if( m_bDefaultPos || m_bDefaultSize ) +- { +- Size aDefSize = calcDefaultSize(); +- maGeometry.nX = -1; +- maGeometry.nY = -1; +- maGeometry.nWidth = aDefSize.Width(); +- maGeometry.nHeight = aDefSize.Height(); +- if( m_pParent ) +- { +- // approximation +- maGeometry.nTopDecoration = m_pParent->maGeometry.nTopDecoration; +- maGeometry.nBottomDecoration = m_pParent->maGeometry.nBottomDecoration; +- maGeometry.nLeftDecoration = m_pParent->maGeometry.nLeftDecoration; +- maGeometry.nRightDecoration = m_pParent->maGeometry.nRightDecoration; +- } +- else +- { +- maGeometry.nTopDecoration = 0; +- maGeometry.nBottomDecoration = 0; +- maGeometry.nLeftDecoration = 0; +- maGeometry.nRightDecoration = 0; +- } +- } +- else +- { +- resizeWindow( maGeometry.nWidth, maGeometry.nHeight ); +- moveWindow( maGeometry.nX, maGeometry.nY ); +- } +- updateScreenNumber(); +- +- SetIcon(1); +- +-#if !GTK_CHECK_VERSION(3,0,0) +- m_nWorkArea = pDisp->getWMAdaptor()->getCurrentWorkArea(); +- /* #i64117# gtk sets a nice background pixmap +- * but we actually don't really want that, so save +- * some time on the Xserver as well as prevent +- * some paint issues +- */ +- XSetWindowBackgroundPixmap( getDisplay()->GetDisplay(), +- widget_get_xid(m_pWindow), +- m_hBackgroundPixmap ); +-#endif +-} +- +-/* Sadly gtk_window_set_accept_focus exists only since gtk 2.4 +- * for achieving the same effect we will remove the WM_TAKE_FOCUS +- * protocol from the window and set the input hint to false. +- * But gtk_window_set_accept_focus needs to be called before +- * window realization whereas the removal obviously can only happen +- * after realization. +- */ +- +-#if !GTK_CHECK_VERSION(3,0,0) +-extern "C" { +- typedef void(*setAcceptFn)( GtkWindow*, gboolean ); +- static setAcceptFn p_gtk_window_set_accept_focus = NULL; +- static bool bGetAcceptFocusFn = true; +- +- typedef void(*setUserTimeFn)( GdkWindow*, guint32 ); +- static setUserTimeFn p_gdk_x11_window_set_user_time = NULL; +- static bool bGetSetUserTimeFn = true; +-} +-#endif +- +-static void lcl_set_accept_focus( GtkWindow* pWindow, gboolean bAccept, bool bBeforeRealize ) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- if( bGetAcceptFocusFn ) +- { +- bGetAcceptFocusFn = false; +- p_gtk_window_set_accept_focus = reinterpret_cast(osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gtk_window_set_accept_focus" )); +- } +- if( p_gtk_window_set_accept_focus && bBeforeRealize ) +- p_gtk_window_set_accept_focus( pWindow, bAccept ); +- else if( ! bBeforeRealize ) +- { +- Display* pDisplay = GetGtkSalData()->GetGtkDisplay()->GetDisplay(); +- ::Window aWindow = widget_get_xid(GTK_WIDGET(pWindow)); +- XWMHints* pHints = XGetWMHints( pDisplay, aWindow ); +- if( ! pHints ) +- { +- pHints = XAllocWMHints(); +- pHints->flags = 0; +- } +- pHints->flags |= InputHint; +- pHints->input = bAccept ? True : False; +- XSetWMHints( pDisplay, aWindow, pHints ); +- XFree( pHints ); +- +- if (GetGtkSalData()->GetGtkDisplay()->getWMAdaptor()->getWindowManagerName() == "compiz") +- return; +- +- /* remove WM_TAKE_FOCUS protocol; this would usually be the +- * right thing, but gtk handles it internally whereas we +- * want to handle it ourselves (as to sometimes not get +- * the focus) +- */ +- Atom* pProtocols = NULL; +- int nProtocols = 0; +- XGetWMProtocols( pDisplay, +- aWindow, +- &pProtocols, &nProtocols ); +- if( pProtocols ) +- { +- bool bSet = false; +- Atom nTakeFocus = XInternAtom( pDisplay, "WM_TAKE_FOCUS", True ); +- if( nTakeFocus ) +- { +- for( int i = 0; i < nProtocols; i++ ) +- { +- if( pProtocols[i] == nTakeFocus ) +- { +- for( int n = i; n < nProtocols-1; n++ ) +- pProtocols[n] = pProtocols[n+1]; +- nProtocols--; +- i--; +- bSet = true; +- } +- } +- } +- if( bSet ) +- XSetWMProtocols( pDisplay, aWindow, pProtocols, nProtocols ); +- XFree( pProtocols ); +- } +- } +-#else +- gtk_window_set_accept_focus(pWindow, bAccept); +- (void)bBeforeRealize; +-#endif +-} +- +-#if !GTK_CHECK_VERSION(3,0,0) +-static void lcl_set_user_time( GtkWindow* i_pWindow, guint32 i_nTime ) +-{ +- if( bGetSetUserTimeFn ) +- { +- bGetSetUserTimeFn = false; +- p_gdk_x11_window_set_user_time = reinterpret_cast(osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_x11_window_set_user_time" )); +- } +- bool bSet = false; +- if( p_gdk_x11_window_set_user_time ) +- { +- GdkWindow* pWin = widget_get_window(GTK_WIDGET(i_pWindow)); +- if( pWin ) // only if the window is realized. +- { +- p_gdk_x11_window_set_user_time( pWin, i_nTime ); +- bSet = true; +- } +- } +- if( !bSet ) +- { +- Display* pDisplay = GetGtkSalData()->GetGtkDisplay()->GetDisplay(); +- Atom nUserTime = XInternAtom( pDisplay, "_NET_WM_USER_TIME", True ); +- if( nUserTime ) +- { +- XChangeProperty( pDisplay, widget_get_xid(GTK_WIDGET(i_pWindow)), +- nUserTime, XA_CARDINAL, 32, +- PropModeReplace, reinterpret_cast(&i_nTime), 1 ); +- } +- } +-}; +-#endif +- +-GtkSalFrame *GtkSalFrame::getFromWindow( GtkWindow *pWindow ) +-{ +- return static_cast(g_object_get_data( G_OBJECT( pWindow ), "SalFrame" )); +-} +- +-void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) +-{ +- if( nStyle & SAL_FRAME_STYLE_DEFAULT ) // ensure default style +- { +- nStyle |= SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE; +- nStyle &= ~SAL_FRAME_STYLE_FLOAT; +- } +- +- m_pParent = static_cast(pParent); +- m_pForeignParent = NULL; +- m_aForeignParentWindow = None; +- m_pForeignTopLevel = NULL; +- m_aForeignTopLevelWindow = None; +- m_nStyle = nStyle; +- +- GtkWindowType eWinType = ( (nStyle & SAL_FRAME_STYLE_FLOAT) && +- ! (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION| +- SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) +- ) +- ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL; +- +- if( nStyle & SAL_FRAME_STYLE_SYSTEMCHILD ) +- { +- m_pWindow = gtk_event_box_new(); +- if( m_pParent ) +- { +- // insert into container +- gtk_fixed_put( m_pParent->getFixedContainer(), +- m_pWindow, 0, 0 ); +- +- } +- } +- else +- { +- m_pWindow = gtk_widget_new( GTK_TYPE_WINDOW, "type", eWinType, +- "visible", FALSE, NULL ); +- } +- g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", this ); +- g_object_set_data( G_OBJECT( m_pWindow ), "libo-version", (gpointer)LIBO_VERSION_DOTTED); +- +- // force wm class hint +- m_nExtStyle = ~0; +- if (m_pParent) +- m_sWMClass = m_pParent->m_sWMClass; +- SetExtendedFrameStyle( 0 ); +- +- if( m_pParent && m_pParent->m_pWindow && ! isChild() ) +- gtk_window_set_screen( GTK_WINDOW(m_pWindow), gtk_window_get_screen( GTK_WINDOW(m_pParent->m_pWindow) ) ); +- +- if (m_pParent) +- { +- if (!(m_pParent->m_nStyle & SAL_FRAME_STYLE_PLUG)) +- gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) ); +- m_pParent->m_aChildren.push_back( this ); +- } +- +- InitCommon(); +- +- // set window type +- bool bDecoHandling = +- ! isChild() && +- ( ! (nStyle & SAL_FRAME_STYLE_FLOAT) || +- (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ); +- +- if( bDecoHandling ) +- { +- GdkWindowTypeHint eType = GDK_WINDOW_TYPE_HINT_NORMAL; +- if( (nStyle & SAL_FRAME_STYLE_DIALOG) && m_pParent != 0 ) +- eType = GDK_WINDOW_TYPE_HINT_DIALOG; +- if( (nStyle & SAL_FRAME_STYLE_INTRO) ) +- { +- gtk_window_set_role( GTK_WINDOW(m_pWindow), "splashscreen" ); +- eType = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN; +- } +- else if( (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ) ) +- { +- eType = GDK_WINDOW_TYPE_HINT_UTILITY; +- gtk_window_set_skip_taskbar_hint( GTK_WINDOW(m_pWindow), true ); +- } +- else if( (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) +- { +- eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; +- lcl_set_accept_focus( GTK_WINDOW(m_pWindow), false, true ); +- } +- else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) +- { +- eType = GDK_WINDOW_TYPE_HINT_UTILITY; +- } +-#if !GTK_CHECK_VERSION(3,0,0) +- if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) +- && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) +- { +- eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; +- gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); +- } +-#endif +- gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); +- gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); +- } +- else if( (nStyle & SAL_FRAME_STYLE_FLOAT) ) +- { +- gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_POPUP_MENU ); +- } +- +-#if !GTK_CHECK_VERSION(3,0,0) +- if( eWinType == GTK_WINDOW_TOPLEVEL ) +- { +-#ifdef ENABLE_GMENU_INTEGRATION +- // Enable DBus native menu if available. +- ensure_dbus_setup( this ); +-#endif +- +- guint32 nUserTime = 0; +- if( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_TOOLWINDOW)) == 0 ) +- { +- nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); +- } +- lcl_set_user_time(GTK_WINDOW(m_pWindow), nUserTime); +- } +-#endif +- +- if( bDecoHandling ) +- { +- gtk_window_set_resizable( GTK_WINDOW(m_pWindow), (nStyle & SAL_FRAME_STYLE_SIZEABLE) != 0 ); +- if( ( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) ) ) +- lcl_set_accept_focus( GTK_WINDOW(m_pWindow), false, false ); +- } +-} +- +-GdkNativeWindow GtkSalFrame::findTopLevelSystemWindow( GdkNativeWindow aWindow ) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- ::Window aRoot, aParent; +- ::Window* pChildren; +- unsigned int nChildren; +- bool bBreak = false; +- do +- { +- pChildren = NULL; +- nChildren = 0; +- aParent = aRoot = None; +- XQueryTree( getDisplay()->GetDisplay(), aWindow, +- &aRoot, &aParent, &pChildren, &nChildren ); +- XFree( pChildren ); +- if( aParent != aRoot ) +- aWindow = aParent; +- int nCount = 0; +- Atom* pProps = XListProperties( getDisplay()->GetDisplay(), +- aWindow, +- &nCount ); +- for( int i = 0; i < nCount && ! bBreak; ++i ) +- bBreak = (pProps[i] == XA_WM_HINTS); +- if( pProps ) +- XFree( pProps ); +- } while( aParent != aRoot && ! bBreak ); +- +- return aWindow; +-#else +- (void)aWindow; +- //FIXME: no findToplevelSystemWindow +- return 0; +-#endif +-} +- +-void GtkSalFrame::Init( SystemParentData* pSysData ) +-{ +- m_pParent = NULL; +- m_aForeignParentWindow = (GdkNativeWindow)pSysData->aWindow; +- m_pForeignParent = NULL; +- m_aForeignTopLevelWindow = findTopLevelSystemWindow( (GdkNativeWindow)pSysData->aWindow ); +- m_pForeignTopLevel = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignTopLevelWindow ); +- gdk_window_set_events( m_pForeignTopLevel, GDK_STRUCTURE_MASK ); +- +- if( pSysData->nSize > sizeof(pSysData->nSize)+sizeof(pSysData->aWindow) && pSysData->bXEmbedSupport ) +- { +-#if GTK_CHECK_VERSION(3,0,0) +- m_pWindow = gtk_plug_new_for_display( getGdkDisplay(), pSysData->aWindow ); +-#else +- m_pWindow = gtk_plug_new( pSysData->aWindow ); +-#endif +- m_bWindowIsGtkPlug = true; +- widget_set_can_default( m_pWindow, true ); +- widget_set_can_focus( m_pWindow, true ); +- gtk_widget_set_sensitive( m_pWindow, true ); +- } +- else +- { +- m_pWindow = gtk_window_new( GTK_WINDOW_POPUP ); +- m_bWindowIsGtkPlug = false; +- } +- m_nStyle = SAL_FRAME_STYLE_PLUG; +- InitCommon(); +- +- m_pForeignParent = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignParentWindow ); +- gdk_window_set_events( m_pForeignParent, GDK_STRUCTURE_MASK ); +- +-#if !GTK_CHECK_VERSION(3,0,0) +- int x_ret, y_ret; +- unsigned int w, h, bw, d; +- ::Window aRoot; +- XGetGeometry( getDisplay()->GetDisplay(), pSysData->aWindow, +- &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d ); +- maGeometry.nWidth = w; +- maGeometry.nHeight = h; +- window_resize(w, h); +- gtk_window_move( GTK_WINDOW(m_pWindow), 0, 0 ); +- if( ! m_bWindowIsGtkPlug ) +- { +- XReparentWindow( getDisplay()->GetDisplay(), +- widget_get_xid(m_pWindow), +- (::Window)pSysData->aWindow, +- 0, 0 ); +- } +-#else +- //FIXME: Handling embedded windows, is going to be fun ... +-#endif +-} +- +-void GtkSalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode ) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- XEvent aEvent; +- +- memset( &aEvent, 0, sizeof(aEvent) ); +- aEvent.xclient.window = m_aForeignParentWindow; +- aEvent.xclient.type = ClientMessage; +- aEvent.xclient.message_type = getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ); +- aEvent.xclient.format = 32; +- aEvent.xclient.data.l[0] = i_nTimeCode ? i_nTimeCode : CurrentTime; +- aEvent.xclient.data.l[1] = 3; // XEMBED_REQUEST_FOCUS +- aEvent.xclient.data.l[2] = 0; +- aEvent.xclient.data.l[3] = 0; +- aEvent.xclient.data.l[4] = 0; +- +- GetGenericData()->ErrorTrapPush(); +- XSendEvent( getDisplay()->GetDisplay(), +- m_aForeignParentWindow, +- False, NoEventMask, &aEvent ); +- GetGenericData()->ErrorTrapPop(); +-#else +- (void) this; // loplugin:staticmethods +- (void)i_nTimeCode; +- //FIXME: no askForXEmbedFocus for gtk3 yet +-#endif +-} +- +-void GtkSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) +-{ +- if( nStyle != m_nExtStyle && ! isChild() ) +- { +- m_nExtStyle = nStyle; +- updateWMClass(); +- } +-} +- +-SalGraphics* GtkSalFrame::AcquireGraphics() +-{ +- if( m_pWindow ) +- { +- for( int i = 0; i < nMaxGraphics; i++ ) +- { +- if( ! m_aGraphics[i].bInUse ) +- { +- m_aGraphics[i].bInUse = true; +- if( ! m_aGraphics[i].pGraphics ) +- { +-#if GTK_CHECK_VERSION(3,0,0) +- m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow ); +- if( !m_aFrame.get() ) +- { +- AllocateFrame(); +- TriggerPaintEvent(); +- } +- m_aGraphics[i].pGraphics->setDevice( m_aFrame ); +-#else // common case: +- m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow, m_nXScreen ); +-#endif +- } +- return m_aGraphics[i].pGraphics; +- } +- } +- } +- +- return NULL; +-} +- +-void GtkSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) +-{ +- for( int i = 0; i < nMaxGraphics; i++ ) +- { +- if( m_aGraphics[i].pGraphics == pGraphics ) +- { +- m_aGraphics[i].bInUse = false; +- break; +- } +- } +-} +- +-bool GtkSalFrame::PostEvent( void* pData ) +-{ +- getDisplay()->SendInternalEvent( this, pData ); +- return true; +-} +- +-void GtkSalFrame::SetTitle( const OUString& rTitle ) +-{ +- m_aTitle = rTitle; +- if( m_pWindow && ! isChild() ) +- gtk_window_set_title( GTK_WINDOW(m_pWindow), OUStringToOString( rTitle, RTL_TEXTENCODING_UTF8 ).getStr() ); +-} +- +-static inline sal_uInt8 * +-getRow( BitmapBuffer *pBuffer, sal_uLong nRow ) +-{ +- if( BMP_SCANLINE_ADJUSTMENT( pBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) +- return pBuffer->mpBits + nRow * pBuffer->mnScanlineSize; +- else +- return pBuffer->mpBits + ( pBuffer->mnHeight - nRow - 1 ) * pBuffer->mnScanlineSize; +-} +- +-static GdkPixbuf * +-bitmapToPixbuf( SalBitmap *pSalBitmap, SalBitmap *pSalAlpha ) +-{ +- g_return_val_if_fail( pSalBitmap != NULL, NULL ); +- g_return_val_if_fail( pSalAlpha != NULL, NULL ); +- +- BitmapBuffer *pBitmap = pSalBitmap->AcquireBuffer( BITMAP_READ_ACCESS ); +- g_return_val_if_fail( pBitmap != NULL, NULL ); +- g_return_val_if_fail( pBitmap->mnBitCount == 24 || pBitmap->mnBitCount == 32, NULL ); +- +- BitmapBuffer *pAlpha = pSalAlpha->AcquireBuffer( BITMAP_READ_ACCESS ); +- g_return_val_if_fail( pAlpha != NULL, NULL ); +- g_return_val_if_fail( pAlpha->mnBitCount == 8, NULL ); +- +- Size aSize = pSalBitmap->GetSize(); +- g_return_val_if_fail( pSalAlpha->GetSize() == aSize, NULL ); +- +- int nX, nY; +- guchar *pPixbufData = static_cast(g_malloc (4 * aSize.Width() * aSize.Height() )); +- guchar *pDestData = pPixbufData; +- +- for( nY = 0; nY < pBitmap->mnHeight; nY++ ) +- { +- sal_uInt8 *pData = getRow( pBitmap, nY ); +- sal_uInt8 *pAlphaData = getRow( pAlpha, nY ); +- +- for( nX = 0; nX < pBitmap->mnWidth; nX++ ) +- { +- BitmapColor aColor; +- if (pBitmap->mnFormat == BMP_FORMAT_24BIT_TC_BGR) +- { +- aColor = BitmapColor(pData[2], pData[1], pData[0]); +- pData += 3; +- } +- else if (pBitmap->mnFormat == BMP_FORMAT_24BIT_TC_RGB) +- { +- aColor = BitmapColor(pData[0], pData[1], pData[2]); +- pData += 3; +- } +- else +- { +- pBitmap->maColorMask.GetColorFor32Bit(aColor, pData); +- pData += 4; +- } +- *pDestData++ = aColor.GetRed(); +- *pDestData++ = aColor.GetGreen(); +- *pDestData++ = aColor.GetBlue(); +- *pDestData++ = 255 - *pAlphaData++; +- } +- } +- +- pSalBitmap->ReleaseBuffer( pBitmap, BITMAP_READ_ACCESS ); +- pSalAlpha->ReleaseBuffer( pAlpha, BITMAP_READ_ACCESS ); +- +- return gdk_pixbuf_new_from_data( pPixbufData, +- GDK_COLORSPACE_RGB, true, 8, +- aSize.Width(), aSize.Height(), +- aSize.Width() * 4, +- reinterpret_cast(g_free), +- NULL ); +-} +- +-void GtkSalFrame::SetIcon( sal_uInt16 nIcon ) +-{ +- if( (m_nStyle & (SAL_FRAME_STYLE_PLUG|SAL_FRAME_STYLE_SYSTEMCHILD|SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_INTRO|SAL_FRAME_STYLE_OWNERDRAWDECORATION)) +- || ! m_pWindow ) +- return; +- +- if( !ImplGetResMgr() ) +- return; +- +- GdkPixbuf *pBuf; +- GList *pIcons = NULL; +- +- sal_uInt16 nOffsets[2] = { SV_ICON_SMALL_START, SV_ICON_LARGE_START }; +- sal_uInt16 nIndex; +- +- for( nIndex = 0; nIndex < sizeof(nOffsets)/ sizeof(sal_uInt16); nIndex++ ) +- { +- // #i44723# workaround gcc temporary problem +- ResId aResId( nOffsets[nIndex] + nIcon, *ImplGetResMgr() ); +- BitmapEx aIcon( aResId ); +- +- // #i81083# convert to 24bit/8bit alpha bitmap +- Bitmap aBmp = aIcon.GetBitmap(); +- if( aBmp.GetBitCount() != 24 || ! aIcon.IsAlpha() ) +- { +- if( aBmp.GetBitCount() != 24 ) +- aBmp.Convert( BMP_CONVERSION_24BIT ); +- AlphaMask aMask; +- if( ! aIcon.IsAlpha() ) +- { +- switch( aIcon.GetTransparentType() ) +- { +- case TRANSPARENT_NONE: +- { +- sal_uInt8 nTrans = 0; +- aMask = AlphaMask( aBmp.GetSizePixel(), &nTrans ); +- } +- break; +- case TRANSPARENT_COLOR: +- aMask = AlphaMask( aBmp.CreateMask( aIcon.GetTransparentColor() ) ); +- break; +- case TRANSPARENT_BITMAP: +- aMask = AlphaMask( aIcon.GetMask() ); +- break; +- default: +- OSL_FAIL( "unhandled transparent type" ); +- break; +- } +- } +- else +- aMask = aIcon.GetAlpha(); +- aIcon = BitmapEx( aBmp, aMask ); +- } +- +- ImpBitmap *pIconImpBitmap = aIcon.ImplGetBitmapImpBitmap(); +- ImpBitmap *pIconImpMask = aIcon.ImplGetMaskImpBitmap(); +- +- if( pIconImpBitmap && pIconImpMask ) +- { +- SalBitmap *pIconBitmap = +- pIconImpBitmap->ImplGetSalBitmap(); +- SalBitmap *pIconMask = +- pIconImpMask->ImplGetSalBitmap(); +- +- if( ( pBuf = bitmapToPixbuf( pIconBitmap, pIconMask ) ) ) +- pIcons = g_list_prepend( pIcons, pBuf ); +- } +- } +- +- gtk_window_set_icon_list( GTK_WINDOW(m_pWindow), pIcons ); +- +- g_list_foreach( pIcons, reinterpret_cast(g_object_unref), NULL ); +- g_list_free( pIcons ); +-} +- +-void GtkSalFrame::SetMenu( SalMenu* pSalMenu ) +-{ +-// if(m_pSalMenu) +-// { +-// static_cast(m_pSalMenu)->DisconnectFrame(); +-// } +- m_pSalMenu = pSalMenu; +-} +- +-SalMenu* GtkSalFrame::GetMenu() +-{ +- return m_pSalMenu; +-} +- +-void GtkSalFrame::DrawMenuBar() +-{ +-} +- +-void GtkSalFrame::Center() +-{ +- long nX, nY; +- +- if( m_pParent ) +- { +- nX = ((long)m_pParent->maGeometry.nWidth - (long)maGeometry.nWidth)/2; +- nY = ((long)m_pParent->maGeometry.nHeight - (long)maGeometry.nHeight)/2; +- } +- else +- { +- GdkScreen *pScreen = NULL; +- gint px, py; +- GdkModifierType nMask; +- gdk_display_get_pointer( getGdkDisplay(), &pScreen, &px, &py, &nMask ); +- if( !pScreen ) +- pScreen = gtk_widget_get_screen( m_pWindow ); +- +- gint nMonitor; +- nMonitor = gdk_screen_get_monitor_at_point( pScreen, px, py ); +- +- GdkRectangle aMonitor; +- gdk_screen_get_monitor_geometry( pScreen, nMonitor, &aMonitor ); +- +- nX = aMonitor.x + (aMonitor.width - (long)maGeometry.nWidth)/2; +- nY = aMonitor.y + (aMonitor.height - (long)maGeometry.nHeight)/2; +- } +- SetPosSize( nX, nY, 0, 0, SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ); +-} +- +-Size GtkSalFrame::calcDefaultSize() +-{ +- return bestmaxFrameSizeForScreenSize(getDisplay()->GetScreenSize(GetDisplayScreen())); +-} +- +-void GtkSalFrame::SetDefaultSize() +-{ +- Size aDefSize = calcDefaultSize(); +- +- SetPosSize( 0, 0, aDefSize.Width(), aDefSize.Height(), +- SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); +- +- if( (m_nStyle & SAL_FRAME_STYLE_DEFAULT) && m_pWindow ) +- gtk_window_maximize( GTK_WINDOW(m_pWindow) ); +-} +- +-static void initClientId() +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- static bool bOnce = false; +- if (!bOnce) +- { +- bOnce = true; +- const OString& rID = SessionManagerClient::getSessionID(); +- if (!rID.isEmpty()) +- gdk_set_sm_client_id(rID.getStr()); +- } +-#else +- // No session management support for gtk3+ - this is now legacy. +-#endif +-} +- +-void GtkSalFrame::Show( bool bVisible, bool bNoActivate ) +-{ +- if( m_pWindow ) +- { +-#if !GTK_CHECK_VERSION(3,0,0) +- if( m_pParent && (m_pParent->m_nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) +- && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) +- gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), bVisible ); +-#endif +- if( bVisible ) +- { +- initClientId(); +- getDisplay()->startupNotificationCompleted(); +- +- if( m_bDefaultPos ) +- Center(); +- if( m_bDefaultSize ) +- SetDefaultSize(); +- setMinMaxSize(); +- +-#if !GTK_CHECK_VERSION(3,0,0) +- // #i45160# switch to desktop where a dialog with parent will appear +- if( m_pParent && m_pParent->m_nWorkArea != m_nWorkArea && IS_WIDGET_MAPPED(m_pParent->m_pWindow) ) +- getDisplay()->getWMAdaptor()->switchToWorkArea( m_pParent->m_nWorkArea ); +-#endif +- +- if( isFloatGrabWindow() && +- m_pParent && +- m_nFloats == 0 && +- ! getDisplay()->GetCaptureFrame() ) +- { +- /* #i63086# +- * outsmart Metacity's "focus:mouse" mode +- * which insists on taking the focus from the document +- * to the new float. Grab focus to parent frame BEFORE +- * showing the float (cannot grab it to the float +- * before show). +- */ +- m_pParent->grabPointer( true, true ); +- } +- +-#if !GTK_CHECK_VERSION(3,0,0) +- guint32 nUserTime = 0; +- if( ! bNoActivate && (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_TOOLWINDOW)) == 0 ) +- nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); +- +- //For these floating windows we don't want the main window to lose focus, and metacity has... +- // metacity-2.24.0/src/core/window.c +- +- // if ((focus_window != NULL) && XSERVER_TIME_IS_BEFORE (compare, focus_window->net_wm_user_time)) +- // "compare" window focus prevented by other activity +- +- // where "compare" is this window +- +- // which leads to... +- +- // /* This happens for error dialogs or alerts; these need to remain on +- // * top, but it would be confusing to have its ancestor remain +- // * focused. +- // */ +- // if (meta_window_is_ancestor_of_transient (focus_window, window)) +- // "The focus window %s is an ancestor of the newly mapped " +- // "window %s which isn't being focused. Unfocusing the " +- // "ancestor.\n", +- +- // i.e. having a time < that of the toplevel frame means that the toplevel frame gets unfocused. +- // awesome. +- if( nUserTime == 0 ) +- { +- nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); +- } +- lcl_set_user_time(GTK_WINDOW(m_pWindow), nUserTime ); +-#endif +- +- if( ! bNoActivate && (m_nStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) +- m_bSetFocusOnMap = true; +- +- gtk_widget_show( m_pWindow ); +- +- if( isFloatGrabWindow() ) +- { +- m_nFloats++; +- if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 ) +- { +- grabPointer(true, true); +- GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; +- pKeyboardFrame->grabKeyboard(true); +- } +- // #i44068# reset parent's IM context +- if( m_pParent ) +- m_pParent->EndExtTextInput(0); +- } +- if( m_bWindowIsGtkPlug ) +- askForXEmbedFocus( 0 ); +- } +- else +- { +- if( isFloatGrabWindow() ) +- { +- m_nFloats--; +- if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 0) +- { +- GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; +- pKeyboardFrame->grabKeyboard(false); +- grabPointer(false); +- } +- } +- gtk_widget_hide( m_pWindow ); +- if( m_pIMHandler ) +- m_pIMHandler->focusChanged( false ); +- // flush here; there may be a very seldom race between +- // the display connection used for clipboard and our connection +- Flush(); +- } +- CallCallback( SALEVENT_RESIZE, NULL ); +- TriggerPaintEvent(); +- } +-} +- +-void GtkSalFrame::setMinMaxSize() +-{ +- /* #i34504# metacity (and possibly others) do not treat +- * _NET_WM_STATE_FULLSCREEN and max_width/height independently; +- * whether they should is undefined. So don't set the max size hint +- * for a full screen window. +- */ +- if( m_pWindow && ! isChild() ) +- { +- GdkGeometry aGeo; +- int aHints = 0; +- if( m_nStyle & SAL_FRAME_STYLE_SIZEABLE ) +- { +- if( m_aMinSize.Width() && m_aMinSize.Height() && ! m_bFullscreen ) +- { +- aGeo.min_width = m_aMinSize.Width(); +- aGeo.min_height = m_aMinSize.Height(); +- aHints |= GDK_HINT_MIN_SIZE; +- } +- if( m_aMaxSize.Width() && m_aMaxSize.Height() && ! m_bFullscreen ) +- { +- aGeo.max_width = m_aMaxSize.Width(); +- aGeo.max_height = m_aMaxSize.Height(); +- aHints |= GDK_HINT_MAX_SIZE; +- } +- } +- else +- { +- if( ! m_bFullscreen ) +- { +- aGeo.min_width = maGeometry.nWidth; +- aGeo.min_height = maGeometry.nHeight; +- aHints |= GDK_HINT_MIN_SIZE; +- +- aGeo.max_width = maGeometry.nWidth; +- aGeo.max_height = maGeometry.nHeight; +- aHints |= GDK_HINT_MAX_SIZE; +- } +- } +- if( m_bFullscreen && m_aMaxSize.Width() && m_aMaxSize.Height() ) +- { +- aGeo.max_width = m_aMaxSize.Width(); +- aGeo.max_height = m_aMaxSize.Height(); +- aHints |= GDK_HINT_MAX_SIZE; +- } +- if( aHints ) +- { +- gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), +- NULL, +- &aGeo, +- GdkWindowHints( aHints ) ); +- } +- } +-} +- +-void GtkSalFrame::SetMaxClientSize( long nWidth, long nHeight ) +-{ +- if( ! isChild() ) +- { +- m_aMaxSize = Size( nWidth, nHeight ); +- // Show does a setMinMaxSize +- if( IS_WIDGET_MAPPED( m_pWindow ) ) +- setMinMaxSize(); +- } +-} +-void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) +-{ +- if( ! isChild() ) +- { +- m_aMinSize = Size( nWidth, nHeight ); +- if( m_pWindow ) +- { +- widget_set_size_request(nWidth, nHeight ); +- // Show does a setMinMaxSize +- if( IS_WIDGET_MAPPED( m_pWindow ) ) +- setMinMaxSize(); +- } +- } +-} +- +-// FIXME: we should really be an SvpSalFrame sub-class, and +-// share their AllocateFrame ! +-void GtkSalFrame::AllocateFrame() +-{ +-#if GTK_CHECK_VERSION(3,0,0) +- basegfx::B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight ); +- if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize ) +- { +- if( aFrameSize.getX() == 0 ) +- aFrameSize.setX( 1 ); +- if( aFrameSize.getY() == 0 ) +- aFrameSize.setY( 1 ); +- m_aFrame = basebmp::createBitmapDevice(aFrameSize, true, +- basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX); +- m_aFrame->setDamageTracker( +- basebmp::IBitmapDeviceDamageTrackerSharedPtr(new DamageTracker(*this)) ); +- SAL_INFO("vcl.gtk3", "allocated m_aFrame size of " << maGeometry.nWidth << " x " << maGeometry.nHeight); +- +-#if OSL_DEBUG_LEVEL > 0 // set background to orange +- m_aFrame->clear( basebmp::Color( 255, 127, 0 ) ); +-#endif +- +- // update device in existing graphics +- for( unsigned int i = 0; i < SAL_N_ELEMENTS( m_aGraphics ); ++i ) +- { +- if( !m_aGraphics[i].pGraphics ) +- continue; +- m_aGraphics[i].pGraphics->setDevice( m_aFrame ); +- } +- } +-#endif +-} +- +-void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) +-{ +- if( !m_pWindow || isChild( true, false ) ) +- return; +- +- bool bSized = false, bMoved = false; +- +- if( (nFlags & ( SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT )) && +- (nWidth > 0 && nHeight > 0 ) // sometimes stupid things happen +- ) +- { +- m_bDefaultSize = false; +- +- if( (unsigned long)nWidth != maGeometry.nWidth || (unsigned long)nHeight != maGeometry.nHeight ) +- bSized = true; +- maGeometry.nWidth = nWidth; +- maGeometry.nHeight = nHeight; +- +- if( isChild( false, true ) ) +- widget_set_size_request(nWidth, nHeight); +- else if( ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ) +- window_resize(nWidth, nHeight); +- setMinMaxSize(); +- } +- else if( m_bDefaultSize ) +- SetDefaultSize(); +- +- m_bDefaultSize = false; +- +- if( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) ) +- { +- if( m_pParent ) +- { +- if( AllSettings::GetLayoutRTL() ) +- nX = m_pParent->maGeometry.nWidth-maGeometry.nWidth-1-nX; +- nX += m_pParent->maGeometry.nX; +- nY += m_pParent->maGeometry.nY; +- } +- +- if( nX != maGeometry.nX || nY != maGeometry.nY ) +- bMoved = true; +- maGeometry.nX = nX; +- maGeometry.nY = nY; +- +- m_bDefaultPos = false; +- +- moveWindow( maGeometry.nX, maGeometry.nY ); +- +- updateScreenNumber(); +- } +- else if( m_bDefaultPos ) +- Center(); +- +- m_bDefaultPos = false; +- +- if( bSized ) +- AllocateFrame(); +- +- if( bSized && ! bMoved ) +- CallCallback( SALEVENT_RESIZE, NULL ); +- else if( bMoved && ! bSized ) +- CallCallback( SALEVENT_MOVE, NULL ); +- else if( bMoved && bSized ) +- CallCallback( SALEVENT_MOVERESIZE, NULL ); +- +- if (bSized) +- TriggerPaintEvent(); +-} +- +-void GtkSalFrame::GetClientSize( long& rWidth, long& rHeight ) +-{ +- if( m_pWindow && !(m_nState & GDK_WINDOW_STATE_ICONIFIED) ) +- { +- rWidth = maGeometry.nWidth; +- rHeight = maGeometry.nHeight; +- } +- else +- rWidth = rHeight = 0; +-} +- +-void GtkSalFrame::GetWorkArea( Rectangle& rRect ) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- rRect = GetGtkSalData()->GetGtkDisplay()->getWMAdaptor()->getWorkArea( 0 ); +-#else +- GdkScreen *pScreen = gtk_window_get_screen(GTK_WINDOW(m_pWindow)); +- Rectangle aRetRect; +- int max = gdk_screen_get_n_monitors (pScreen); +- for (int i = 0; i < max; ++i) +- { +- GdkRectangle aRect; +- gdk_screen_get_monitor_workarea(pScreen, i, &aRect); +- Rectangle aMonitorRect(aRect.x, aRect.y, aRect.x+aRect.width, aRect.y+aRect.height); +- aRetRect.Union(aMonitorRect); +- } +- rRect = aRetRect; +-#endif +-} +- +-SalFrame* GtkSalFrame::GetParent() const +-{ +- return m_pParent; +-} +- +-void GtkSalFrame::SetWindowState( const SalFrameState* pState ) +-{ +- if( ! m_pWindow || ! pState || isChild( true, false ) ) +- return; +- +- const sal_uLong nMaxGeometryMask = +- WINDOWSTATE_MASK_X | WINDOWSTATE_MASK_Y | +- WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT | +- WINDOWSTATE_MASK_MAXIMIZED_X | WINDOWSTATE_MASK_MAXIMIZED_Y | +- WINDOWSTATE_MASK_MAXIMIZED_WIDTH | WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; +- +- if( (pState->mnMask & WINDOWSTATE_MASK_STATE) && +- ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) && +- (pState->mnState & WINDOWSTATE_STATE_MAXIMIZED) && +- (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask ) +- { +- resizeWindow( pState->mnWidth, pState->mnHeight ); +- moveWindow( pState->mnX, pState->mnY ); +- m_bDefaultPos = m_bDefaultSize = false; +- +- maGeometry.nX = pState->mnMaximizedX; +- maGeometry.nY = pState->mnMaximizedY; +- maGeometry.nWidth = pState->mnMaximizedWidth; +- maGeometry.nHeight = pState->mnMaximizedHeight; +- updateScreenNumber(); +- +- m_nState = GdkWindowState( m_nState | GDK_WINDOW_STATE_MAXIMIZED ); +- m_aRestorePosSize = Rectangle( Point( pState->mnX, pState->mnY ), +- Size( pState->mnWidth, pState->mnHeight ) ); +- CallCallback( SALEVENT_RESIZE, NULL ); +- } +- else if( pState->mnMask & (WINDOWSTATE_MASK_X | WINDOWSTATE_MASK_Y | +- WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ) ) +- { +- sal_uInt16 nPosSizeFlags = 0; +- long nX = pState->mnX - (m_pParent ? m_pParent->maGeometry.nX : 0); +- long nY = pState->mnY - (m_pParent ? m_pParent->maGeometry.nY : 0); +- if( pState->mnMask & WINDOWSTATE_MASK_X ) +- nPosSizeFlags |= SAL_FRAME_POSSIZE_X; +- else +- nX = maGeometry.nX - (m_pParent ? m_pParent->maGeometry.nX : 0); +- if( pState->mnMask & WINDOWSTATE_MASK_Y ) +- nPosSizeFlags |= SAL_FRAME_POSSIZE_Y; +- else +- nY = maGeometry.nY - (m_pParent ? m_pParent->maGeometry.nY : 0); +- if( pState->mnMask & WINDOWSTATE_MASK_WIDTH ) +- nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH; +- if( pState->mnMask & WINDOWSTATE_MASK_HEIGHT ) +- nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT; +- SetPosSize( nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags ); +- } +- if( pState->mnMask & WINDOWSTATE_MASK_STATE && ! isChild() ) +- { +- if( pState->mnState & WINDOWSTATE_STATE_MAXIMIZED ) +- gtk_window_maximize( GTK_WINDOW(m_pWindow) ); +- else +- gtk_window_unmaximize( GTK_WINDOW(m_pWindow) ); +- /* #i42379# there is no rollup state in GDK; and rolled up windows are +- * (probably depending on the WM) reported as iconified. If we iconify a +- * window here that was e.g. a dialog, then it will be unmapped but still +- * not be displayed in the task list, so it's an iconified window that +- * the user cannot get out of this state. So do not set the iconified state +- * on windows with a parent (that is transient frames) since these tend +- * to not be represented in an icon task list. +- */ +- if( (pState->mnState & WINDOWSTATE_STATE_MINIMIZED) +- && ! m_pParent ) +- gtk_window_iconify( GTK_WINDOW(m_pWindow) ); +- else +- gtk_window_deiconify( GTK_WINDOW(m_pWindow) ); +- } +- TriggerPaintEvent(); +-} +- +-bool GtkSalFrame::GetWindowState( SalFrameState* pState ) +-{ +- pState->mnState = WINDOWSTATE_STATE_NORMAL; +- pState->mnMask = WINDOWSTATE_MASK_STATE; +- // rollup ? gtk 2.2 does not seem to support the shaded state +- if( (m_nState & GDK_WINDOW_STATE_ICONIFIED) ) +- pState->mnState |= WINDOWSTATE_STATE_MINIMIZED; +- if( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) +- { +- pState->mnState |= WINDOWSTATE_STATE_MAXIMIZED; +- pState->mnX = m_aRestorePosSize.Left(); +- pState->mnY = m_aRestorePosSize.Top(); +- pState->mnWidth = m_aRestorePosSize.GetWidth(); +- pState->mnHeight = m_aRestorePosSize.GetHeight(); +- pState->mnMaximizedX = maGeometry.nX; +- pState->mnMaximizedY = maGeometry.nY; +- pState->mnMaximizedWidth = maGeometry.nWidth; +- pState->mnMaximizedHeight = maGeometry.nHeight; +- pState->mnMask |= WINDOWSTATE_MASK_MAXIMIZED_X | +- WINDOWSTATE_MASK_MAXIMIZED_Y | +- WINDOWSTATE_MASK_MAXIMIZED_WIDTH | +- WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; +- } +- else +- { +- pState->mnX = maGeometry.nX; +- pState->mnY = maGeometry.nY; +- pState->mnWidth = maGeometry.nWidth; +- pState->mnHeight = maGeometry.nHeight; +- } +- pState->mnMask |= WINDOWSTATE_MASK_X | +- WINDOWSTATE_MASK_Y | +- WINDOWSTATE_MASK_WIDTH | +- WINDOWSTATE_MASK_HEIGHT; +- +- return true; +-} +- +-typedef enum { +- SET_RETAIN_SIZE, +- SET_FULLSCREEN, +- SET_UN_FULLSCREEN +-} SetType; +- +-void GtkSalFrame::SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSize ) +-{ +- if( !m_pWindow ) +- return; +- +- if (maGeometry.nDisplayScreenNumber == nNewScreen && eType == SET_RETAIN_SIZE) +- return; +- +- GdkScreen *pScreen = NULL; +- GdkRectangle aNewMonitor; +- +- bool bSpanAllScreens = nNewScreen == (unsigned int)-1; +- m_bSpanMonitorsWhenFullscreen = bSpanAllScreens && getDisplay()->getSystem()->GetDisplayScreenCount() > 1; +- +- if (m_bSpanMonitorsWhenFullscreen) //span all screens +- { +- pScreen = gtk_widget_get_screen( m_pWindow ); +- aNewMonitor.x = 0; +- aNewMonitor.y = 0; +- aNewMonitor.width = gdk_screen_get_width(pScreen); +- aNewMonitor.height = gdk_screen_get_height(pScreen); +- } +- else +- { +- gint nMonitor; +- bool bSameMonitor = false; +- +- if (!bSpanAllScreens) +- { +- pScreen = getDisplay()->getSystem()->getScreenMonitorFromIdx( nNewScreen, nMonitor ); +- if (!pScreen) +- { +- g_warning ("Attempt to move GtkSalFrame to invalid screen %d => " +- "fallback to current\n", nNewScreen); +- } +- } +- +- if (!pScreen) +- { +- pScreen = gtk_widget_get_screen( m_pWindow ); +- bSameMonitor = true; +- } +- +- // Heavy lifting, need to move screen ... +- if( pScreen != gtk_widget_get_screen( m_pWindow )) +- gtk_window_set_screen( GTK_WINDOW( m_pWindow ), pScreen ); +- +- gint nOldMonitor = gdk_screen_get_monitor_at_window( +- pScreen, widget_get_window( m_pWindow ) ); +- if (bSameMonitor) +- nMonitor = nOldMonitor; +- +- #if OSL_DEBUG_LEVEL > 1 +- if( nMonitor == nOldMonitor ) +- g_warning( "An apparently pointless SetScreen - should we elide it ?" ); +- #endif +- +- GdkRectangle aOldMonitor; +- gdk_screen_get_monitor_geometry( pScreen, nOldMonitor, &aOldMonitor ); +- gdk_screen_get_monitor_geometry( pScreen, nMonitor, &aNewMonitor ); +- +- maGeometry.nX = aNewMonitor.x + maGeometry.nX - aOldMonitor.x; +- maGeometry.nY = aNewMonitor.y + maGeometry.nY - aOldMonitor.y; +- } +- +- bool bResize = false; +- bool bVisible = IS_WIDGET_MAPPED( m_pWindow ); +- if( bVisible ) +- Show( false ); +- +- if( eType == SET_FULLSCREEN ) +- { +- maGeometry.nX = aNewMonitor.x; +- maGeometry.nY = aNewMonitor.y; +- maGeometry.nWidth = aNewMonitor.width; +- maGeometry.nHeight = aNewMonitor.height; +- m_nStyle |= SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; +- bResize = true; +- +- // #i110881# for the benefit of compiz set a max size here +- // else setting to fullscreen fails for unknown reasons +- m_aMaxSize.Width() = aNewMonitor.width; +- m_aMaxSize.Height() = aNewMonitor.height; +- } +- +- if( pSize && eType == SET_UN_FULLSCREEN ) +- { +- maGeometry.nX = pSize->Left(); +- maGeometry.nY = pSize->Top(); +- maGeometry.nWidth = pSize->GetWidth(); +- maGeometry.nHeight = pSize->GetHeight(); +- m_nStyle &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; +- bResize = true; +- } +- +- if (bResize) +- { +- // temporarily re-sizeable +- if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) +- gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); +- window_resize(maGeometry.nWidth, maGeometry.nHeight); +- //I wonder if we should instead leave maGeometry alone and rely on +- //configure-event to trigger signalConfigure and set it there +- AllocateFrame(); +- TriggerPaintEvent(); +- } +- +- gtk_window_move( GTK_WINDOW( m_pWindow ), maGeometry.nX, maGeometry.nY ); +- +-#if !GTK_CHECK_VERSION(3,0,0) +- // _NET_WM_STATE_FULLSCREEN (Metacity <-> KWin) +- if( ! getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) +-#endif +- { +-#if GTK_CHECK_VERSION(3,8,0) +- gdk_window_set_fullscreen_mode( widget_get_window(m_pWindow), m_bSpanMonitorsWhenFullscreen +- ? GDK_FULLSCREEN_ON_ALL_MONITORS : GDK_FULLSCREEN_ON_CURRENT_MONITOR ); +-#endif +- if( eType == SET_FULLSCREEN ) +- gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); +- else if( eType == SET_UN_FULLSCREEN ) +- gtk_window_unfullscreen( GTK_WINDOW( m_pWindow ) ); +- } +- +- if( eType == SET_UN_FULLSCREEN && +- !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) +- gtk_window_set_resizable( GTK_WINDOW( m_pWindow ), FALSE ); +- +- // FIXME: we should really let gtk+ handle our widget hierarchy ... +- if( m_pParent && gtk_widget_get_screen( m_pParent->m_pWindow ) != pScreen ) +- SetParent( NULL ); +- std::list< GtkSalFrame* > aChildren = m_aChildren; +- for( std::list< GtkSalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it ) +- (*it)->SetScreen( nNewScreen, SET_RETAIN_SIZE ); +- +- m_bDefaultPos = m_bDefaultSize = false; +- updateScreenNumber(); +- CallCallback( SALEVENT_MOVERESIZE, NULL ); +- +- if( bVisible ) +- Show( true ); +-} +- +-void GtkSalFrame::SetScreenNumber( unsigned int nNewScreen ) +-{ +- SetScreen( nNewScreen, SET_RETAIN_SIZE ); +-} +- +-void GtkSalFrame::updateWMClass() +-{ +- OString aResClass = OUStringToOString(m_sWMClass, RTL_TEXTENCODING_ASCII_US); +- const char *pResClass = !aResClass.isEmpty() ? aResClass.getStr() : +- SalGenericSystem::getFrameClassName(); +- Display *display; +- +- if (!getDisplay()->IsX11Display()) +- return; +- +-#if GTK_CHECK_VERSION(3,0,0) +- display = GDK_DISPLAY_XDISPLAY(getGdkDisplay()); +-#else +- display = getDisplay()->GetDisplay(); +-#endif +- +- if( IS_WIDGET_REALIZED( m_pWindow ) ) +- { +- XClassHint* pClass = XAllocClassHint(); +- OString aResName = SalGenericSystem::getFrameResName(); +- pClass->res_name = const_cast(aResName.getStr()); +- pClass->res_class = const_cast(pResClass); +- XSetClassHint( display, +- widget_get_xid(m_pWindow), +- pClass ); +- XFree( pClass ); +- } +-} +- +-void GtkSalFrame::SetApplicationID( const OUString &rWMClass ) +-{ +- if( rWMClass != m_sWMClass && ! isChild() ) +- { +- m_sWMClass = rWMClass; +- updateWMClass(); +- +- for( std::list< GtkSalFrame* >::iterator it = m_aChildren.begin(); it != m_aChildren.end(); ++it ) +- (*it)->SetApplicationID(rWMClass); +- } +-} +- +-void GtkSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen ) +-{ +- m_bFullscreen = bFullScreen; +- +- if( !m_pWindow || isChild() ) +- return; +- +- if( bFullScreen ) +- { +- m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), +- Size( maGeometry.nWidth, maGeometry.nHeight ) ); +- SetScreen( nScreen, SET_FULLSCREEN ); +- } +- else +- { +- SetScreen( nScreen, SET_UN_FULLSCREEN, +- !m_aRestorePosSize.IsEmpty() ? &m_aRestorePosSize : NULL ); +- m_aRestorePosSize = Rectangle(); +- } +-} +- +-/* definitions from xautolock.c (pl15) */ +-#define XAUTOLOCK_DISABLE 1 +-#define XAUTOLOCK_ENABLE 2 +- +-void GtkSalFrame::setAutoLock( bool bLock ) +-{ +- if( isChild() || !getDisplay()->IsX11Display() ) +- return; +- +- GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(m_pWindow) ); +- GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); +- GdkWindow *pRootWin = gdk_screen_get_root_window( pScreen ); +- +- Atom nAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( pDisplay ), +- "XAUTOLOCK_MESSAGE", False ); +- +- int nMessage = bLock ? XAUTOLOCK_ENABLE : XAUTOLOCK_DISABLE; +- +- XChangeProperty( GDK_DISPLAY_XDISPLAY( pDisplay ), +- GDK_WINDOW_XID( pRootWin ), +- nAtom, XA_INTEGER, +- 8, PropModeReplace, +- reinterpret_cast(&nMessage), +- sizeof( nMessage ) ); +-} +- +-#ifdef ENABLE_DBUS +-/** cookie is returned as an unsigned integer */ +-static guint +-dbus_inhibit_gsm (const gchar *appname, +- const gchar *reason, +- guint xid) +-{ +- gboolean res; +- guint cookie; +- GError *error = NULL; +- DBusGProxy *proxy = NULL; +- +- /* get the DBUS session connection */ +- DBusGConnection *session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); +- if (error != NULL) { +- g_debug ("DBUS cannot connect : %s", error->message); +- g_error_free (error); +- return -1; +- } +- +- /* get the proxy with gnome-session-manager */ +- proxy = dbus_g_proxy_new_for_name (session_connection, +- GSM_DBUS_SERVICE, +- GSM_DBUS_PATH, +- GSM_DBUS_INTERFACE); +- if (proxy == NULL) { +- g_debug ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); +- return -1; +- } +- +- res = dbus_g_proxy_call (proxy, +- "Inhibit", &error, +- G_TYPE_STRING, appname, +- G_TYPE_UINT, xid, +- G_TYPE_STRING, reason, +- G_TYPE_UINT, 8, //Inhibit the session being marked as idle +- G_TYPE_INVALID, +- G_TYPE_UINT, &cookie, +- G_TYPE_INVALID); +- +- /* check the return value */ +- if (! res) { +- cookie = -1; +- g_debug ("Inhibit method failed"); +- } +- +- /* check the error value */ +- if (error != NULL) { +- g_debug ("Inhibit problem : %s", error->message); +- g_error_free (error); +- cookie = -1; +- } +- +- g_object_unref (G_OBJECT (proxy)); +- return cookie; +-} +- +-static void +-dbus_uninhibit_gsm (guint cookie) +-{ +- gboolean res; +- GError *error = NULL; +- DBusGProxy *proxy = NULL; +- DBusGConnection *session_connection = NULL; +- +- if (cookie == guint(-1)) { +- g_debug ("Invalid cookie"); +- return; +- } +- +- /* get the DBUS session connection */ +- session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); +- if (error) { +- g_debug ("DBUS cannot connect : %s", error->message); +- g_error_free (error); +- return; +- } +- +- /* get the proxy with gnome-session-manager */ +- proxy = dbus_g_proxy_new_for_name (session_connection, +- GSM_DBUS_SERVICE, +- GSM_DBUS_PATH, +- GSM_DBUS_INTERFACE); +- if (proxy == NULL) { +- g_debug ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); +- return; +- } +- +- res = dbus_g_proxy_call (proxy, +- "Uninhibit", +- &error, +- G_TYPE_UINT, cookie, +- G_TYPE_INVALID, +- G_TYPE_INVALID); +- +- /* check the return value */ +- if (! res) { +- g_debug ("Uninhibit method failed"); +- } +- +- /* check the error value */ +- if (error != NULL) { +- g_debug ("Uninhibit problem : %s", error->message); +- g_error_free (error); +- cookie = -1; +- } +- g_object_unref (G_OBJECT (proxy)); +-} +-#endif +- +-void GtkSalFrame::StartPresentation( bool bStart ) +-{ +- setAutoLock( !bStart ); +- +- if( !getDisplay()->IsX11Display() ) +- return; +- +-#if !GTK_CHECK_VERSION(3,0,0) +- Display *pDisplay = GDK_DISPLAY_XDISPLAY( getGdkDisplay() ); +- +- int nTimeout, nInterval, bPreferBlanking, bAllowExposures; +- XGetScreenSaver( pDisplay, &nTimeout, &nInterval, +- &bPreferBlanking, &bAllowExposures ); +-#endif +- if( bStart ) +- { +-#if !GTK_CHECK_VERSION(3,0,0) +- if ( nTimeout ) +- { +- m_nSavedScreenSaverTimeout = nTimeout; +- XResetScreenSaver( pDisplay ); +- XSetScreenSaver( pDisplay, 0, nInterval, +- bPreferBlanking, bAllowExposures ); +- } +-#endif +-#ifdef ENABLE_DBUS +- m_nGSMCookie = dbus_inhibit_gsm(g_get_application_name(), "presentation", +- widget_get_xid(m_pWindow)); +-#endif +- } +- else +- { +-#if !GTK_CHECK_VERSION(3,0,0) +- if( m_nSavedScreenSaverTimeout ) +- XSetScreenSaver( pDisplay, m_nSavedScreenSaverTimeout, +- nInterval, bPreferBlanking, +- bAllowExposures ); +-#endif +- m_nSavedScreenSaverTimeout = 0; +-#ifdef ENABLE_DBUS +- dbus_uninhibit_gsm(m_nGSMCookie); +-#endif +- } +-} +- +-void GtkSalFrame::SetAlwaysOnTop( bool bOnTop ) +-{ +- if( m_pWindow ) +- gtk_window_set_keep_above( GTK_WINDOW( m_pWindow ), bOnTop ); +-} +- +-void GtkSalFrame::ToTop( sal_uInt16 nFlags ) +-{ +- if( m_pWindow ) +- { +- if( isChild( false, true ) ) +- gtk_widget_grab_focus( m_pWindow ); +- else if( IS_WIDGET_MAPPED( m_pWindow ) ) +- { +- if( ! (nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY) ) +- gtk_window_present( GTK_WINDOW(m_pWindow) ); +- else +- { +-#if !GTK_CHECK_VERSION(3,0,0) +- guint32 nUserTime = gdk_x11_get_server_time(GTK_WIDGET (m_pWindow)->window); +-#else +- guint32 nUserTime = GDK_CURRENT_TIME; +-#endif +- gdk_window_focus( widget_get_window(m_pWindow), nUserTime ); +- } +-#if !GTK_CHECK_VERSION(3,0,0) +- /* need to do an XSetInputFocus here because +- * gdk_window_focus will ask a EWMH compliant WM to put the focus +- * to our window - which it of course won't since our input hint +- * is set to false. +- */ +- if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ) +- { +- // sad but true: this can cause an XError, we need to catch that +- // to do this we need to synchronize with the XServer +- GetGenericData()->ErrorTrapPush(); +- XSetInputFocus( getDisplay()->GetDisplay(), widget_get_xid(m_pWindow), RevertToParent, CurrentTime ); +- // fdo#46687 - an XSync should not be necessary - but for some reason it is. +- XSync( getDisplay()->GetDisplay(), False ); +- GetGenericData()->ErrorTrapPop(); +- } +-#endif +- } +- else +- { +- if( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) +- gtk_window_present( GTK_WINDOW(m_pWindow) ); +- } +- } +-} +- +-void GtkSalFrame::SetPointer( PointerStyle ePointerStyle ) +-{ +- if( m_pWindow && ePointerStyle != m_ePointerStyle ) +- { +- m_ePointerStyle = ePointerStyle; +- GdkCursor *pCursor = getDisplay()->getCursor( ePointerStyle ); +- gdk_window_set_cursor( widget_get_window(m_pWindow), pCursor ); +- m_pCurrentCursor = pCursor; +- +- // #i80791# use grabPointer the same way as CaptureMouse, respective float grab +- if( getDisplay()->MouseCaptured( this ) ) +- grabPointer( true, false ); +- else if( m_nFloats > 0 ) +- grabPointer( true, true ); +- } +-} +- +-void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents ) +-{ +- static const char* pEnv = getenv( "SAL_NO_MOUSEGRABS" ); +- if (pEnv && *pEnv) +- return; +- +- if (!m_pWindow) +- return; +- +- const int nMask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); +- +-#if GTK_CHECK_VERSION(3,0,0) +- GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay()); +- GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager); +- if (bGrab) +- gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, GDK_CURRENT_TIME); +- else +- gdk_device_ungrab(pPointer, GDK_CURRENT_TIME); +-#else +- if( bGrab ) +- { +- bool bUseGdkGrab = true; +- const std::list< SalFrame* >& rFrames = getDisplay()->getFrames(); +- for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it ) +- { +- const GtkSalFrame* pFrame = static_cast< const GtkSalFrame* >(*it); +- if( pFrame->m_bWindowIsGtkPlug ) +- { +- bUseGdkGrab = false; +- break; +- } +- } +- if( bUseGdkGrab ) +- { +- gdk_pointer_grab( widget_get_window( m_pWindow ), bOwnerEvents, +- (GdkEventMask) nMask, NULL, m_pCurrentCursor, +- GDK_CURRENT_TIME ); +- } +- else +- { +- // FIXME: for some unknown reason gdk_pointer_grab does not +- // really produce owner events for GtkPlug windows +- // the cause is yet unknown +- +- // this is of course a bad hack, especially as we cannot +- // set the right cursor this way +- XGrabPointer( getDisplay()->GetDisplay(), +- widget_get_xid( m_pWindow ), +- bOwnerEvents, +- PointerMotionMask | ButtonPressMask | ButtonReleaseMask, +- GrabModeAsync, +- GrabModeAsync, +- None, +- None, +- CurrentTime +- ); +- } +- } +- else +- { +- // Two GdkDisplays may be open +- gdk_display_pointer_ungrab( getGdkDisplay(), GDK_CURRENT_TIME); +- } +-#endif +-} +- +-void GtkSalFrame::grabKeyboard( bool bGrab ) +-{ +- if (!m_pWindow) +- return; +- +-#if GTK_CHECK_VERSION(3,0,0) +- GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay()); +- GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager); +- GdkDevice* pKeyboard = gdk_device_get_associated_device(pPointer); +- if (bGrab) +- { +- gdk_device_grab(pKeyboard, widget_get_window(m_pWindow), GDK_OWNERSHIP_NONE, +- true, (GdkEventMask)(GDK_KEY_PRESS | GDK_KEY_RELEASE), NULL, GDK_CURRENT_TIME); +- } +- else +- { +- gdk_device_ungrab(pKeyboard, GDK_CURRENT_TIME); +- } +-#else +- if( bGrab ) +- { +- gdk_keyboard_grab(widget_get_window(m_pWindow), true, +- GDK_CURRENT_TIME); +- } +- else +- { +- gdk_keyboard_ungrab(GDK_CURRENT_TIME); +- } +-#endif +-} +- +-void GtkSalFrame::CaptureMouse( bool bCapture ) +-{ +- getDisplay()->CaptureMouse( bCapture ? this : NULL ); +-} +- +-void GtkSalFrame::SetPointerPos( long nX, long nY ) +-{ +- GtkSalFrame* pFrame = this; +- while( pFrame && pFrame->isChild( false, true ) ) +- pFrame = pFrame->m_pParent; +- if( ! pFrame ) +- return; +- +- GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(pFrame->m_pWindow) ); +- GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); +- +- /* when the application tries to center the mouse in the dialog the +- * window isn't mapped already. So use coordinates relative to the root window. +- */ +- unsigned int nWindowLeft = maGeometry.nX + nX; +- unsigned int nWindowTop = maGeometry.nY + nY; +- +- XWarpPointer( GDK_DISPLAY_XDISPLAY (pDisplay), None, +- GDK_WINDOW_XID (gdk_screen_get_root_window( pScreen ) ), +- 0, 0, 0, 0, nWindowLeft, nWindowTop); +- // #i38648# ask for the next motion hint +- gint x, y; +- GdkModifierType mask; +- gdk_window_get_pointer( widget_get_window(pFrame->m_pWindow) , &x, &y, &mask ); +-} +- +-void GtkSalFrame::Flush() +-{ +-#if GTK_CHECK_VERSION(3,0,0) +- gdk_display_flush( getGdkDisplay() ); +-#else +- XFlush (GDK_DISPLAY_XDISPLAY (getGdkDisplay())); +-#endif +-} +- +-void GtkSalFrame::Sync() +-{ +- gdk_display_sync( getGdkDisplay() ); +-} +- +-#ifndef GDK_Open +-#define GDK_Open 0x1008ff6b +-#endif +-#ifndef GDK_Paste +-#define GDK_Paste 0x1008ff6d +-#endif +-#ifndef GDK_Copy +-#define GDK_Copy 0x1008ff57 +-#endif +-#ifndef GDK_Cut +-#define GDK_Cut 0x1008ff58 +-#endif +- +-void GtkSalFrame::KeyCodeToGdkKey(const vcl::KeyCode& rKeyCode, +- guint* pGdkKeyCode, GdkModifierType *pGdkModifiers) +-{ +- if ( pGdkKeyCode == NULL || pGdkModifiers == NULL ) +- return; +- +- // Get GDK key modifiers +- GdkModifierType nModifiers = (GdkModifierType) 0; +- +- if ( rKeyCode.IsShift() ) +- nModifiers = (GdkModifierType) ( nModifiers | GDK_SHIFT_MASK ); +- +- if ( rKeyCode.IsMod1() ) +- nModifiers = (GdkModifierType) ( nModifiers | GDK_CONTROL_MASK ); +- +- if ( rKeyCode.IsMod2() ) +- nModifiers = (GdkModifierType) ( nModifiers | GDK_MOD1_MASK ); +- +- *pGdkModifiers = nModifiers; +- +- // Get GDK keycode. +- guint nKeyCode = 0; +- +- guint nCode = rKeyCode.GetCode(); +- +- if ( nCode >= KEY_0 && nCode <= KEY_9 ) +- nKeyCode = ( nCode - KEY_0 ) + GDK_0; +- else if ( nCode >= KEY_A && nCode <= KEY_Z ) +- nKeyCode = ( nCode - KEY_A ) + GDK_A; +- else if ( nCode >= KEY_F1 && nCode <= KEY_F26 ) +- nKeyCode = ( nCode - KEY_F1 ) + GDK_F1; +- else +- { +- switch( nCode ) +- { +- case KEY_DOWN: nKeyCode = GDK_Down; break; +- case KEY_UP: nKeyCode = GDK_Up; break; +- case KEY_LEFT: nKeyCode = GDK_Left; break; +- case KEY_RIGHT: nKeyCode = GDK_Right; break; +- case KEY_HOME: nKeyCode = GDK_Home; break; +- case KEY_END: nKeyCode = GDK_End; break; +- case KEY_PAGEUP: nKeyCode = GDK_Page_Up; break; +- case KEY_PAGEDOWN: nKeyCode = GDK_Page_Down; break; +- case KEY_RETURN: nKeyCode = GDK_Return; break; +- case KEY_ESCAPE: nKeyCode = GDK_Escape; break; +- case KEY_TAB: nKeyCode = GDK_Tab; break; +- case KEY_BACKSPACE: nKeyCode = GDK_BackSpace; break; +- case KEY_SPACE: nKeyCode = GDK_space; break; +- case KEY_INSERT: nKeyCode = GDK_Insert; break; +- case KEY_DELETE: nKeyCode = GDK_Delete; break; +- case KEY_ADD: nKeyCode = GDK_plus; break; +- case KEY_SUBTRACT: nKeyCode = GDK_minus; break; +- case KEY_MULTIPLY: nKeyCode = GDK_asterisk; break; +- case KEY_DIVIDE: nKeyCode = GDK_slash; break; +- case KEY_POINT: nKeyCode = GDK_period; break; +- case KEY_COMMA: nKeyCode = GDK_comma; break; +- case KEY_LESS: nKeyCode = GDK_less; break; +- case KEY_GREATER: nKeyCode = GDK_greater; break; +- case KEY_EQUAL: nKeyCode = GDK_equal; break; +- case KEY_FIND: nKeyCode = GDK_Find; break; +- case KEY_CONTEXTMENU: nKeyCode = GDK_Menu; break; +- case KEY_HELP: nKeyCode = GDK_Help; break; +- case KEY_UNDO: nKeyCode = GDK_Undo; break; +- case KEY_REPEAT: nKeyCode = GDK_Redo; break; +- case KEY_DECIMAL: nKeyCode = GDK_KP_Decimal; break; +- case KEY_TILDE: nKeyCode = GDK_asciitilde; break; +- case KEY_QUOTELEFT: nKeyCode = GDK_quoteleft; break; +- case KEY_BRACKETLEFT: nKeyCode = GDK_bracketleft; break; +- case KEY_BRACKETRIGHT: nKeyCode = GDK_bracketright; break; +- case KEY_SEMICOLON: nKeyCode = GDK_semicolon; break; +- case KEY_QUOTERIGHT: nKeyCode = GDK_quoteright; break; +- +- // Special cases +- case KEY_COPY: nKeyCode = GDK_Copy; break; +- case KEY_CUT: nKeyCode = GDK_Cut; break; +- case KEY_PASTE: nKeyCode = GDK_Paste; break; +- case KEY_OPEN: nKeyCode = GDK_Open; break; +- } +- } +- +- *pGdkKeyCode = nKeyCode; +-} +- +-OUString GtkSalFrame::GetKeyName( sal_uInt16 nKeyCode ) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- return getDisplay()->GetKeyName( nKeyCode ); +-#else +- guint nGtkKeyCode; +- GdkModifierType nGtkModifiers; +- KeyCodeToGdkKey(nKeyCode, &nGtkKeyCode, &nGtkModifiers ); +- +- gchar* pName = gtk_accelerator_get_label(nGtkKeyCode, nGtkModifiers); +- OUString aRet(pName, rtl_str_getLength(pName), RTL_TEXTENCODING_UTF8); +- g_free(pName); +- return aRet; +-#endif +-} +- +-GdkDisplay *GtkSalFrame::getGdkDisplay() +-{ +- return GetGtkSalData()->GetGdkDisplay(); +-} +- +-GtkSalDisplay *GtkSalFrame::getDisplay() +-{ +- return GetGtkSalData()->GetGtkDisplay(); +-} +- +-SalFrame::SalPointerState GtkSalFrame::GetPointerState() +-{ +- SalPointerState aState; +- GdkScreen* pScreen; +- gint x, y; +- GdkModifierType aMask; +- gdk_display_get_pointer( getGdkDisplay(), &pScreen, &x, &y, &aMask ); +- aState.maPos = Point( x - maGeometry.nX, y - maGeometry.nY ); +- aState.mnState = GetMouseModCode( aMask ); +- return aState; +-} +- +-KeyIndicatorState GtkSalFrame::GetIndicatorState() +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- return GetGtkSalData()->GetGtkDisplay()->GetIndicatorState(); +-#else +- KeyIndicatorState nState = KeyIndicatorState::NONE; +- +- GdkKeymap *pKeyMap = gdk_keymap_get_for_display(getGdkDisplay()); +- +- if (gdk_keymap_get_caps_lock_state(pKeyMap)) +- nState |= KeyIndicatorState::CAPSLOCK; +- if (gdk_keymap_get_num_lock_state(pKeyMap)) +- nState |= KeyIndicatorState::NUMLOCK; +-#if GTK_CHECK_VERSION(3,18,0) +- if (gdk_keymap_get_scroll_lock_state(pKeyMap)) +- nState |= KeyIndicatorState::SCROLLLOCK; +-#endif +- return nState; +-#endif +-} +- +-void GtkSalFrame::SimulateKeyPress( sal_uInt16 nKeyCode ) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- GetGtkSalData()->GetGtkDisplay()->SimulateKeyPress(nKeyCode); +-#else +- g_warning ("missing simulate keypress %d", nKeyCode); +-#endif +-} +- +-void GtkSalFrame::SetInputContext( SalInputContext* pContext ) +-{ +- if( ! pContext ) +- return; +- +- if( ! (pContext->mnOptions & InputContextFlags::Text) ) +- return; +- +- // create a new im context +- if( ! m_pIMHandler ) +- m_pIMHandler = new IMHandler( this ); +-} +- +-void GtkSalFrame::EndExtTextInput( sal_uInt16 nFlags ) +-{ +- if( m_pIMHandler ) +- m_pIMHandler->endExtTextInput( nFlags ); +-} +- +-bool GtkSalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , vcl::KeyCode& ) +-{ +- // not supported yet +- return false; +-} +- +-LanguageType GtkSalFrame::GetInputLanguage() +-{ +- return LANGUAGE_DONTKNOW; +-} +- +-void GtkSalFrame::UpdateSettings( AllSettings& rSettings ) +-{ +- if( ! m_pWindow ) +- return; +- +- GtkSalGraphics* pGraphics = static_cast(m_aGraphics[0].pGraphics); +- bool bFreeGraphics = false; +- if( ! pGraphics ) +- { +- pGraphics = static_cast(AcquireGraphics()); +- if ( !pGraphics ) +- { +- SAL_WARN("vcl", "Could not get graphics - unable to update settings"); +- return; +- } +- bFreeGraphics = true; +- } +- +- pGraphics->updateSettings( rSettings ); +- +- if( bFreeGraphics ) +- ReleaseGraphics( pGraphics ); +-} +- +-void GtkSalFrame::Beep() +-{ +- gdk_display_beep( getGdkDisplay() ); +-} +- +-const SystemEnvData* GtkSalFrame::GetSystemData() const +-{ +- return &m_aSystemData; +-} +- +-void GtkSalFrame::SetParent( SalFrame* pNewParent ) +-{ +- if( m_pParent ) +- m_pParent->m_aChildren.remove( this ); +- m_pParent = static_cast(pNewParent); +- if( m_pParent ) +- m_pParent->m_aChildren.push_back( this ); +- if( ! isChild() ) +- gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), +- (m_pParent && ! m_pParent->isChild(true,false)) ? GTK_WINDOW(m_pParent->m_pWindow) : NULL +- ); +-} +- +-#if !GTK_CHECK_VERSION(3,0,0) +- +-void GtkSalFrame::createNewWindow( ::Window aNewParent, bool bXEmbed, SalX11Screen nXScreen ) +-{ +- bool bWasVisible = m_pWindow && IS_WIDGET_MAPPED(m_pWindow); +- if( bWasVisible ) +- Show( false ); +- +- if( (int)nXScreen.getXScreen() >= getDisplay()->GetXScreenCount() ) +- nXScreen = m_nXScreen; +- +- SystemParentData aParentData; +- aParentData.aWindow = aNewParent; +- aParentData.bXEmbedSupport = bXEmbed; +- if( aNewParent == None ) +- { +- aNewParent = getDisplay()->GetRootWindow(nXScreen); +- aParentData.aWindow = None; +- aParentData.bXEmbedSupport = false; +- } +- else +- { +- // is new parent a root window ? +- Display* pDisp = getDisplay()->GetDisplay(); +- int nScreens = getDisplay()->GetXScreenCount(); +- for( int i = 0; i < nScreens; i++ ) +- { +- if( aNewParent == RootWindow( pDisp, i ) ) +- { +- nXScreen = SalX11Screen( i ); +- aParentData.aWindow = None; +- aParentData.bXEmbedSupport = false; +- break; +- } +- } +- } +- +- // free xrender resources +- for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ ) +- if( m_aGraphics[i].bInUse ) +- m_aGraphics[i].pGraphics->SetDrawable( None, m_nXScreen ); +- +- // first deinit frame +- if( m_pIMHandler ) +- { +- delete m_pIMHandler; +- m_pIMHandler = NULL; +- } +- if( m_pRegion ) +- { +- gdk_region_destroy( m_pRegion ); +- } +- +- GtkWidget *pEventWidget = getMouseEventWidget(); +- for (auto handler_id : m_aMouseSignalIds) +- g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); +- if( m_pFixedContainer ) +- gtk_widget_destroy( GTK_WIDGET(m_pFixedContainer) ); +- if( m_pEventBox ) +- gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); +- if( m_pWindow ) +- gtk_widget_destroy( m_pWindow ); +- if( m_pForeignParent ) +- g_object_unref( G_OBJECT( m_pForeignParent ) ); +- if( m_pForeignTopLevel ) +- g_object_unref( G_OBJECT( m_pForeignTopLevel ) ); +- +- // init new window +- m_bDefaultPos = m_bDefaultSize = false; +- if( aParentData.aWindow != None ) +- { +- m_nStyle |= SAL_FRAME_STYLE_PLUG; +- Init( &aParentData ); +- } +- else +- { +- m_nStyle &= ~SAL_FRAME_STYLE_PLUG; +- Init( (m_pParent && m_pParent->m_nXScreen == m_nXScreen) ? m_pParent : NULL, m_nStyle ); +- } +- +- // update graphics +- for( unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); i++ ) +- { +- if( m_aGraphics[i].bInUse ) +- { +- m_aGraphics[i].pGraphics->SetDrawable( widget_get_xid(m_pWindow), m_nXScreen ); +- m_aGraphics[i].pGraphics->SetWindow( m_pWindow ); +- } +- } +- +- if( ! m_aTitle.isEmpty() ) +- SetTitle( m_aTitle ); +- +- if( bWasVisible ) +- Show( true ); +- +- std::list< GtkSalFrame* > aChildren = m_aChildren; +- m_aChildren.clear(); +- for( std::list< GtkSalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it ) +- (*it)->createNewWindow( None, false, m_nXScreen ); +- +- // FIXME: SalObjects +-} +-#endif +- +-bool GtkSalFrame::SetPluginParent( SystemParentData* pSysParent ) +-{ +-#if !GTK_CHECK_VERSION(3,0,0) +- GetGenericData()->ErrorTrapPush(); // permanantly ignore unruly children's errors +- createNewWindow( pSysParent->aWindow, (pSysParent->nSize > sizeof(long)) && pSysParent->bXEmbedSupport, m_nXScreen ); +- return true; +-#else +- (void)pSysParent; +- //FIXME: no SetPluginParent impl. for gtk3 +- return false; +-#endif +-} +- +-void GtkSalFrame::ResetClipRegion() +-{ +- if( m_pWindow ) +- gdk_window_shape_combine_region( widget_get_window( m_pWindow ), NULL, 0, 0 ); +-} +- +-void GtkSalFrame::BeginSetClipRegion( sal_uLong ) +-{ +-#if GTK_CHECK_VERSION(3,0,0) +- if( m_pRegion ) +- cairo_region_destroy( m_pRegion ); +- m_pRegion = cairo_region_create(); +-#else +- if( m_pRegion ) +- gdk_region_destroy( m_pRegion ); +- m_pRegion = gdk_region_new(); +-#endif +-} +- +-void GtkSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) +-{ +- if( m_pRegion ) +- { +- GdkRectangle aRect; +- aRect.x = nX; +- aRect.y = nY; +- aRect.width = nWidth; +- aRect.height = nHeight; +-#if GTK_CHECK_VERSION(3,0,0) +- cairo_region_union_rectangle( m_pRegion, &aRect ); +-#else +- gdk_region_union_with_rect( m_pRegion, &aRect ); +-#endif +- } +-} +- +-void GtkSalFrame::EndSetClipRegion() +-{ +- if( m_pWindow && m_pRegion ) +- gdk_window_shape_combine_region( widget_get_window(m_pWindow), m_pRegion, 0, 0 ); +-} +- +-#if !GTK_CHECK_VERSION(3,0,0) +-bool GtkSalFrame::Dispatch( const XEvent* pEvent ) +-{ +- bool bContinueDispatch = true; +- +- if( pEvent->type == PropertyNotify ) +- { +- vcl_sal::WMAdaptor* pAdaptor = getDisplay()->getWMAdaptor(); +- Atom nDesktopAtom = pAdaptor->getAtom( vcl_sal::WMAdaptor::NET_WM_DESKTOP ); +- if( pEvent->xproperty.atom == nDesktopAtom && +- pEvent->xproperty.state == PropertyNewValue ) +- { +- m_nWorkArea = pAdaptor->getWindowWorkArea( widget_get_xid(m_pWindow) ); +- } +- } +- else if( pEvent->type == ConfigureNotify ) +- { +- if( m_pForeignParent && pEvent->xconfigure.window == m_aForeignParentWindow ) +- { +- bContinueDispatch = false; +- gtk_window_resize( GTK_WINDOW(m_pWindow), pEvent->xconfigure.width, pEvent->xconfigure.height ); +- if( ( sal::static_int_cast< int >(maGeometry.nWidth) != +- pEvent->xconfigure.width ) || +- ( sal::static_int_cast< int >(maGeometry.nHeight) != +- pEvent->xconfigure.height ) ) +- { +- maGeometry.nWidth = pEvent->xconfigure.width; +- maGeometry.nHeight = pEvent->xconfigure.height; +- setMinMaxSize(); +- getDisplay()->SendInternalEvent( this, NULL, SALEVENT_RESIZE ); +- } +- } +- else if( m_pForeignTopLevel && pEvent->xconfigure.window == m_aForeignTopLevelWindow ) +- { +- bContinueDispatch = false; +- // update position +- int x = 0, y = 0; +- ::Window aChild; +- XTranslateCoordinates( getDisplay()->GetDisplay(), +- widget_get_xid(m_pWindow), +- getDisplay()->GetRootWindow( getDisplay()->GetDefaultXScreen() ), +- 0, 0, +- &x, &y, +- &aChild ); +- if( x != maGeometry.nX || y != maGeometry.nY ) +- { +- maGeometry.nX = x; +- maGeometry.nY = y; +- getDisplay()->SendInternalEvent( this, NULL, SALEVENT_MOVE ); +- } +- } +- } +- else if( pEvent->type == ClientMessage && +- pEvent->xclient.message_type == getDisplay()->getWMAdaptor()->getAtom( vcl_sal::WMAdaptor::XEMBED ) && +- pEvent->xclient.window == widget_get_xid(m_pWindow) && +- m_bWindowIsGtkPlug +- ) +- { +- // FIXME: this should not be necessary, GtkPlug should do this +- // transparently for us +- if( pEvent->xclient.data.l[1] == 1 || // XEMBED_WINDOW_ACTIVATE +- pEvent->xclient.data.l[1] == 2 // XEMBED_WINDOW_DEACTIVATE +- ) +- { +- GdkEventFocus aEvent; +- aEvent.type = GDK_FOCUS_CHANGE; +- aEvent.window = widget_get_window( m_pWindow ); +- aEvent.send_event = gint8(TRUE); +- aEvent.in = gint16(pEvent->xclient.data.l[1] == 1); +- signalFocus( m_pWindow, &aEvent, this ); +- } +- } +- +- return bContinueDispatch; +-} +-#endif +- +-gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- SalMouseEvent aEvent; +- sal_uInt16 nEventType = 0; +- switch( pEvent->type ) +- { +- case GDK_BUTTON_PRESS: +- nEventType = SALEVENT_MOUSEBUTTONDOWN; +- break; +- case GDK_BUTTON_RELEASE: +- nEventType = SALEVENT_MOUSEBUTTONUP; +- break; +- default: +- return false; +- } +- switch( pEvent->button ) +- { +- case 1: aEvent.mnButton = MOUSE_LEFT; break; +- case 2: aEvent.mnButton = MOUSE_MIDDLE; break; +- case 3: aEvent.mnButton = MOUSE_RIGHT; break; +- default: return false; +- } +- aEvent.mnTime = pEvent->time; +- aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; +- aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; +- aEvent.mnCode = GetMouseModCode( pEvent->state ); +- +- bool bClosePopups = false; +- if( pEvent->type == GDK_BUTTON_PRESS && +- (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) == 0 +- ) +- { +- if( m_nFloats > 0 ) +- { +- // close popups if user clicks outside our application +- gint x, y; +- bClosePopups = (gdk_display_get_window_at_pointer( GtkSalFrame::getGdkDisplay(), &x, &y ) == NULL); +- } +- /* #i30306# release implicit pointer grab if no popups are open; else +- * Drag cannot grab the pointer and will fail. +- */ +- if( m_nFloats < 1 || bClosePopups ) +- gdk_display_pointer_ungrab( GtkSalFrame::getGdkDisplay(), GDK_CURRENT_TIME ); +- } +- +- if( pThis->m_bWindowIsGtkPlug && +- pEvent->type == GDK_BUTTON_PRESS && +- pEvent->button == 1 ) +- { +- pThis->askForXEmbedFocus( pEvent->time ); +- } +- +- // --- RTL --- (mirror mouse pos) +- if( AllSettings::GetLayoutRTL() ) +- aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; +- +- vcl::DeletionListener aDel( pThis ); +- +- pThis->CallCallback( nEventType, &aEvent ); +- +- if( ! aDel.isDeleted() ) +- { +- if( bClosePopups ) +- { +- ImplSVData* pSVData = ImplGetSVData(); +- if ( pSVData->maWinData.mpFirstFloat ) +- { +- static const char* pEnv = getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" ); +- if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose) && !(pEnv && *pEnv) ) +- pSVData->maWinData.mpFirstFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll ); +- } +- } +- +- if( ! aDel.isDeleted() ) +- { +- int frame_x = (int)(pEvent->x_root - pEvent->x); +- int frame_y = (int)(pEvent->y_root - pEvent->y); +- if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) +- { +- pThis->maGeometry.nX = frame_x; +- pThis->maGeometry.nY = frame_y; +- pThis->CallCallback( SALEVENT_MOVE, NULL ); +- } +- } +- } +- +- return true; +-} +- +-#if GTK_CHECK_VERSION(3,0,0) +-void GtkSalFrame::signalFlagsChanged( GtkWidget* , GtkStateFlags state, gpointer frame ) +-{ +- //TO-DO: This isn't as helpful as I'd like it to be. The color selector puts the main +- //windows into the backdrop, disabling everything, and the floating navigator window +- //is also problematic. +- GtkSalFrame* pThis = static_cast(frame); +- +- bool bOldBackDrop = state & GTK_STATE_FLAG_BACKDROP; +- bool bNewBackDrop = (gtk_widget_get_state_flags(GTK_WIDGET(pThis->m_pWindow)) & GTK_STATE_FLAG_BACKDROP); +- if (bNewBackDrop && !bOldBackDrop) +- { +- pThis->GetWindow()->Disable(); +- } +- else if (bOldBackDrop && !bNewBackDrop) +- { +- pThis->GetWindow()->Enable(); +- } +-} +-#endif +- +-gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- GdkEventScroll* pSEvent = reinterpret_cast(pEvent); +- +-#if GTK_CHECK_VERSION(3,0,0) +- // gnome#726878 check for duplicate legacy scroll event +- if (pSEvent->direction != GDK_SCROLL_SMOOTH && +- pThis->m_nLastScrollEventTime == pSEvent->time) +- { +- return true; +- } +-#endif +- +- SalWheelMouseEvent aEvent; +- +- aEvent.mnTime = pSEvent->time; +- aEvent.mnX = (sal_uLong)pSEvent->x; +- aEvent.mnY = (sal_uLong)pSEvent->y; +- aEvent.mnCode = GetMouseModCode( pSEvent->state ); +- aEvent.mnScrollLines = 3; +- +- switch (pSEvent->direction) +- { +-#if GTK_CHECK_VERSION(3,0,0) +- case GDK_SCROLL_SMOOTH: +- { +- double delta_x, delta_y; +- gdk_event_get_scroll_deltas(pEvent, &delta_x, &delta_y); +- //pick the bigger one I guess +- aEvent.mbHorz = fabs(delta_x) > fabs(delta_y); +- if (aEvent.mbHorz) +- aEvent.mnDelta = -delta_x; +- else +- aEvent.mnDelta = -delta_y; +- aEvent.mnScrollLines = 1; +- pThis->m_nLastScrollEventTime = pSEvent->time; +- break; +- } +-#endif +- case GDK_SCROLL_UP: +- aEvent.mnDelta = 120; +- aEvent.mbHorz = false; +- break; +- case GDK_SCROLL_DOWN: +- aEvent.mnDelta = -120; +- aEvent.mbHorz = false; +- break; +- case GDK_SCROLL_LEFT: +- aEvent.mbHorz = true; +- aEvent.mnDelta = 120; +- break; +- case GDK_SCROLL_RIGHT: +- aEvent.mnDelta = -120; +- aEvent.mbHorz = true; +- break; +- }; +- +- aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : 1; +- +- // --- RTL --- (mirror mouse pos) +- if( AllSettings::GetLayoutRTL() ) +- aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; +- +- pThis->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); +- +- return true; +-} +- +-#if GTK_CHECK_VERSION(3,14,0) +-void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame) +-{ +- gdouble x, y; +- GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); +- //I feel I want the first point of the sequence, not the last point which +- //the docs say this gives, but for the moment assume we start and end +- //within the same vcl window +- if (gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y)) +- { +- GtkSalFrame* pThis = static_cast(frame); +- +- SalSwipeEvent aEvent; +- aEvent.mnVelocityX = velocity_x; +- aEvent.mnVelocityY = velocity_y; +- aEvent.mnX = x; +- aEvent.mnY = y; +- +- pThis->CallCallback(SALEVENT_SWIPE, &aEvent); +- } +-} +- +-void GtkSalFrame::gestureLongPress(GtkGestureLongPress* gesture, gpointer frame) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- if(pThis) +- { +- SalLongPressEvent aEvent; +- +- gdouble x, y; +- GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); +- gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y); +- aEvent.mnX = x; +- aEvent.mnY = y; +- +- pThis->CallCallback(SALEVENT_LONGPRESS, &aEvent); +- } +-} +- +-#endif +- +-gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- SalMouseEvent aEvent; +- aEvent.mnTime = pEvent->time; +- aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; +- aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; +- aEvent.mnCode = GetMouseModCode( pEvent->state ); +- aEvent.mnButton = 0; +- +- // --- RTL --- (mirror mouse pos) +- if( AllSettings::GetLayoutRTL() ) +- aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; +- +- vcl::DeletionListener aDel( pThis ); +- +- pThis->CallCallback( SALEVENT_MOUSEMOVE, &aEvent ); +- +- if( ! aDel.isDeleted() ) +- { +- int frame_x = (int)(pEvent->x_root - pEvent->x); +- int frame_y = (int)(pEvent->y_root - pEvent->y); +- if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) +- { +- pThis->maGeometry.nX = frame_x; +- pThis->maGeometry.nY = frame_y; +- pThis->CallCallback( SALEVENT_MOVE, NULL ); +- } +- +- if( ! aDel.isDeleted() ) +- { +- // ask for the next hint +- gint x, y; +- GdkModifierType mask; +- gdk_window_get_pointer( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &x, &y, &mask ); +- } +- } +- +- return true; +-} +- +-gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- SalMouseEvent aEvent; +- aEvent.mnTime = pEvent->time; +- aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; +- aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; +- aEvent.mnCode = GetMouseModCode( pEvent->state ); +- aEvent.mnButton = 0; +- +- pThis->CallCallback( (pEvent->type == GDK_ENTER_NOTIFY) ? SALEVENT_MOUSEMOVE : SALEVENT_MOUSELEAVE, &aEvent ); +- +- return true; +-} +- +-#if GTK_CHECK_VERSION(3,0,0) +- +-cairo_t* GtkSalFrame::getCairoContext() const +-{ +- cairo_t* cr = SvpSalGraphics::createCairoContext(m_aFrame); +- assert(cr); +- return cr; +-} +- +-void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect) +-{ +-#if OSL_DEBUG_LEVEL > 1 +- long long area = rDamageRect.getWidth() * rDamageRect.getHeight(); +- if( area > 32 * 1024 ) +- { +- fprintf( stderr, "bitmap damaged %d %d (%dx%d) area %lld widget\n", +- (int) rDamageRect.getMinX(), +- (int) rDamageRect.getMinY(), +- (int) rDamageRect.getWidth(), +- (int) rDamageRect.getHeight(), +- area ); +- } +-#endif +- +- if (dumpframes) +- { +- static int frame; +- OString tmp("/tmp/frame" + OString::number(frame++) + ".png"); +- cairo_t* cr = getCairoContext(); +- cairo_surface_write_to_png(cairo_get_target(cr), tmp.getStr()); +- cairo_destroy(cr); +- } +- +- gtk_widget_queue_draw_area(GTK_WIDGET(m_pFixedContainer), +- rDamageRect.getMinX(), +- rDamageRect.getMinY(), +- rDamageRect.getWidth(), +- rDamageRect.getHeight()); +-} +- +-// blit our backing basebmp buffer to the target cairo context cr +-gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- cairo_save(cr); +- +- cairo_t* source = pThis->getCairoContext(); +- cairo_surface_t *pSurface = cairo_get_target(source); +- +- cairo_set_operator( cr, CAIRO_OPERATOR_OVER ); +- cairo_set_source_surface(cr, pSurface, 0, 0); +- cairo_paint(cr); +- +- cairo_destroy(source); +- +- cairo_restore(cr); +- +- cairo_surface_flush(cairo_get_target(cr)); +- +- return false; +-} +- +-void GtkSalFrame::sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer frame) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- bool bSized = false; +- +- if( pThis->m_bFullscreen || (pThis->m_nStyle & (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_PLUG)) == SAL_FRAME_STYLE_SIZEABLE ) +- { +- if( pAllocation->width != (int)pThis->maGeometry.nWidth || pAllocation->height != (int)pThis->maGeometry.nHeight ) +- { +- bSized = true; +- pThis->maGeometry.nWidth = pAllocation->width; +- pThis->maGeometry.nHeight = pAllocation->height; +- } +- } +- +- if( bSized ) +- { +- pThis->AllocateFrame(); +- pThis->CallCallback( SALEVENT_RESIZE, nullptr ); +- pThis->TriggerPaintEvent(); +- } +-} +- +-gboolean GtkSalFrame::signalConfigure(GtkWidget*, GdkEventConfigure* pEvent, gpointer frame) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- pThis->m_bPaintsBlocked = false; +- +- bool bMoved = false; +- int x = pEvent->x, y = pEvent->y; +- +- /* HACK: during sizing/moving a toolbar pThis->maGeometry is actually +- * already exact; even worse: due to the asynchronicity of configure +- * events the borderwindow which would evaluate this event +- * would size/move based on wrong data if we would actually evaluate +- * this event. So let's swallow it. +- */ +- if( (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && +- GtkSalFrame::getDisplay()->GetCaptureFrame() == pThis ) +- return false; +- +- /* #i31785# claims we cannot trust the x,y members of the event; +- * they are e.g. not set correctly on maximize/demaximize; +- * yet the gdkdisplay-x11.c code handling configure_events has +- * done this XTranslateCoordinates work since the day ~zero. +- */ +- if( x != pThis->maGeometry.nX || y != pThis->maGeometry.nY ) +- { +- bMoved = true; +- pThis->maGeometry.nX = x; +- pThis->maGeometry.nY = y; +- } +- +- // update decoration hints +- if( ! (pThis->m_nStyle & SAL_FRAME_STYLE_PLUG) ) +- { +- GdkRectangle aRect; +- gdk_window_get_frame_extents( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &aRect ); +- pThis->maGeometry.nTopDecoration = y - aRect.y; +- pThis->maGeometry.nBottomDecoration = aRect.y + aRect.height - y - pEvent->height; +- pThis->maGeometry.nLeftDecoration = x - aRect.x; +- pThis->maGeometry.nRightDecoration = aRect.x + aRect.width - x - pEvent->width; +- } +- else +- { +- pThis->maGeometry.nTopDecoration = +- pThis->maGeometry.nBottomDecoration = +- pThis->maGeometry.nLeftDecoration = +- pThis->maGeometry.nRightDecoration = 0; +- } +- +- pThis->updateScreenNumber(); +- +- if (bMoved) +- pThis->CallCallback(SALEVENT_MOVE, nullptr); +- +- return false; +-} +-#else +-gboolean GtkSalFrame::signalExpose( GtkWidget*, GdkEventExpose* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- pThis->m_bPaintsBlocked = false; +- +- struct SalPaintEvent aEvent( pEvent->area.x, pEvent->area.y, pEvent->area.width, pEvent->area.height ); +- +- pThis->CallCallback( SALEVENT_PAINT, &aEvent ); +- +- return false; +-} +- +-gboolean GtkSalFrame::signalConfigure( GtkWidget*, GdkEventConfigure* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- pThis->m_bPaintsBlocked = false; +- +- bool bMoved = false, bSized = false; +- int x = pEvent->x, y = pEvent->y; +- +- /* HACK: during sizing/moving a toolbar pThis->maGeometry is actually +- * already exact; even worse: due to the asynchronicity of configure +- * events the borderwindow which would evaluate this event +- * would size/move based on wrong data if we would actually evaluate +- * this event. So let's swallow it. +- */ +- if( (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && +- GtkSalFrame::getDisplay()->GetCaptureFrame() == pThis ) +- return false; +- +- /* #i31785# claims we cannot trust the x,y members of the event; +- * they are e.g. not set correctly on maximize/demaximize; +- * yet the gdkdisplay-x11.c code handling configure_events has +- * done this XTranslateCoordinates work since the day ~zero. +- */ +- if( x != pThis->maGeometry.nX || y != pThis->maGeometry.nY ) +- { +- bMoved = true; +- pThis->maGeometry.nX = x; +- pThis->maGeometry.nY = y; +- } +- /* #i86302# +- * for non sizeable windows we set the min and max hint for the window manager to +- * achieve correct sizing. However this is asynchronous and e.g. on Compiz +- * it sometimes happens that the window gets resized to another size (some default) +- * if we update the size here, subsequent setMinMaxSize will use this wrong size +- * - which is not good since the window manager will now size the window back to this +- * wrong size at some point. +- */ +- if( pThis->m_bFullscreen || (pThis->m_nStyle & (SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_PLUG)) == SAL_FRAME_STYLE_SIZEABLE ) +- { +- if( pEvent->width != (int)pThis->maGeometry.nWidth || pEvent->height != (int)pThis->maGeometry.nHeight ) +- { +- bSized = true; +- pThis->maGeometry.nWidth = pEvent->width; +- pThis->maGeometry.nHeight = pEvent->height; +- } +- } +- +- // update decoration hints +- if( ! (pThis->m_nStyle & SAL_FRAME_STYLE_PLUG) ) +- { +- GdkRectangle aRect; +- gdk_window_get_frame_extents( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &aRect ); +- pThis->maGeometry.nTopDecoration = y - aRect.y; +- pThis->maGeometry.nBottomDecoration = aRect.y + aRect.height - y - pEvent->height; +- pThis->maGeometry.nLeftDecoration = x - aRect.x; +- pThis->maGeometry.nRightDecoration = aRect.x + aRect.width - x - pEvent->width; +- } +- else +- { +- pThis->maGeometry.nTopDecoration = +- pThis->maGeometry.nBottomDecoration = +- pThis->maGeometry.nLeftDecoration = +- pThis->maGeometry.nRightDecoration = 0; +- } +- +- pThis->updateScreenNumber(); +- if( bSized ) +- pThis->AllocateFrame(); +- +- if( bMoved && bSized ) +- pThis->CallCallback( SALEVENT_MOVERESIZE, nullptr ); +- else if( bMoved ) +- pThis->CallCallback( SALEVENT_MOVE, nullptr ); +- else if( bSized ) +- pThis->CallCallback( SALEVENT_RESIZE, nullptr ); +- +- if (bSized) +- pThis->TriggerPaintEvent(); +- return false; +-} +- +-#endif // GTK_CHECK_VERSION(3,0,0) +- +-void GtkSalFrame::TriggerPaintEvent() +-{ +- //Under gtk2 we can basically paint directly into the XWindow and on +- //additional "expose-event" events we can re-render the missing pieces +- // +- //Under gtk3 we have to keep our own buffer up to date and flush it into +- //the given cairo context on "draw". So we emit a paint event on +- //opportune resize trigger events to initially fill our backbuffer and then +- //keep it up to date with our direct paints and tell gtk those regions +- //have changed and then blit them into the provided cairo context when +- //we get the "draw" +- // +- //The other alternative was to always paint everything on "draw", but +- //that duplicates the amount of drawing and is hideously slow +-#if GTK_CHECK_VERSION(3,0,0) +- SAL_INFO("vcl.gtk3", "force painting" << 0 << "," << 0 << " " << maGeometry.nWidth << "x" << maGeometry.nHeight); +- SalPaintEvent aPaintEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight, true); +- CallCallback(SALEVENT_PAINT, &aPaintEvt); +- gtk_widget_queue_draw(GTK_WIDGET(m_pFixedContainer)); +-#endif +-} +- +-gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- SalGenericInstance *pSalInstance = +- static_cast< SalGenericInstance* >(GetSalData()->m_pInstance); +- +- // check if printers have changed (analogous to salframe focus handler) +- pSalInstance->updatePrinterUpdate(); +- +- if( !pEvent->in ) +- { +- pThis->m_nKeyModifiers = 0; +- pThis->m_bSendModChangeOnRelease = false; +- } +- +- if( pThis->m_pIMHandler ) +- pThis->m_pIMHandler->focusChanged( pEvent->in ); +- +- // ask for changed printers like generic implementation +- if( pEvent->in && pSalInstance->isPrinterInit() ) +- pSalInstance->updatePrinterUpdate(); +- +- // FIXME: find out who the hell steals the focus from our frame +- // while we have the pointer grabbed, this should not come from +- // the window manager. Is this an event that was still queued ? +- // The focus does not seem to get set inside our process +- +- // in the meantime do not propagate focus get/lose if floats are open +- if( m_nFloats == 0 ) +- pThis->CallCallback( pEvent->in ? SALEVENT_GETFOCUS : SALEVENT_LOSEFOCUS, NULL ); +- +- return false; +-} +- +-#if !GTK_CHECK_VERSION(3,8,0) +-static OString getDisplayString() +-{ +- int nParams = rtl_getAppCommandArgCount(); +- OUString aParam; +- for( int i = 0; i < nParams; i++ ) +- { +- rtl_getAppCommandArg( i, &aParam.pData ); +- if( i < nParams-1 && (aParam == "-display" || aParam == "--display" ) ) +- { +- rtl_getAppCommandArg( i+1, &aParam.pData ); +- return OUStringToOString( aParam, osl_getThreadTextEncoding() ); +- } +- } +- return OString(); +-} +-#endif +- +-gboolean GtkSalFrame::signalMap( GtkWidget *pWidget, GdkEvent*, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +-#if !GTK_CHECK_VERSION(3,8,0) +- //Spawn off a helper program that will attempt to set this fullscreen +- //window to span all displays. +- if (pThis->m_bFullscreen && pThis->m_bSpanMonitorsWhenFullscreen) +- { +- GdkWindow* gdkwin = widget_get_window(pThis->m_pWindow); +- if (gdkwin) +- { +- OUString sProgramURL( "$BRAND_BASE_DIR/" LIBO_LIBEXEC_FOLDER "/xid-fullscreen-on-all-monitors"); +- rtl::Bootstrap::expandMacros(sProgramURL); +- OUString sProgram; +- if (osl::FileBase::getSystemPathFromFileURL(sProgramURL, sProgram) == osl::File::E_None) +- { +- OString sFinalProgram(OUStringToOString(sProgram, osl_getThreadTextEncoding()) +- + " " + OString::number((int)GDK_WINDOW_XID(gdkwin))); +- OString sDisplay(getDisplayString()); +- if (!sDisplay.isEmpty()) +- { +- sFinalProgram += "--display " + sDisplay; +- } +- int returnValue = system(sFinalProgram.getStr()); +- (void)returnValue; +- } +- } +- } +-#endif +- +- bool bSetFocus = pThis->m_bSetFocusOnMap; +- pThis->m_bSetFocusOnMap = false; +- +-#if !GTK_CHECK_VERSION(3,0,0) +- if( bSetFocus ) +- { +- GetGenericData()->ErrorTrapPush(); +- XSetInputFocus( GtkSalFrame::getDisplay()->GetDisplay(), +- widget_get_xid(pWidget), +- RevertToParent, CurrentTime ); +- XSync( GtkSalFrame::getDisplay()->GetDisplay(), False ); +- GetGenericData()->ErrorTrapPop(); +- } +-#else +- (void)pWidget; (void)bSetFocus; +- //FIXME: no set input focus ... +-#endif +- +- pThis->CallCallback( SALEVENT_RESIZE, NULL ); +- pThis->TriggerPaintEvent(); +- +- return false; +-} +- +-gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- pThis->CallCallback( SALEVENT_RESIZE, NULL ); +- +- return false; +-} +- +-gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- vcl::DeletionListener aDel( pThis ); +- +- if( pThis->m_pIMHandler ) +- { +- if( pThis->m_pIMHandler->handleKeyEvent( pEvent ) ) +- return true; +- } +- +- // handle modifiers +- if( pEvent->keyval == GDK_Shift_L || pEvent->keyval == GDK_Shift_R || +- pEvent->keyval == GDK_Control_L || pEvent->keyval == GDK_Control_R || +- pEvent->keyval == GDK_Alt_L || pEvent->keyval == GDK_Alt_R || +- pEvent->keyval == GDK_Meta_L || pEvent->keyval == GDK_Meta_R || +- pEvent->keyval == GDK_Super_L || pEvent->keyval == GDK_Super_R ) +- { +- SalKeyModEvent aModEvt; +- +- sal_uInt16 nModCode = GetKeyModCode( pEvent->state ); +- +- aModEvt.mnModKeyCode = 0; // emit no MODKEYCHANGE events +- if( pEvent->type == GDK_KEY_PRESS && !pThis->m_nKeyModifiers ) +- pThis->m_bSendModChangeOnRelease = true; +- +- else if( pEvent->type == GDK_KEY_RELEASE && +- pThis->m_bSendModChangeOnRelease ) +- { +- aModEvt.mnModKeyCode = pThis->m_nKeyModifiers; +- pThis->m_nKeyModifiers = 0; +- } +- +- sal_uInt16 nExtModMask = 0; +- sal_uInt16 nModMask = 0; +- // pressing just the ctrl key leads to a keysym of XK_Control but +- // the event state does not contain ControlMask. In the release +- // event its the other way round: it does contain the Control mask. +- // The modifier mode therefore has to be adapted manually. +- switch( pEvent->keyval ) +- { +- case GDK_Control_L: +- nExtModMask = MODKEY_LMOD1; +- nModMask = KEY_MOD1; +- break; +- case GDK_Control_R: +- nExtModMask = MODKEY_RMOD1; +- nModMask = KEY_MOD1; +- break; +- case GDK_Alt_L: +- nExtModMask = MODKEY_LMOD2; +- nModMask = KEY_MOD2; +- break; +- case GDK_Alt_R: +- nExtModMask = MODKEY_RMOD2; +- nModMask = KEY_MOD2; +- break; +- case GDK_Shift_L: +- nExtModMask = MODKEY_LSHIFT; +- nModMask = KEY_SHIFT; +- break; +- case GDK_Shift_R: +- nExtModMask = MODKEY_RSHIFT; +- nModMask = KEY_SHIFT; +- break; +- // Map Meta/Super to MOD3 modifier on all Unix systems +- // except Mac OS X +- case GDK_Meta_L: +- case GDK_Super_L: +- nExtModMask = MODKEY_LMOD3; +- nModMask = KEY_MOD3; +- break; +- case GDK_Meta_R: +- case GDK_Super_R: +- nExtModMask = MODKEY_RMOD3; +- nModMask = KEY_MOD3; +- break; +- } +- if( pEvent->type == GDK_KEY_RELEASE ) +- { +- nModCode &= ~nModMask; +- pThis->m_nKeyModifiers &= ~nExtModMask; +- } +- else +- { +- nModCode |= nModMask; +- pThis->m_nKeyModifiers |= nExtModMask; +- } +- +- aModEvt.mnCode = nModCode; +- aModEvt.mnTime = pEvent->time; +- +- pThis->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt ); +- +- } +- else +- { +- pThis->doKeyCallback( pEvent->state, +- pEvent->keyval, +- pEvent->hardware_keycode, +- pEvent->group, +- pEvent->time, +- sal_Unicode(gdk_keyval_to_unicode( pEvent->keyval )), +- (pEvent->type == GDK_KEY_PRESS), +- false ); +- if( ! aDel.isDeleted() ) +- pThis->m_bSendModChangeOnRelease = false; +- } +- +- if( !aDel.isDeleted() && pThis->m_pIMHandler ) +- pThis->m_pIMHandler->updateIMSpotLocation(); +- +- return true; +-} +- +-gboolean GtkSalFrame::signalDelete( GtkWidget*, GdkEvent*, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +-#if GTK_CHECK_VERSION(3,0,0) +- //If we went into the backdrop we disabled the toplevel window, if we +- //receive a delete here, re-enable so we can process it +- bool bBackDrop = (gtk_widget_get_state_flags(GTK_WIDGET(pThis->m_pWindow)) & GTK_STATE_FLAG_BACKDROP); +- if (bBackDrop) +- pThis->GetWindow()->Enable(); +-#endif +- +- pThis->CallCallback( SALEVENT_CLOSE, NULL ); +- +- return true; +-} +- +-void GtkSalFrame::signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- +- // every frame gets an initial style set on creation +- // do not post these as the whole application tends to +- // redraw itself to adjust to the new style +- // where there IS no new style resulting in tremendous unnecessary flickering +- if( pPrevious != NULL ) +- { +- // signalStyleSet does NOT usually have the gdk lock +- // so post user event to safely dispatch the SALEVENT_SETTINGSCHANGED +- // note: settings changed for multiple frames is avoided in winproc.cxx ImplHandleSettings +- GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_SETTINGSCHANGED ); +- GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_FONTCHANGED ); +- } +- +-#if !GTK_CHECK_VERSION(3,0,0) +- /* #i64117# gtk sets a nice background pixmap +- * but we actually don't really want that, so save +- * some time on the Xserver as well as prevent +- * some paint issues +- */ +- GdkWindow* pWin = widget_get_window(GTK_WIDGET(pThis->getWindow())); +- if( pWin ) +- { +- ::Window aWin = GDK_WINDOW_XWINDOW(pWin); +- if( aWin != None ) +- XSetWindowBackgroundPixmap( GtkSalFrame::getDisplay()->GetDisplay(), +- aWin, +- pThis->m_hBackgroundPixmap ); +- } +- if( ! pThis->m_pParent ) +- { +- // signalize theme changed for NWF caches +- // FIXME: should be called only once for a style change +- GtkSalGraphics::bThemeChanged = true; +- } +-#endif +-} +- +-gboolean GtkSalFrame::signalWindowState( GtkWidget*, GdkEvent* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- if( (pThis->m_nState & GDK_WINDOW_STATE_ICONIFIED) != (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED ) ) +- { +- GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_RESIZE ); +- pThis->TriggerPaintEvent(); +- } +- +- if( (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) && +- ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) ) +- { +- pThis->m_aRestorePosSize = +- Rectangle( Point( pThis->maGeometry.nX, pThis->maGeometry.nY ), +- Size( pThis->maGeometry.nWidth, pThis->maGeometry.nHeight ) ); +- } +- pThis->m_nState = pEvent->window_state.new_window_state; +- +- #if OSL_DEBUG_LEVEL > 1 +- if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) +- { +- fprintf( stderr, "window %p %s full screen state\n", +- pThis, +- (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); +- } +- #endif +- +- return false; +-} +- +-gboolean GtkSalFrame::signalVisibility( GtkWidget*, GdkEventVisibility* pEvent, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- pThis->m_nVisibility = pEvent->state; +- return true; +-} +- +-void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame ) +-{ +- GtkSalFrame* pThis = static_cast(frame); +- if( pObj == pThis->m_pWindow ) +- { +- pThis->m_pFixedContainer = NULL; +- pThis->m_pEventBox = NULL; +- pThis->m_pWindow = NULL; +- pThis->InvalidateGraphics(); +- } +-} +- +-// GtkSalFrame::IMHandler +- +-GtkSalFrame::IMHandler::IMHandler( GtkSalFrame* pFrame ) +-: m_pFrame(pFrame), +- m_nPrevKeyPresses( 0 ), +- m_pIMContext( NULL ), +- m_bFocused( true ), +- m_bPreeditJustChanged( false ) +-{ +- m_aInputEvent.mpTextAttr = NULL; +- createIMContext(); +-} +- +-GtkSalFrame::IMHandler::~IMHandler() +-{ +- // cancel an eventual event posted to begin preedit again +- GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); +- deleteIMContext(); +-} +- +-void GtkSalFrame::IMHandler::createIMContext() +-{ +- if( ! m_pIMContext ) +- { +- m_pIMContext = gtk_im_multicontext_new (); +- g_signal_connect( m_pIMContext, "commit", +- G_CALLBACK (signalIMCommit), this ); +- g_signal_connect( m_pIMContext, "preedit_changed", +- G_CALLBACK (signalIMPreeditChanged), this ); +- g_signal_connect( m_pIMContext, "retrieve_surrounding", +- G_CALLBACK (signalIMRetrieveSurrounding), this ); +- g_signal_connect( m_pIMContext, "delete_surrounding", +- G_CALLBACK (signalIMDeleteSurrounding), this ); +- g_signal_connect( m_pIMContext, "preedit_start", +- G_CALLBACK (signalIMPreeditStart), this ); +- g_signal_connect( m_pIMContext, "preedit_end", +- G_CALLBACK (signalIMPreeditEnd), this ); +- +- GetGenericData()->ErrorTrapPush(); +- gtk_im_context_set_client_window( m_pIMContext, widget_get_window(GTK_WIDGET(m_pFrame->m_pWindow)) ); +- gtk_im_context_focus_in( m_pIMContext ); +- GetGenericData()->ErrorTrapPop(); +- m_bFocused = true; +- } +-} +- +-void GtkSalFrame::IMHandler::deleteIMContext() +-{ +- if( m_pIMContext ) +- { +- // first give IC a chance to deinitialize +- GetGenericData()->ErrorTrapPush(); +- gtk_im_context_set_client_window( m_pIMContext, NULL ); +- GetGenericData()->ErrorTrapPop(); +- // destroy old IC +- g_object_unref( m_pIMContext ); +- m_pIMContext = NULL; +- } +-} +- +-void GtkSalFrame::IMHandler::doCallEndExtTextInput() +-{ +- m_aInputEvent.mpTextAttr = NULL; +- m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); +-} +- +-void GtkSalFrame::IMHandler::updateIMSpotLocation() +-{ +- SalExtTextInputPosEvent aPosEvent; +- m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvent ); +- GdkRectangle aArea; +- aArea.x = aPosEvent.mnX; +- aArea.y = aPosEvent.mnY; +- aArea.width = aPosEvent.mnWidth; +- aArea.height = aPosEvent.mnHeight; +- GetGenericData()->ErrorTrapPush(); +- gtk_im_context_set_cursor_location( m_pIMContext, &aArea ); +- GetGenericData()->ErrorTrapPop(); +-} +- +-void GtkSalFrame::IMHandler::sendEmptyCommit() +-{ +- vcl::DeletionListener aDel( m_pFrame ); +- +- SalExtTextInputEvent aEmptyEv; +- aEmptyEv.mnTime = 0; +- aEmptyEv.mpTextAttr = 0; +- aEmptyEv.maText.clear(); +- aEmptyEv.mnCursorPos = 0; +- aEmptyEv.mnCursorFlags = 0; +- aEmptyEv.mbOnlyCursor = False; +- m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEmptyEv ); +- if( ! aDel.isDeleted() ) +- m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); +-} +- +-void GtkSalFrame::IMHandler::endExtTextInput( sal_uInt16 /*nFlags*/ ) +-{ +- gtk_im_context_reset ( m_pIMContext ); +- +- if( m_aInputEvent.mpTextAttr ) +- { +- vcl::DeletionListener aDel( m_pFrame ); +- // delete preedit in sal (commit an empty string) +- sendEmptyCommit(); +- if( ! aDel.isDeleted() ) +- { +- // mark previous preedit state again (will e.g. be sent at focus gain) +- m_aInputEvent.mpTextAttr = &m_aInputFlags[0]; +- if( m_bFocused ) +- { +- // begin preedit again +- GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); +- } +- } +- } +-} +- +-void GtkSalFrame::IMHandler::focusChanged( bool bFocusIn ) +-{ +- m_bFocused = bFocusIn; +- if( bFocusIn ) +- { +- GetGenericData()->ErrorTrapPush(); +- gtk_im_context_focus_in( m_pIMContext ); +- GetGenericData()->ErrorTrapPop(); +- if( m_aInputEvent.mpTextAttr ) +- { +- sendEmptyCommit(); +- // begin preedit again +- GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); +- } +- } +- else +- { +- GetGenericData()->ErrorTrapPush(); +- gtk_im_context_focus_out( m_pIMContext ); +- GetGenericData()->ErrorTrapPop(); +- // cancel an eventual event posted to begin preedit again +- GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); +- } +-} +- +-bool GtkSalFrame::IMHandler::handleKeyEvent( GdkEventKey* pEvent ) +-{ +- vcl::DeletionListener aDel( m_pFrame ); +- +- if( pEvent->type == GDK_KEY_PRESS ) +- { +- // Add this key press event to the list of previous key presses +- // to which we compare key release events. If a later key release +- // event has a matching key press event in this list, we swallow +- // the key release because some GTK Input Methods don't swallow it +- // for us. +- m_aPrevKeyPresses.push_back( PreviousKeyPress(pEvent) ); +- m_nPrevKeyPresses++; +- +- // Also pop off the earliest key press event if there are more than 10 +- // already. +- while (m_nPrevKeyPresses > 10) +- { +- m_aPrevKeyPresses.pop_front(); +- m_nPrevKeyPresses--; +- } +- +- GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); +- +- // #i51353# update spot location on every key input since we cannot +- // know which key may activate a preedit choice window +- updateIMSpotLocation(); +- if( aDel.isDeleted() ) +- return true; +- +- gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); +- g_object_unref( pRef ); +- +- if( aDel.isDeleted() ) +- return true; +- +- m_bPreeditJustChanged = false; +- +- if( bResult ) +- return true; +- else +- { +- DBG_ASSERT( m_nPrevKeyPresses > 0, "key press has vanished !" ); +- if( ! m_aPrevKeyPresses.empty() ) // sanity check +- { +- // event was not swallowed, do not filter a following +- // key release event +- // note: this relies on gtk_im_context_filter_keypress +- // returning without calling a handler (in the "not swallowed" +- // case ) which might change the previous key press list so +- // we would pop the wrong event here +- m_aPrevKeyPresses.pop_back(); +- m_nPrevKeyPresses--; +- } +- } +- } +- +- // Determine if we got an earlier key press event corresponding to this key release +- if (pEvent->type == GDK_KEY_RELEASE) +- { +- GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); +- gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); +- g_object_unref( pRef ); +- +- if( aDel.isDeleted() ) +- return true; +- +- m_bPreeditJustChanged = false; +- +- std::list::iterator iter = m_aPrevKeyPresses.begin(); +- std::list::iterator iter_end = m_aPrevKeyPresses.end(); +- while (iter != iter_end) +- { +- // If we found a corresponding previous key press event, swallow the release +- // and remove the earlier key press from our list +- if (*iter == pEvent) +- { +- m_aPrevKeyPresses.erase(iter); +- m_nPrevKeyPresses--; +- return true; +- } +- ++iter; +- } +- +- if( bResult ) +- return true; +- } +- +- return false; +-} +- +-/* FIXME: +-* #122282# still more hacking: some IMEs never start a preedit but simply commit +-* in this case we cannot commit a single character. Workaround: do not do the +-* single key hack for enter or space if the unicode committed does not match +-*/ +- +-static bool checkSingleKeyCommitHack( guint keyval, sal_Unicode cCode ) +-{ +- bool bRet = true; +- switch( keyval ) +- { +- case GDK_KP_Enter: +- case GDK_Return: +- if( cCode != '\n' && cCode != '\r' ) +- bRet = false; +- break; +- case GDK_space: +- case GDK_KP_Space: +- if( cCode != ' ' ) +- bRet = false; +- break; +- default: +- break; +- } +- return bRet; +-} +- +-void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* pContext, gchar* pText, gpointer im_handler ) +-{ +- GtkSalFrame::IMHandler* pThis = static_cast(im_handler); +- +- SolarMutexGuard aGuard; +- vcl::DeletionListener aDel( pThis->m_pFrame ); +- { +- const bool bWasPreedit = +- (pThis->m_aInputEvent.mpTextAttr != 0) || +- pThis->m_bPreeditJustChanged; +- +- pThis->m_aInputEvent.mnTime = 0; +- pThis->m_aInputEvent.mpTextAttr = 0; +- pThis->m_aInputEvent.maText = OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ); +- pThis->m_aInputEvent.mnCursorPos = pThis->m_aInputEvent.maText.getLength(); +- pThis->m_aInputEvent.mnCursorFlags = 0; +- pThis->m_aInputEvent.mbOnlyCursor = False; +- +- pThis->m_aInputFlags.clear(); +- +- /* necessary HACK: all keyboard input comes in here as soon as a IMContext is set +- * which is logical and consequent. But since even simple input like +- * comes through the commit signal instead of signalKey +- * and all kinds of windows only implement KeyInput (e.g. PushButtons, +- * RadioButtons and a lot of other Controls), will send a single +- * KeyInput/KeyUp sequence instead of an ExtText event if there +- * never was a preedit and the text is only one character. +- * +- * In this case there the last ExtText event must have been +- * SALEVENT_ENDEXTTEXTINPUT, either because of a regular commit +- * or because there never was a preedit. +- */ +- bool bSingleCommit = false; +- if( ! bWasPreedit +- && pThis->m_aInputEvent.maText.getLength() == 1 +- && ! pThis->m_aPrevKeyPresses.empty() +- ) +- { +- const PreviousKeyPress& rKP = pThis->m_aPrevKeyPresses.back(); +- sal_Unicode aOrigCode = pThis->m_aInputEvent.maText[0]; +- +- if( checkSingleKeyCommitHack( rKP.keyval, aOrigCode ) ) +- { +- pThis->m_pFrame->doKeyCallback( rKP.state, rKP.keyval, rKP.hardware_keycode, rKP.group, rKP.time, aOrigCode, true, true ); +- bSingleCommit = true; +- } +- } +- if( ! bSingleCommit ) +- { +- pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); +- if( ! aDel.isDeleted() ) +- pThis->doCallEndExtTextInput(); +- } +- if( ! aDel.isDeleted() ) +- { +- // reset input event +- pThis->m_aInputEvent.maText.clear(); +- pThis->m_aInputEvent.mnCursorPos = 0; +- pThis->updateIMSpotLocation(); +- } +- } +-#ifdef SOLARIS +- // #i51356# workaround a solaris IIIMP bug +- // in case of partial commits the preedit changed signal +- // and commit signal come in wrong order +- if( ! aDel.isDeleted() ) +- signalIMPreeditChanged( pContext, im_handler ); +-#else +- (void) pContext; +-#endif +-} +- +-void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_handler ) +-{ +- GtkSalFrame::IMHandler* pThis = static_cast(im_handler); +- +- char* pText = NULL; +- PangoAttrList* pAttrs = NULL; +- gint nCursorPos = 0; +- +- gtk_im_context_get_preedit_string( pThis->m_pIMContext, +- &pText, +- &pAttrs, +- &nCursorPos ); +- if( pText && ! *pText ) // empty string +- { +- // change from nothing to nothing -> do not start preedit +- // e.g. this will activate input into a calc cell without +- // user input +- if( pThis->m_aInputEvent.maText.getLength() == 0 ) +- { +- g_free( pText ); +- pango_attr_list_unref( pAttrs ); +- return; +- } +- } +- +- pThis->m_bPreeditJustChanged = true; +- +- bool bEndPreedit = (!pText || !*pText) && pThis->m_aInputEvent.mpTextAttr != NULL; +- pThis->m_aInputEvent.mnTime = 0; +- pThis->m_aInputEvent.maText = pText ? OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ) : OUString(); +- pThis->m_aInputEvent.mnCursorPos = nCursorPos; +- pThis->m_aInputEvent.mnCursorFlags = 0; +- pThis->m_aInputEvent.mbOnlyCursor = False; +- +- pThis->m_aInputFlags = std::vector( std::max( 1, (int)pThis->m_aInputEvent.maText.getLength() ), 0 ); +- +- PangoAttrIterator *iter = pango_attr_list_get_iterator(pAttrs); +- do +- { +- GSList *attr_list = NULL; +- GSList *tmp_list = NULL; +- gint start, end; +- guint sal_attr = 0; +- +- pango_attr_iterator_range (iter, &start, &end); +- if (end == G_MAXINT) +- end = pText ? strlen (pText) : 0; +- if (end == start) +- continue; +- +- start = g_utf8_pointer_to_offset (pText, pText + start); +- end = g_utf8_pointer_to_offset (pText, pText + end); +- +- tmp_list = attr_list = pango_attr_iterator_get_attrs (iter); +- while (tmp_list) +- { +- PangoAttribute *pango_attr = static_cast(tmp_list->data); +- +- switch (pango_attr->klass->type) +- { +- case PANGO_ATTR_BACKGROUND: +- sal_attr |= (EXTTEXTINPUT_ATTR_HIGHLIGHT | EXTTEXTINPUT_CURSOR_INVISIBLE); +- break; +- case PANGO_ATTR_UNDERLINE: +- sal_attr |= EXTTEXTINPUT_ATTR_UNDERLINE; +- break; +- case PANGO_ATTR_STRIKETHROUGH: +- sal_attr |= EXTTEXTINPUT_ATTR_REDTEXT; +- break; +- default: +- break; +- } +- pango_attribute_destroy (pango_attr); +- tmp_list = tmp_list->next; +- } +- if (sal_attr == 0) +- sal_attr |= EXTTEXTINPUT_ATTR_UNDERLINE; +- g_slist_free (attr_list); +- +- // Set the sal attributes on our text +- for (int i = start; i < end; ++i) +- { +- SAL_WARN_IF(i >= static_cast(pThis->m_aInputFlags.size()), +- "vcl.gtk", "pango attrib out of range. Broken range: " +- << start << "," << end << " Legal range: 0," +- << pThis->m_aInputFlags.size()); +- if (i >= static_cast(pThis->m_aInputFlags.size())) +- continue; +- pThis->m_aInputFlags[i] |= sal_attr; +- } +- } while (pango_attr_iterator_next (iter)); +- pango_attr_iterator_destroy(iter); +- +- pThis->m_aInputEvent.mpTextAttr = &pThis->m_aInputFlags[0]; +- +- g_free( pText ); +- pango_attr_list_unref( pAttrs ); +- +- SolarMutexGuard aGuard; +- vcl::DeletionListener aDel( pThis->m_pFrame ); +- +- pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); +- if( bEndPreedit && ! aDel.isDeleted() ) +- pThis->doCallEndExtTextInput(); +- if( ! aDel.isDeleted() ) +- pThis->updateIMSpotLocation(); +-} +- +-void GtkSalFrame::IMHandler::signalIMPreeditStart( GtkIMContext*, gpointer /*im_handler*/ ) +-{ +-} +- +-void GtkSalFrame::IMHandler::signalIMPreeditEnd( GtkIMContext*, gpointer im_handler ) +-{ +- GtkSalFrame::IMHandler* pThis = static_cast(im_handler); +- +- pThis->m_bPreeditJustChanged = true; +- +- SolarMutexGuard aGuard; +- vcl::DeletionListener aDel( pThis->m_pFrame ); +- pThis->doCallEndExtTextInput(); +- if( ! aDel.isDeleted() ) +- pThis->updateIMSpotLocation(); +-} +- +-uno::Reference +- FindFocus(uno::Reference< accessibility::XAccessibleContext > xContext) +-{ +- if (!xContext.is()) +- uno::Reference< accessibility::XAccessibleEditableText >(); +- +- uno::Reference xState = xContext->getAccessibleStateSet(); +- if (xState.is()) +- { +- if (xState->contains(accessibility::AccessibleStateType::FOCUSED)) +- return uno::Reference(xContext, uno::UNO_QUERY); +- } +- +- for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i) +- { +- uno::Reference< accessibility::XAccessible > xChild = xContext->getAccessibleChild(i); +- if (!xChild.is()) +- continue; +- uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext(); +- if (!xChildContext.is()) +- continue; +- uno::Reference< accessibility::XAccessibleEditableText > xText = FindFocus(xChildContext); +- if (xText.is()) +- return xText; +- } +- return uno::Reference< accessibility::XAccessibleEditableText >(); +-} +- +-static uno::Reference lcl_GetxText(vcl::Window *pFocusWin) +-{ +- uno::Reference xText; +- try +- { +- uno::Reference< accessibility::XAccessible > xAccessible( pFocusWin->GetAccessible( true ) ); +- if (xAccessible.is()) +- xText = FindFocus(xAccessible->getAccessibleContext()); +- } +- catch(const uno::Exception& e) +- { +- SAL_WARN( "vcl.gtk", "Exception in getting input method surrounding text: " << e.Message); +- } +- return xText; +-} +- +-gboolean GtkSalFrame::IMHandler::signalIMRetrieveSurrounding( GtkIMContext* pContext, gpointer /*im_handler*/ ) +-{ +- vcl::Window *pFocusWin = Application::GetFocusWindow(); +- if (!pFocusWin) +- return true; +- +- uno::Reference xText = lcl_GetxText(pFocusWin); +- if (xText.is()) +- { +- sal_Int32 nPosition = xText->getCaretPosition(); +- OUString sAllText = xText->getText(); +- OString sUTF = OUStringToOString(sAllText, RTL_TEXTENCODING_UTF8); +- OUString sCursorText(sAllText.copy(0, nPosition)); +- gtk_im_context_set_surrounding(pContext, sUTF.getStr(), sUTF.getLength(), +- OUStringToOString(sCursorText, RTL_TEXTENCODING_UTF8).getLength()); +- return true; +- } +- +- return false; +-} +- +-gboolean GtkSalFrame::IMHandler::signalIMDeleteSurrounding( GtkIMContext*, gint offset, gint nchars, +- gpointer /*im_handler*/ ) +-{ +- vcl::Window *pFocusWin = Application::GetFocusWindow(); +- if (!pFocusWin) +- return true; +- +- uno::Reference xText = lcl_GetxText(pFocusWin); +- if (xText.is()) +- { +- sal_Int32 nPosition = xText->getCaretPosition(); +- // #i111768# range checking +- sal_Int32 nDeletePos = nPosition + offset; +- sal_Int32 nDeleteEnd = nDeletePos + nchars; +- if (nDeletePos < 0) +- nDeletePos = 0; +- if (nDeleteEnd < 0) +- nDeleteEnd = 0; +- if (nDeleteEnd > xText->getCharacterCount()) +- nDeleteEnd = xText->getCharacterCount(); +- +- xText->deleteText(nDeletePos, nDeleteEnd); +- //tdf91641 adjust cursor if deleted chars shift it forward (normal case) +- if (nDeletePos < nPosition) +- { +- if (nDeleteEnd <= nPosition) +- nPosition = nPosition - (nDeleteEnd - nDeletePos); +- else +- nPosition = nDeletePos; +- +- if (xText->getCharacterCount() >= nPosition) +- xText->setCaretPosition( nPosition ); +- } +- return true; +- } +- +- return false; +-} +- +-Size GtkSalDisplay::GetScreenSize( int nDisplayScreen ) +-{ +- Rectangle aRect = m_pSys->GetDisplayScreenPosSizePixel( nDisplayScreen ); +- return Size( aRect.GetWidth(), aRect.GetHeight() ); +-} +- +-Window GtkSalFrame::GetX11Window() +-{ +- return widget_get_xid(m_pWindow); +-} +- +-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/unx/gtk3/app/gtk3gtkinst.cxx b/vcl/unx/gtk3/app/gtk3gtkinst.cxx +deleted file mode 100644 +index 5716058..0000000 +--- a/vcl/unx/gtk3/app/gtk3gtkinst.cxx ++++ /dev/null +@@ -1,641 +0,0 @@ +-/* -*- 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 "../../gtk/app/gtkinst.cxx" +- +-#include +-#include "com/sun/star/lang/XServiceInfo.hpp" +-#include "com/sun/star/lang/XSingleServiceFactory.hpp" +-#include "com/sun/star/lang/XInitialization.hpp" +-#include "com/sun/star/lang/DisposedException.hpp" +-#include "com/sun/star/datatransfer/XTransferable.hpp" +-#include "com/sun/star/datatransfer/clipboard/XClipboard.hpp" +-#include "com/sun/star/datatransfer/clipboard/XClipboardEx.hpp" +-#include "com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp" +-#include "com/sun/star/datatransfer/clipboard/XClipboardListener.hpp" +-#include "com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp" +-#include "com/sun/star/datatransfer/dnd/XDragSource.hpp" +-#include "com/sun/star/datatransfer/dnd/XDropTarget.hpp" +-#include "com/sun/star/datatransfer/dnd/DNDConstants.hpp" +-#include +-#include +-#include "cppuhelper/compbase.hxx" +-#include "cppuhelper/implbase1.hxx" +-#include +- +-using namespace com::sun::star; +-using namespace com::sun::star::uno; +-using namespace com::sun::star::lang; +- +-namespace +-{ +- struct TypeEntry +- { +- const char* pNativeType; // string corresponding to nAtom for the case of nAtom being uninitialized +- const char* pType; // Mime encoding on our side +- }; +- +- static TypeEntry aConversionTab[] = +- { +- { "ISO10646-1", "text/plain;charset=utf-16" }, +- { "UTF8_STRING", "text/plain;charset=utf-8" }, +- { "UTF-8", "text/plain;charset=utf-8" }, +- { "text/plain;charset=UTF-8", "text/plain;charset=utf-8" }, +- // ISO encodings +- { "ISO8859-2", "text/plain;charset=iso8859-2" }, +- { "ISO8859-3", "text/plain;charset=iso8859-3" }, +- { "ISO8859-4", "text/plain;charset=iso8859-4" }, +- { "ISO8859-5", "text/plain;charset=iso8859-5" }, +- { "ISO8859-6", "text/plain;charset=iso8859-6" }, +- { "ISO8859-7", "text/plain;charset=iso8859-7" }, +- { "ISO8859-8", "text/plain;charset=iso8859-8" }, +- { "ISO8859-9", "text/plain;charset=iso8859-9" }, +- { "ISO8859-10", "text/plain;charset=iso8859-10" }, +- { "ISO8859-13", "text/plain;charset=iso8859-13" }, +- { "ISO8859-14", "text/plain;charset=iso8859-14" }, +- { "ISO8859-15", "text/plain;charset=iso8859-15" }, +- // asian encodings +- { "JISX0201.1976-0", "text/plain;charset=jisx0201.1976-0" }, +- { "JISX0208.1983-0", "text/plain;charset=jisx0208.1983-0" }, +- { "JISX0208.1990-0", "text/plain;charset=jisx0208.1990-0" }, +- { "JISX0212.1990-0", "text/plain;charset=jisx0212.1990-0" }, +- { "GB2312.1980-0", "text/plain;charset=gb2312.1980-0" }, +- { "KSC5601.1992-0", "text/plain;charset=ksc5601.1992-0" }, +- // eastern european encodings +- { "KOI8-R", "text/plain;charset=koi8-r" }, +- { "KOI8-U", "text/plain;charset=koi8-u" }, +- // String (== iso8859-1) +- { "STRING", "text/plain;charset=iso8859-1" }, +- // special for compound text +- { "COMPOUND_TEXT", "text/plain;charset=compound_text" }, +- +- // PIXMAP +- { "PIXMAP", "image/bmp" } +- }; +- +- class DataFlavorEq : public std::unary_function +- { +- private: +- const css::datatransfer::DataFlavor& m_rData; +- public: +- explicit DataFlavorEq(const css::datatransfer::DataFlavor& rData) : m_rData(rData) {} +- bool operator() (const css::datatransfer::DataFlavor& rData) const +- { +- return rData.MimeType == m_rData.MimeType && +- rData.DataType == m_rData.DataType; +- } +- }; +-} +- +-class GtkTransferable : public ::cppu::WeakImplHelper1 < +- css::datatransfer::XTransferable > +-{ +-private: +- GdkAtom m_nSelection; +- std::map m_aMimeTypeToAtom; +-public: +- +- GtkTransferable(GdkAtom nSelection) +- : m_nSelection(nSelection) +- { +- } +- +- /* +- * XTransferable +- */ +- +- virtual css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor& rFlavor) +- throw(css::datatransfer::UnsupportedFlavorException, +- css::io::IOException, +- css::uno::RuntimeException, std::exception +- ) SAL_OVERRIDE +- { +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- if (rFlavor.MimeType == "text/plain;charset=utf-16") +- { +- OUString aStr; +- gchar *pText = gtk_clipboard_wait_for_text(clipboard); +- if (pText) +- aStr = OUString(pText, rtl_str_getLength(pText), RTL_TEXTENCODING_UTF8); +- g_free(pText); +- css::uno::Any aRet; +- aRet <<= aStr.replaceAll("\r\n", "\n"); +- return aRet; +- } +- +- auto it = m_aMimeTypeToAtom.find(rFlavor.MimeType); +- if (it == m_aMimeTypeToAtom.end()) +- return css::uno::Any(); +- +- css::uno::Any aRet; +- GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, +- it->second); +- gint length; +- const guchar *rawdata = gtk_selection_data_get_data_with_length(data, +- &length); +- Sequence aSeq(reinterpret_cast(rawdata), length); +- gtk_selection_data_free(data); +- aRet <<= aSeq; +- return aRet; +- } +- +- std::vector getTransferDataFlavorsAsVector() +- { +- std::vector aVector; +- +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- +- GdkAtom *targets; +- gint n_targets; +- if (gtk_clipboard_wait_for_targets(clipboard, &targets, &n_targets)) +- { +- bool bHaveText = false, bHaveUTF16 = false; +- +- for (gint i = 0; i < n_targets; ++i) +- { +- gchar* pName = gdk_atom_name(targets[i]); +- const char* pFinalName = pName; +- css::datatransfer::DataFlavor aFlavor; +- +- for (size_t j = 0; j < SAL_N_ELEMENTS(aConversionTab); ++j) +- { +- if (rtl_str_compare(pName, aConversionTab[j].pNativeType) == 0) +- { +- pFinalName = aConversionTab[j].pType; +- break; +- } +- } +- +- aFlavor.MimeType = OUString(pFinalName, +- rtl_str_getLength(pFinalName), +- RTL_TEXTENCODING_UTF8); +- +- m_aMimeTypeToAtom[aFlavor.MimeType] = targets[i]; +- +- aFlavor.DataType = cppu::UnoType>::get(); +- +- sal_Int32 nIndex(0); +- if (aFlavor.MimeType.getToken(0, ';', nIndex) == "text/plain") +- { +- bHaveText = true; +- OUString aToken(aFlavor.MimeType.getToken(0, ';', nIndex)); +- if (aToken == "charset=utf-16") +- { +- bHaveUTF16 = true; +- aFlavor.DataType = cppu::UnoType::get(); +- } +- } +- aVector.push_back(aFlavor); +- g_free(pName); +- } +- +- g_free(targets); +- +- //If we have text, but no UTF-16 format which is basically the only +- //text-format LibreOffice supports for cnp then claim we do and we +- //will convert on demand +- if (bHaveText && !bHaveUTF16) +- { +- css::datatransfer::DataFlavor aFlavor; +- aFlavor.MimeType = "text/plain;charset=utf-16"; +- aFlavor.DataType = cppu::UnoType::get(); +- aVector.push_back(aFlavor); +- } +- } +- +- return aVector; +- } +- +- virtual css::uno::Sequence SAL_CALL getTransferDataFlavors() +- throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE +- { +- return comphelper::containerToSequence(getTransferDataFlavorsAsVector()); +- } +- +- virtual sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) +- throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE +- { +- const std::vector aAll = +- getTransferDataFlavorsAsVector(); +- +- return std::find_if(aAll.begin(), aAll.end(), DataFlavorEq(rFlavor)) != aAll.end(); +- } +-}; +- +-//We want to use gtk_clipboard_get_owner own owner-change to distinguish between +-//us gaining the clipboard ownership vs losing it. To do that we need to use +-//gtk_clipboard_set_with_owner and to do that we need a GObject, so define +-//one here for that purpose and just give it a VclGtkClipboard* member +-class VclGtkClipboard; +- +-typedef struct _ClipboardOwner ClipboardOwner; +-typedef struct _ClipboardOwnerClass ClipboardOwnerClass; +- +-struct _ClipboardOwner +-{ +- GObject parent_instance; +- +- /* instance members */ +- VclGtkClipboard* m_pThis; +-}; +- +-struct _ClipboardOwnerClass +-{ +- GObjectClass parent_class; +- +- /* class members */ +-}; +- +-#define CLIPBOARD_OWNER_OBJECT (clipboard_owner_get_type ()) +-#define CLIPBOARD_OWNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLIPBOARD_OWNER_OBJECT, ClipboardOwner)) +- +-#ifdef __GNUC__ +-#pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wunused-function" +-#endif +-G_DEFINE_TYPE(ClipboardOwner, clipboard_owner, G_TYPE_OBJECT); +-#ifdef __GNUC__ +-#pragma GCC diagnostic pop +-#endif +- +-static void clipboard_owner_class_init (ClipboardOwnerClass *) +-{ +-} +- +-static void clipboard_owner_init(ClipboardOwner *) +-{ +-} +- +-class VclGtkClipboard : +- public cppu::WeakComponentImplHelper< +- datatransfer::clipboard::XSystemClipboard, +- XServiceInfo> +-{ +- GdkAtom m_nSelection; +- osl::Mutex m_aMutex; +- ClipboardOwner* m_pOwner; +- gulong m_nOwnerChangedSignalId; +- Reference m_aContents; +- Reference m_aOwner; +- std::list< Reference > m_aListeners; +- std::vector m_aGtkTargets; +- std::vector m_aInfoToFlavor; +- +-public: +- +- VclGtkClipboard(GdkAtom nSelection); +- virtual ~VclGtkClipboard(); +- +- /* +- * XServiceInfo +- */ +- +- virtual OUString SAL_CALL getImplementationName() throw( RuntimeException, std::exception ) SAL_OVERRIDE; +- virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw( RuntimeException, std::exception ) SAL_OVERRIDE; +- virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( RuntimeException, std::exception ) SAL_OVERRIDE; +- +- static OUString getImplementationName_static(); +- static Sequence< OUString > getSupportedServiceNames_static(); +- +- /* +- * XClipboard +- */ +- +- virtual Reference< css::datatransfer::XTransferable > SAL_CALL getContents() +- throw(RuntimeException, std::exception) SAL_OVERRIDE; +- +- virtual void SAL_CALL setContents( +- const Reference< css::datatransfer::XTransferable >& xTrans, +- const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) +- throw(RuntimeException, std::exception) SAL_OVERRIDE; +- +- virtual OUString SAL_CALL getName() +- throw(RuntimeException, std::exception) SAL_OVERRIDE; +- +- /* +- * XClipboardEx +- */ +- +- virtual sal_Int8 SAL_CALL getRenderingCapabilities() +- throw(RuntimeException, std::exception) SAL_OVERRIDE; +- +- /* +- * XClipboardNotifier +- */ +- virtual void SAL_CALL addClipboardListener( +- const Reference< css::datatransfer::clipboard::XClipboardListener >& listener ) +- throw(RuntimeException, std::exception) SAL_OVERRIDE; +- +- virtual void SAL_CALL removeClipboardListener( +- const Reference< css::datatransfer::clipboard::XClipboardListener >& listener ) +- throw(RuntimeException, std::exception) SAL_OVERRIDE; +- +- void ClipboardGet(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info); +- void ClipboardClear(GtkClipboard *clipboard); +- void OwnerChanged(GtkClipboard *clipboard, GdkEvent *event); +-private: +- GtkTargetEntry makeGtkTargetEntry(const css::datatransfer::DataFlavor& rFlavor); +-}; +- +-OUString VclGtkClipboard::getImplementationName_static() +-{ +- return OUString( "com.sun.star.datatransfer.VclGtkClipboard" ); +-} +- +-Sequence< OUString > VclGtkClipboard::getSupportedServiceNames_static() +-{ +- Sequence< OUString > aRet(1); +- aRet[0] = "com.sun.star.datatransfer.clipboard.SystemClipboard"; +- return aRet; +-} +- +-OUString VclGtkClipboard::getImplementationName() throw( RuntimeException, std::exception ) +-{ +- return getImplementationName_static(); +-} +- +-Sequence< OUString > VclGtkClipboard::getSupportedServiceNames() throw( RuntimeException, std::exception ) +-{ +- return getSupportedServiceNames_static(); +-} +- +-sal_Bool VclGtkClipboard::supportsService( const OUString& ServiceName ) throw( RuntimeException, std::exception ) +-{ +- return cppu::supportsService(this, ServiceName); +-} +- +-Reference< css::datatransfer::XTransferable > VclGtkClipboard::getContents() throw( RuntimeException, std::exception ) +-{ +- if (G_OBJECT(m_pOwner) != gtk_clipboard_get_owner(gtk_clipboard_get(m_nSelection)) && +- !m_aContents.is()) +- { +- //tdf#93887 This is the system clipboard/selection. We fetch it when we are not +- //the owner of the clipboard and have not already fetched it. +- m_aContents = new GtkTransferable(m_nSelection); +- } +- return m_aContents; +-} +- +-void VclGtkClipboard::ClipboardGet(GtkClipboard* /*clipboard*/, GtkSelectionData *selection_data, +- guint info) +-{ +- if (!m_aContents.is()) +- return; +- +- GdkAtom type(gdk_atom_intern(OUStringToOString(m_aInfoToFlavor[info].MimeType, +- RTL_TEXTENCODING_UTF8).getStr(), +- false)); +- +- css::datatransfer::DataFlavor aFlavor(m_aInfoToFlavor[info]); +- if (aFlavor.MimeType == "UTF8_STRING" || aFlavor.MimeType == "STRING") +- aFlavor.MimeType = "text/plain;charset=utf-8"; +- +- Sequence aData; +- Any aValue; +- +- try +- { +- aValue = m_aContents->getTransferData(aFlavor); +- } +- catch(...) +- { +- } +- +- if (aValue.getValueTypeClass() == TypeClass_STRING) +- { +- OUString aString; +- aValue >>= aString; +- aData = Sequence< sal_Int8 >( reinterpret_cast(aString.getStr()), aString.getLength() * sizeof( sal_Unicode ) ); +- } +- else if (aValue.getValueType() == cppu::UnoType>::get()) +- { +- aValue >>= aData; +- } +- else if (aFlavor.MimeType == "text/plain;charset=utf-8") +- { +- //didn't have utf-8, try utf-16 and convert +- aFlavor.MimeType = "text/plain;charset=utf-16"; +- aFlavor.DataType = cppu::UnoType::get(); +- try +- { +- aValue = m_aContents->getTransferData(aFlavor); +- } +- catch(...) +- { +- } +- OUString aString; +- aValue >>= aString; +- OString aUTF8String(OUStringToOString(aString, RTL_TEXTENCODING_UTF8)); +- gtk_selection_data_set(selection_data, type, 8, +- reinterpret_cast(aUTF8String.getStr()), +- aUTF8String.getLength()); +- return; +- } +- +- gtk_selection_data_set(selection_data, type, 8, +- reinterpret_cast(aData.getArray()), +- aData.getLength()); +-} +- +-void VclGtkClipboard::OwnerChanged(GtkClipboard* clipboard, GdkEvent* /*event*/) +-{ +- if (G_OBJECT(m_pOwner) != gtk_clipboard_get_owner(clipboard)) +- { +- //null out m_aContents to return control to the system-one which +- //will be retrieved if getContents is called again +- setContents(Reference(), +- Reference()); +- } +-} +- +-void VclGtkClipboard::ClipboardClear(GtkClipboard * /*clipboard*/) +-{ +- for (auto &a : m_aGtkTargets) +- free(a.target); +- m_aGtkTargets.clear(); +-} +- +-GtkTargetEntry VclGtkClipboard::makeGtkTargetEntry(const css::datatransfer::DataFlavor& rFlavor) +-{ +- GtkTargetEntry aEntry; +- aEntry.target = +- g_strdup(OUStringToOString(rFlavor.MimeType, RTL_TEXTENCODING_UTF8).getStr()); +- aEntry.flags = 0; +- auto it = std::find_if(m_aInfoToFlavor.begin(), m_aInfoToFlavor.end(), +- DataFlavorEq(rFlavor)); +- if (it != m_aInfoToFlavor.end()) +- aEntry.info = std::distance(m_aInfoToFlavor.begin(), it); +- else +- { +- aEntry.info = m_aInfoToFlavor.size(); +- m_aInfoToFlavor.push_back(rFlavor); +- } +- return aEntry; +-} +- +-namespace +-{ +- void ClipboardGetFunc(GtkClipboard *clipboard, GtkSelectionData *selection_data, +- guint info, +- gpointer user_data_or_owner) +- { +- VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis; +- pThis->ClipboardGet(clipboard, selection_data, info); +- } +- +- void ClipboardClearFunc(GtkClipboard *clipboard, gpointer user_data_or_owner) +- { +- VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis; +- pThis->ClipboardClear(clipboard); +- } +- +- void handle_owner_change(GtkClipboard *clipboard, GdkEvent *event, gpointer user_data) +- { +- VclGtkClipboard* pThis = static_cast(user_data); +- pThis->OwnerChanged(clipboard, event); +- } +-} +- +-VclGtkClipboard::VclGtkClipboard(GdkAtom nSelection) +- : cppu::WeakComponentImplHelper +- (m_aMutex) +- , m_nSelection(nSelection) +-{ +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- m_nOwnerChangedSignalId = g_signal_connect(clipboard, "owner-change", +- G_CALLBACK(handle_owner_change), this); +- m_pOwner = CLIPBOARD_OWNER(g_object_new(CLIPBOARD_OWNER_OBJECT, NULL)); +- m_pOwner->m_pThis = this; +-} +- +-VclGtkClipboard::~VclGtkClipboard() +-{ +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- g_signal_handler_disconnect(clipboard, m_nOwnerChangedSignalId); +- g_object_unref(m_pOwner); +-} +- +-void VclGtkClipboard::setContents( +- const Reference< css::datatransfer::XTransferable >& xTrans, +- const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) +- throw( RuntimeException, std::exception ) +-{ +- osl::ClearableMutexGuard aGuard( m_aMutex ); +- Reference< datatransfer::clipboard::XClipboardOwner > xOldOwner( m_aOwner ); +- Reference< datatransfer::XTransferable > xOldContents( m_aContents ); +- m_aContents = xTrans; +- m_aOwner = xClipboardOwner; +- +- std::list< Reference< datatransfer::clipboard::XClipboardListener > > xListeners( m_aListeners ); +- datatransfer::clipboard::ClipboardEvent aEv; +- +- if (m_aContents.is()) +- { +- css::uno::Sequence aFormats = xTrans->getTransferDataFlavors(); +- std::vector aGtkTargets; +- bool bHaveText(false), bHaveUTF8(false); +- for (int i = 0; i < aFormats.getLength(); ++i) +- { +- const css::datatransfer::DataFlavor& rFlavor = aFormats[i]; +- +- sal_Int32 nIndex(0); +- if (rFlavor.MimeType.getToken(0, ';', nIndex) == "text/plain") +- { +- bHaveText = true; +- OUString aToken(rFlavor.MimeType.getToken(0, ';', nIndex)); +- if (aToken == "charset=utf-8") +- { +- bHaveUTF8 = true; +- } +- } +- GtkTargetEntry aEntry(makeGtkTargetEntry(rFlavor)); +- aGtkTargets.push_back(aEntry); +- } +- +- if (bHaveText) +- { +- css::datatransfer::DataFlavor aFlavor; +- aFlavor.DataType = cppu::UnoType>::get(); +- if (!bHaveUTF8) +- { +- aFlavor.MimeType = "text/plain;charset=utf-8"; +- aGtkTargets.push_back(makeGtkTargetEntry(aFlavor)); +- } +- aFlavor.MimeType = "UTF8_STRING"; +- aGtkTargets.push_back(makeGtkTargetEntry(aFlavor)); +- aFlavor.MimeType = "STRING"; +- aGtkTargets.push_back(makeGtkTargetEntry(aFlavor)); +- } +- +- //if there was a previous gtk_clipboard_set_with_data call then +- //ClipboardClearFunc will be called now +- GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +- //use with_owner with m_pOwner so we can distinguish in handle_owner_change +- //if we have gained or lost ownership of the clipboard +- gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(), +- ClipboardGetFunc, ClipboardClearFunc, G_OBJECT(m_pOwner)); +- m_aGtkTargets = aGtkTargets; +- } +- +- aEv.Contents = getContents(); +- +- aGuard.clear(); +- +- if( xOldOwner.is() && xOldOwner != xClipboardOwner ) +- xOldOwner->lostOwnership( this, xOldContents ); +- for( std::list< Reference< datatransfer::clipboard::XClipboardListener > >::iterator it = +- xListeners.begin(); it != xListeners.end() ; ++it ) +- { +- (*it)->changedContents( aEv ); +- } +-} +- +-OUString VclGtkClipboard::getName() throw( RuntimeException, std::exception ) +-{ +- return OUString( "CLIPBOARD" ); +-} +- +-sal_Int8 VclGtkClipboard::getRenderingCapabilities() throw( RuntimeException, std::exception ) +-{ +- return 0; +-} +- +-void VclGtkClipboard::addClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener ) +- throw( RuntimeException, std::exception ) +-{ +- osl::ClearableMutexGuard aGuard( m_aMutex ); +- +- m_aListeners.push_back( listener ); +-} +- +-void VclGtkClipboard::removeClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener ) +- throw( RuntimeException, std::exception ) +-{ +- osl::ClearableMutexGuard aGuard( m_aMutex ); +- +- m_aListeners.remove( listener ); +-} +- +-Reference< XInterface > GtkInstance::CreateClipboard(const Sequence< Any >& arguments) +-{ +- OUString sel; +- if (arguments.getLength() == 0) { +- sel = "CLIPBOARD"; +- } else if (arguments.getLength() != 1 || !(arguments[0] >>= sel)) { +- throw css::lang::IllegalArgumentException( +- "bad GtkInstance::CreateClipboard arguments", +- css::uno::Reference(), -1); +- } +- +- GdkAtom nSelection = (sel == "CLIPBOARD") ? GDK_SELECTION_CLIPBOARD : GDK_SELECTION_PRIMARY; +- +- return Reference< XInterface >( static_cast(new VclGtkClipboard(nSelection)) ); +-} +- +-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +new file mode 100644 +index 0000000..dcfebbf +--- /dev/null ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -0,0 +1,3805 @@ ++/* -*- 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/. ++ * ++ * This file incorporates work covered by the following license notice: ++ * ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed ++ * with this work for additional information regarding copyright ++ * ownership. The ASF licenses this file to you under the Apache ++ * License, Version 2.0 (the "License"); you may not use this file ++ * except in compliance with the License. You may obtain a copy of ++ * the License at http://www.apache.org/licenses/LICENSE-2.0 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++# include ++#endif ++#if defined ENABLE_GMENU_INTEGRATION // defined in gtksalmenu.hxx above ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include ++ ++#if OSL_DEBUG_LEVEL > 1 ++# include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#ifdef ENABLE_DBUS ++#include ++ ++#define GSM_DBUS_SERVICE "org.gnome.SessionManager" ++#define GSM_DBUS_PATH "/org/gnome/SessionManager" ++#define GSM_DBUS_INTERFACE "org.gnome.SessionManager" ++#endif ++ ++#include ++ ++#define IS_WIDGET_REALIZED gtk_widget_get_realized ++#define IS_WIDGET_MAPPED gtk_widget_get_mapped ++ ++using namespace com::sun::star; ++ ++int GtkSalFrame::m_nFloats = 0; ++ ++#if defined ENABLE_GMENU_INTEGRATION ++static GDBusConnection* pSessionBus = NULL; ++#endif ++ ++static sal_uInt16 GetKeyModCode( guint state ) ++{ ++ sal_uInt16 nCode = 0; ++ if( (state & GDK_SHIFT_MASK) ) ++ nCode |= KEY_SHIFT; ++ if( (state & GDK_CONTROL_MASK) ) ++ nCode |= KEY_MOD1; ++ if( (state & GDK_MOD1_MASK) ) ++ nCode |= KEY_MOD2; ++ ++ // Map Meta/Super keys to MOD3 modifier on all Unix systems ++ // except Mac OS X ++ if ( (state & GDK_META_MASK ) || ( state & GDK_SUPER_MASK ) ) ++ nCode |= KEY_MOD3; ++ return nCode; ++} ++ ++static sal_uInt16 GetMouseModCode( guint state ) ++{ ++ sal_uInt16 nCode = GetKeyModCode( state ); ++ if( (state & GDK_BUTTON1_MASK) ) ++ nCode |= MOUSE_LEFT; ++ if( (state & GDK_BUTTON2_MASK) ) ++ nCode |= MOUSE_MIDDLE; ++ if( (state & GDK_BUTTON3_MASK) ) ++ nCode |= MOUSE_RIGHT; ++ ++ return nCode; ++} ++ ++static sal_uInt16 GetKeyCode( guint keyval ) ++{ ++ sal_uInt16 nCode = 0; ++ if( keyval >= GDK_0 && keyval <= GDK_9 ) ++ nCode = KEY_0 + (keyval-GDK_0); ++ else if( keyval >= GDK_KP_0 && keyval <= GDK_KP_9 ) ++ nCode = KEY_0 + (keyval-GDK_KP_0); ++ else if( keyval >= GDK_A && keyval <= GDK_Z ) ++ nCode = KEY_A + (keyval-GDK_A ); ++ else if( keyval >= GDK_a && keyval <= GDK_z ) ++ nCode = KEY_A + (keyval-GDK_a ); ++ else if( keyval >= GDK_F1 && keyval <= GDK_F26 ) ++ { ++ switch( keyval ) ++ { ++ // - - - - - Sun keyboard, see vcl/unx/source/app/saldisp.cxx ++ case GDK_L2: ++ nCode = KEY_F12; ++ break; ++ case GDK_L3: nCode = KEY_PROPERTIES; break; ++ case GDK_L4: nCode = KEY_UNDO; break; ++ case GDK_L6: nCode = KEY_COPY; break; // KEY_F16 ++ case GDK_L8: nCode = KEY_PASTE; break; // KEY_F18 ++ case GDK_L10: nCode = KEY_CUT; break; // KEY_F20 ++ default: ++ nCode = KEY_F1 + (keyval-GDK_F1); break; ++ } ++ } ++ else ++ { ++ switch( keyval ) ++ { ++ case GDK_KP_Down: ++ case GDK_Down: nCode = KEY_DOWN; break; ++ case GDK_KP_Up: ++ case GDK_Up: nCode = KEY_UP; break; ++ case GDK_KP_Left: ++ case GDK_Left: nCode = KEY_LEFT; break; ++ case GDK_KP_Right: ++ case GDK_Right: nCode = KEY_RIGHT; break; ++ case GDK_KP_Begin: ++ case GDK_KP_Home: ++ case GDK_Begin: ++ case GDK_Home: nCode = KEY_HOME; break; ++ case GDK_KP_End: ++ case GDK_End: nCode = KEY_END; break; ++ case GDK_KP_Page_Up: ++ case GDK_Page_Up: nCode = KEY_PAGEUP; break; ++ case GDK_KP_Page_Down: ++ case GDK_Page_Down: nCode = KEY_PAGEDOWN; break; ++ case GDK_KP_Enter: ++ case GDK_Return: nCode = KEY_RETURN; break; ++ case GDK_Escape: nCode = KEY_ESCAPE; break; ++ case GDK_ISO_Left_Tab: ++ case GDK_KP_Tab: ++ case GDK_Tab: nCode = KEY_TAB; break; ++ case GDK_BackSpace: nCode = KEY_BACKSPACE; break; ++ case GDK_KP_Space: ++ case GDK_space: nCode = KEY_SPACE; break; ++ case GDK_KP_Insert: ++ case GDK_Insert: nCode = KEY_INSERT; break; ++ case GDK_KP_Delete: ++ case GDK_Delete: nCode = KEY_DELETE; break; ++ case GDK_plus: ++ case GDK_KP_Add: nCode = KEY_ADD; break; ++ case GDK_minus: ++ case GDK_KP_Subtract: nCode = KEY_SUBTRACT; break; ++ case GDK_asterisk: ++ case GDK_KP_Multiply: nCode = KEY_MULTIPLY; break; ++ case GDK_slash: ++ case GDK_KP_Divide: nCode = KEY_DIVIDE; break; ++ case GDK_period: nCode = KEY_POINT; break; ++ case GDK_decimalpoint: nCode = KEY_POINT; break; ++ case GDK_comma: nCode = KEY_COMMA; break; ++ case GDK_less: nCode = KEY_LESS; break; ++ case GDK_greater: nCode = KEY_GREATER; break; ++ case GDK_KP_Equal: ++ case GDK_equal: nCode = KEY_EQUAL; break; ++ case GDK_Find: nCode = KEY_FIND; break; ++ case GDK_Menu: nCode = KEY_CONTEXTMENU;break; ++ case GDK_Help: nCode = KEY_HELP; break; ++ case GDK_Undo: nCode = KEY_UNDO; break; ++ case GDK_Redo: nCode = KEY_REPEAT; break; ++ case GDK_KP_Decimal: ++ case GDK_KP_Separator: nCode = KEY_DECIMAL; break; ++ case GDK_asciitilde: nCode = KEY_TILDE; break; ++ case GDK_leftsinglequotemark: ++ case GDK_quoteleft: nCode = KEY_QUOTELEFT; break; ++ case GDK_bracketleft: nCode = KEY_BRACKETLEFT; break; ++ case GDK_bracketright: nCode = KEY_BRACKETRIGHT; break; ++ case GDK_semicolon: nCode = KEY_SEMICOLON; break; ++ case GDK_quoteright: nCode = KEY_QUOTERIGHT; break; ++ // some special cases, also see saldisp.cxx ++ // - - - - - - - - - - - - - Apollo - - - - - - - - - - - - - 0x1000 ++ case 0x1000FF02: // apXK_Copy ++ nCode = KEY_COPY; ++ break; ++ case 0x1000FF03: // apXK_Cut ++ nCode = KEY_CUT; ++ break; ++ case 0x1000FF04: // apXK_Paste ++ nCode = KEY_PASTE; ++ break; ++ case 0x1000FF14: // apXK_Repeat ++ nCode = KEY_REPEAT; ++ break; ++ // Exit, Save ++ // - - - - - - - - - - - - - - D E C - - - - - - - - - - - - - 0x1000 ++ case 0x1000FF00: ++ nCode = KEY_DELETE; ++ break; ++ // - - - - - - - - - - - - - - H P - - - - - - - - - - - - - 0x1000 ++ case 0x1000FF73: // hpXK_DeleteChar ++ nCode = KEY_DELETE; ++ break; ++ case 0x1000FF74: // hpXK_BackTab ++ case 0x1000FF75: // hpXK_KP_BackTab ++ nCode = KEY_TAB; ++ break; ++ // - - - - - - - - - - - - - - I B M - - - - - - - - - - - - - ++ // - - - - - - - - - - - - - - O S F - - - - - - - - - - - - - 0x1004 ++ case 0x1004FF02: // osfXK_Copy ++ nCode = KEY_COPY; ++ break; ++ case 0x1004FF03: // osfXK_Cut ++ nCode = KEY_CUT; ++ break; ++ case 0x1004FF04: // osfXK_Paste ++ nCode = KEY_PASTE; ++ break; ++ case 0x1004FF07: // osfXK_BackTab ++ nCode = KEY_TAB; ++ break; ++ case 0x1004FF08: // osfXK_BackSpace ++ nCode = KEY_BACKSPACE; ++ break; ++ case 0x1004FF1B: // osfXK_Escape ++ nCode = KEY_ESCAPE; ++ break; ++ // Up, Down, Left, Right, PageUp, PageDown ++ // - - - - - - - - - - - - - - S C O - - - - - - - - - - - - - ++ // - - - - - - - - - - - - - - S G I - - - - - - - - - - - - - 0x1007 ++ // - - - - - - - - - - - - - - S N I - - - - - - - - - - - - - ++ // - - - - - - - - - - - - - - S U N - - - - - - - - - - - - - 0x1005 ++ case 0x1005FF10: // SunXK_F36 ++ nCode = KEY_F11; ++ break; ++ case 0x1005FF11: // SunXK_F37 ++ nCode = KEY_F12; ++ break; ++ case 0x1005FF70: // SunXK_Props ++ nCode = KEY_PROPERTIES; ++ break; ++ case 0x1005FF71: // SunXK_Front ++ nCode = KEY_FRONT; ++ break; ++ case 0x1005FF72: // SunXK_Copy ++ nCode = KEY_COPY; ++ break; ++ case 0x1005FF73: // SunXK_Open ++ nCode = KEY_OPEN; ++ break; ++ case 0x1005FF74: // SunXK_Paste ++ nCode = KEY_PASTE; ++ break; ++ case 0x1005FF75: // SunXK_Cut ++ nCode = KEY_CUT; ++ break; ++ } ++ } ++ ++ return nCode; ++} ++ ++static guint GetKeyValFor(GdkKeymap* pKeyMap, guint16 hardware_keycode, guint8 group) ++{ ++ guint updated_keyval = 0; ++ gdk_keymap_translate_keyboard_state(pKeyMap, hardware_keycode, ++ (GdkModifierType)0, group, &updated_keyval, NULL, NULL, NULL); ++ return updated_keyval; ++} ++ ++// F10 means either KEY_F10 or KEY_MENU, which has to be decided ++// in the independent part. ++struct KeyAlternate ++{ ++ sal_uInt16 nKeyCode; ++ sal_Unicode nCharCode; ++ KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {} ++ KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {} ++}; ++ ++inline KeyAlternate ++GetAlternateKeyCode( const sal_uInt16 nKeyCode ) ++{ ++ KeyAlternate aAlternate; ++ ++ switch( nKeyCode ) ++ { ++ case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break; ++ case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break; ++ } ++ ++ return aAlternate; ++} ++ ++namespace { ++/// Decouple SalFrame lifetime from damagetracker lifetime ++struct DamageTracker : public basebmp::IBitmapDeviceDamageTracker ++{ ++ DamageTracker(GtkSalFrame& rFrame) : m_rFrame(rFrame) ++ {} ++ ++ virtual ~DamageTracker() {} ++ ++ virtual void damaged(const basegfx::B2IBox& rDamageRect) const SAL_OVERRIDE ++ { ++ m_rFrame.damaged(rDamageRect); ++ } ++ ++ GtkSalFrame& m_rFrame; ++}; ++} ++ ++static bool dumpframes = false; ++ ++void GtkSalFrame::doKeyCallback( guint state, ++ guint keyval, ++ guint16 hardware_keycode, ++ guint8 group, ++ guint32 time, ++ sal_Unicode aOrigCode, ++ bool bDown, ++ bool bSendRelease ++ ) ++{ ++ SalKeyEvent aEvent; ++ ++ aEvent.mnTime = time; ++ aEvent.mnCharCode = aOrigCode; ++ aEvent.mnRepeat = 0; ++ ++ vcl::DeletionListener aDel( this ); ++ ++#if 0 ++ // shift-zero forces a re-draw and event is swallowed ++ if (keyval == GDK_0) ++ { ++ fprintf( stderr, "force widget_queue_draw\n"); ++ gtk_widget_queue_draw (m_pFixedContainer); ++ return; ++ } ++ else if (keyval == GDK_1) ++ { ++ fprintf( stderr, "force repaint all\n"); ++ TriggerPaintEvent(); ++ return; ++ } ++ else if (keyval == GDK_2) ++ { ++ dumpframes = !dumpframes; ++ fprintf(stderr, "toggle dump frames to %d\n", dumpframes); ++ return; ++ } ++#endif ++ ++ /* ++ * #i42122# translate all keys with Ctrl and/or Alt to group 0 else ++ * shortcuts (e.g. Ctrl-o) will not work but be inserted by the ++ * application ++ * ++ * #i52338# do this for all keys that the independent part has no key code ++ * for ++ * ++ * fdo#41169 rather than use group 0, detect if there is a group which can ++ * be used to input Latin text and use that if possible ++ */ ++ aEvent.mnCode = GetKeyCode( keyval ); ++ if( aEvent.mnCode == 0 ) ++ { ++ gint best_group = SAL_MAX_INT32; ++ ++ // Try and find Latin layout ++ GdkKeymap* keymap = gdk_keymap_get_default(); ++ GdkKeymapKey *keys; ++ gint n_keys; ++ if (gdk_keymap_get_entries_for_keyval(keymap, GDK_A, &keys, &n_keys)) ++ { ++ // Find the lowest group that supports Latin layout ++ for (gint i = 0; i < n_keys; ++i) ++ { ++ if (keys[i].level != 0 && keys[i].level != 1) ++ continue; ++ best_group = std::min(best_group, keys[i].group); ++ if (best_group == 0) ++ break; ++ } ++ g_free(keys); ++ } ++ ++ //Unavailable, go with original group then I suppose ++ if (best_group == SAL_MAX_INT32) ++ best_group = group; ++ ++ guint updated_keyval = GetKeyValFor(keymap, hardware_keycode, best_group); ++ aEvent.mnCode = GetKeyCode(updated_keyval); ++ } ++ ++ aEvent.mnCode |= GetKeyModCode( state ); ++ ++ if( bDown ) ++ { ++ bool bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); ++ // #i46889# copy AlternatKeyCode handling from generic plugin ++ if( ! bHandled ) ++ { ++ KeyAlternate aAlternate = GetAlternateKeyCode( aEvent.mnCode ); ++ if( aAlternate.nKeyCode ) ++ { ++ aEvent.mnCode = aAlternate.nKeyCode; ++ if( aAlternate.nCharCode ) ++ aEvent.mnCharCode = aAlternate.nCharCode; ++ bHandled = CallCallback( SALEVENT_KEYINPUT, &aEvent ); ++ } ++ } ++ if( bSendRelease && ! aDel.isDeleted() ) ++ { ++ CallCallback( SALEVENT_KEYUP, &aEvent ); ++ } ++ } ++ else ++ CallCallback( SALEVENT_KEYUP, &aEvent ); ++} ++ ++GtkSalFrame::GraphicsHolder::~GraphicsHolder() ++{ ++ delete pGraphics; ++} ++ ++GtkSalFrame::GtkSalFrame( SalFrame* pParent, sal_uLong nStyle ) ++ : m_nXScreen( getDisplay()->GetDefaultXScreen() ) ++{ ++ getDisplay()->registerFrame( this ); ++ m_bDefaultPos = true; ++ m_bDefaultSize = ( (nStyle & SAL_FRAME_STYLE_SIZEABLE) && ! pParent ); ++ m_bWindowIsGtkPlug = false; ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++ m_pLastSyncedDbusMenu = NULL; ++#endif ++ Init( pParent, nStyle ); ++} ++ ++GtkSalFrame::GtkSalFrame( SystemParentData* pSysData ) ++ : m_nXScreen( getDisplay()->GetDefaultXScreen() ) ++{ ++ getDisplay()->registerFrame( this ); ++ // permanently ignore errors from our unruly children ... ++ GetGenericData()->ErrorTrapPush(); ++ m_bDefaultPos = true; ++ m_bDefaultSize = true; ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++ m_pLastSyncedDbusMenu = NULL; ++#endif ++ Init( pSysData ); ++} ++ ++#ifdef ENABLE_GMENU_INTEGRATION ++ ++static void ++gdk_x11_window_set_utf8_property (GdkWindow *window, ++ const gchar *name, ++ const gchar *value) ++{ ++} ++ ++// AppMenu watch functions. ++ ++static void ObjectDestroyedNotify( gpointer data ) ++{ ++ if ( data ) { ++ g_object_unref( data ); ++ } ++} ++ ++#if defined(ENABLE_DBUS) && defined(ENABLE_GIO) ++void GtkSalFrame::EnsureDbusMenuSynced() ++{ ++ GtkSalMenu* pSalMenu = static_cast(GetMenu()); ++ if(m_pLastSyncedDbusMenu != pSalMenu) { ++ m_pLastSyncedDbusMenu = pSalMenu; ++ static_cast(pSalMenu)->Activate(); ++ } ++} ++#endif ++ ++static void hud_activated( gboolean hud_active, gpointer user_data ) ++{ ++ if ( hud_active ) ++ { ++ SolarMutexGuard aGuard; ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); ++ GtkSalMenu* pSalMenu = reinterpret_cast< GtkSalMenu* >( pSalFrame->GetMenu() ); ++ ++ if ( pSalMenu ) ++ pSalMenu->UpdateFull(); ++ } ++} ++ ++static void activate_uno(GSimpleAction *action, GVariant*, gpointer) ++{ ++ uno::Reference< css::uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext(); ++ ++ uno::Reference< css::frame::XDesktop2 > xDesktop = css::frame::Desktop::create( xContext ); ++ ++ uno::Reference < css::frame::XFrame > xFrame(xDesktop->getActiveFrame()); ++ if (!xFrame.is()) ++ xFrame = uno::Reference < css::frame::XFrame >(xDesktop, uno::UNO_QUERY); ++ ++ if (!xFrame.is()) ++ return; ++ ++ uno::Reference< css::frame::XDispatchProvider > xDispatchProvider(xFrame, uno::UNO_QUERY); ++ if (!xDispatchProvider.is()) ++ return; ++ ++ gchar *strval = NULL; ++ g_object_get(action, "name", &strval, NULL); ++ if (!strval) ++ return; ++ ++ if (strcmp(strval, "New") == 0) ++ { ++ uno::Reference xModuleManager(frame::ModuleManager::create(xContext)); ++ OUString aModuleId(xModuleManager->identify(xFrame)); ++ if (aModuleId.isEmpty()) ++ return; ++ ++ comphelper::SequenceAsHashMap lModuleDescription(xModuleManager->getByName(aModuleId)); ++ OUString sFactoryService; ++ lModuleDescription[OUString("ooSetupFactoryEmptyDocumentURL")] >>= sFactoryService; ++ if (sFactoryService.isEmpty()) ++ return; ++ ++ uno::Sequence < css::beans::PropertyValue > args(0); ++ xDesktop->loadComponentFromURL(sFactoryService, OUString("_blank"), 0, args); ++ return; ++ } ++ ++ OUString sCommand(".uno:"); ++ sCommand += OUString(strval, strlen(strval), RTL_TEXTENCODING_UTF8); ++ g_free(strval); ++ ++ css::util::URL aCommand; ++ aCommand.Complete = sCommand; ++ uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(xContext); ++ xParser->parseStrict(aCommand); ++ ++ uno::Reference< css::frame::XDispatch > xDisp = xDispatchProvider->queryDispatch(aCommand, OUString(), 0); ++ ++ if (!xDisp.is()) ++ return; ++ ++ xDisp->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >()); ++} ++ ++static const GActionEntry app_entries[] = { ++ { "OptionsTreeDialog", activate_uno, NULL, NULL, NULL, {0} }, ++ { "About", activate_uno, NULL, NULL, NULL, {0} }, ++ { "HelpIndex", activate_uno, NULL, NULL, NULL, {0} }, ++ { "Quit", activate_uno, NULL, NULL, NULL, {0} }, ++ { "New", activate_uno, NULL, NULL, NULL, {0} } ++}; ++ ++gboolean ensure_dbus_setup( gpointer data ) ++{ ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( data ); ++ GdkWindow* gdkWindow = widget_get_window( pSalFrame->getWindow() ); ++ ++ if ( gdkWindow != NULL && g_object_get_data( G_OBJECT( gdkWindow ), "g-lo-menubar" ) == NULL ) ++ { ++ // Get a DBus session connection. ++ if(!pSessionBus) ++ pSessionBus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); ++ if( !pSessionBus ) ++ return FALSE; ++ ++ // Create menu model and action group attached to this frame. ++ GMenuModel* pMenuModel = G_MENU_MODEL( g_lo_menu_new() ); ++ GActionGroup* pActionGroup = reinterpret_cast(g_lo_action_group_new( static_cast< gpointer >( pSalFrame ) )); ++ ++ // Generate menu paths. ++ ::Window windowId = GDK_WINDOW_XID( gdkWindow ); ++ gchar* aDBusWindowPath = g_strdup_printf( "/org/libreoffice/window/%lu", windowId ); ++ gchar* aDBusMenubarPath = g_strdup_printf( "/org/libreoffice/window/%lu/menus/menubar", windowId ); ++ ++ // Set window properties. ++ g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-menubar", pMenuModel, ObjectDestroyedNotify ); ++ g_object_set_data_full( G_OBJECT( gdkWindow ), "g-lo-action-group", pActionGroup, ObjectDestroyedNotify ); ++ ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_ID", "org.libreoffice" ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_UNIQUE_BUS_NAME", g_dbus_connection_get_unique_name( pSessionBus ) ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APPLICATION_OBJECT_PATH", "/org/libreoffice" ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_WINDOW_OBJECT_PATH", aDBusWindowPath ); ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_MENUBAR_OBJECT_PATH", aDBusMenubarPath ); ++ ++ // Publish the menu model and the action group. ++ SAL_INFO("vcl.unity", "exporting menu model at " << pMenuModel << " for window " << windowId); ++ pSalFrame->m_nMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, aDBusMenubarPath, pMenuModel, NULL); ++ SAL_INFO("vcl.unity", "exporting action group at " << pActionGroup << " for window " << windowId); ++ pSalFrame->m_nActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, aDBusWindowPath, pActionGroup, NULL); ++ pSalFrame->m_nHudAwarenessId = hud_awareness_register( pSessionBus, aDBusMenubarPath, hud_activated, pSalFrame, NULL, NULL ); ++ ++ // fdo#70885 we don't want app menu under Unity ++ bool bDesktopIsUnity = (SalGetDesktopEnvironment() == "UNITY"); ++ ++ if (!bDesktopIsUnity) ++ gdk_x11_window_set_utf8_property( gdkWindow, "_GTK_APP_MENU_OBJECT_PATH", "/org/libreoffice/menus/appmenu" ); ++ ++ //app menu, to-do translations, block normal menus when active, honor use appmenu settings ++ ResMgr* pMgr = ImplGetResMgr(); ++ if( pMgr && !bDesktopIsUnity ) ++ { ++ GMenu *menu = g_menu_new (); ++ GMenuItem* item; ++ ++ GMenu *firstsubmenu = g_menu_new (); ++ ++ OString sNew(OUStringToOString(ResId(SV_BUTTONTEXT_NEW, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sNew.getStr(), "app.New"); ++ g_menu_append_item( firstsubmenu, item ); ++ g_object_unref(item); ++ ++ g_menu_append_section( menu, NULL, G_MENU_MODEL(firstsubmenu)); ++ g_object_unref(firstsubmenu); ++ ++ GMenu *secondsubmenu = g_menu_new (); ++ ++ OString sPreferences(OUStringToOString(ResId(SV_STDTEXT_PREFERENCES, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sPreferences.getStr(), "app.OptionsTreeDialog"); ++ g_menu_append_item( secondsubmenu, item ); ++ g_object_unref(item); ++ ++ g_menu_append_section( menu, NULL, G_MENU_MODEL(secondsubmenu)); ++ g_object_unref(secondsubmenu); ++ ++ GMenu *thirdsubmenu = g_menu_new (); ++ ++ OString sHelp(OUStringToOString(ResId(SV_BUTTONTEXT_HELP, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sHelp.getStr(), "app.HelpIndex"); ++ g_menu_append_item( thirdsubmenu, item ); ++ g_object_unref(item); ++ ++ OString sAbout(OUStringToOString(ResId(SV_STDTEXT_ABOUT, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sAbout.getStr(), "app.About"); ++ g_menu_append_item( thirdsubmenu, item ); ++ g_object_unref(item); ++ ++ OString sQuit(OUStringToOString(ResId(SV_MENU_MAC_QUITAPP, *pMgr).toString(), ++ RTL_TEXTENCODING_UTF8).replaceFirst("~", "_")); ++ ++ item = g_menu_item_new(sQuit.getStr(), "app.Quit"); ++ g_menu_append_item( thirdsubmenu, item ); ++ g_object_unref(item); ++ g_menu_append_section( menu, NULL, G_MENU_MODEL(thirdsubmenu)); ++ g_object_unref(thirdsubmenu); ++ ++ GSimpleActionGroup *group = g_simple_action_group_new (); ++#if GLIB_CHECK_VERSION(2,38,0) // g_simple_action_group_add_entries is deprecated since 2.38 ++ g_action_map_add_action_entries (G_ACTION_MAP (group), app_entries, G_N_ELEMENTS (app_entries), NULL); ++#else ++ g_simple_action_group_add_entries (group, app_entries, G_N_ELEMENTS (app_entries), NULL); ++#endif ++ GActionGroup* pAppActionGroup = G_ACTION_GROUP(group); ++ ++ pSalFrame->m_nAppActionGroupExportId = g_dbus_connection_export_action_group( pSessionBus, "/org/libreoffice", pAppActionGroup, NULL); ++ g_object_unref(pAppActionGroup); ++ pSalFrame->m_nAppMenuExportId = g_dbus_connection_export_menu_model (pSessionBus, "/org/libreoffice/menus/appmenu", G_MENU_MODEL (menu), NULL); ++ g_object_unref(menu); ++ } ++ ++ g_free( aDBusMenubarPath ); ++ g_free( aDBusWindowPath ); ++ } ++ ++ return FALSE; ++} ++ ++void on_registrar_available( GDBusConnection * /*connection*/, ++ const gchar * /*name*/, ++ const gchar * /*name_owner*/, ++ gpointer user_data ) ++{ ++ SolarMutexGuard aGuard; ++ ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); ++ ++ SalMenu* pSalMenu = pSalFrame->GetMenu(); ++ ++ if ( pSalMenu != NULL ) ++ { ++ GtkSalMenu* pGtkSalMenu = static_cast(pSalMenu); ++ pGtkSalMenu->Display( true ); ++ pGtkSalMenu->UpdateFull(); ++ } ++} ++ ++// This is called when the registrar becomes unavailable. It shows the menubar. ++void on_registrar_unavailable( GDBusConnection * /*connection*/, ++ const gchar * /*name*/, ++ gpointer user_data ) ++{ ++ SolarMutexGuard aGuard; ++ ++ SAL_INFO("vcl.unity", "on_registrar_unavailable"); ++ ++ //pSessionBus = NULL; ++ GtkSalFrame* pSalFrame = static_cast< GtkSalFrame* >( user_data ); ++ ++ SalMenu* pSalMenu = pSalFrame->GetMenu(); ++ ++ if ( pSalMenu ) { ++ GtkSalMenu* pGtkSalMenu = static_cast< GtkSalMenu* >( pSalMenu ); ++ pGtkSalMenu->Display( false ); ++ } ++} ++#endif ++ ++void GtkSalFrame::EnsureAppMenuWatch() ++{ ++#ifdef ENABLE_GMENU_INTEGRATION ++ if ( !m_nWatcherId ) ++ { ++ // Get a DBus session connection. ++ if ( pSessionBus == NULL ) ++ { ++ pSessionBus = g_bus_get_sync( G_BUS_TYPE_SESSION, NULL, NULL ); ++ ++ if ( pSessionBus == NULL ) ++ return; ++ } ++ ++ // Publish the menu only if AppMenu registrar is available. ++ m_nWatcherId = g_bus_watch_name_on_connection( pSessionBus, ++ "com.canonical.AppMenu.Registrar", ++ G_BUS_NAME_WATCHER_FLAGS_NONE, ++ on_registrar_available, ++ on_registrar_unavailable, ++ static_cast(this), ++ NULL ); ++ } ++ ++ //ensure_dbus_setup( this ); ++#else ++ (void) this; // loplugin:staticmethods ++#endif ++} ++ ++void GtkSalFrame::InvalidateGraphics() ++{ ++ for (unsigned int i = 0; i < SAL_N_ELEMENTS(m_aGraphics); ++i) ++ { ++ if( !m_aGraphics[i].pGraphics ) ++ continue; ++ m_aGraphics[i].bInUse = false; ++ } ++} ++ ++GtkSalFrame::~GtkSalFrame() ++{ ++ InvalidateGraphics(); ++ ++ if( m_pParent ) ++ m_pParent->m_aChildren.remove( this ); ++ ++ getDisplay()->deregisterFrame( this ); ++ ++ if( m_pRegion ) ++ { ++ cairo_region_destroy( m_pRegion ); ++ } ++ ++ delete m_pIMHandler; ++ ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ for (auto handler_id : m_aMouseSignalIds) ++ g_signal_handler_disconnect(G_OBJECT(pEventWidget), handler_id); ++ if( m_pFixedContainer ) ++ gtk_widget_destroy( GTK_WIDGET( m_pFixedContainer ) ); ++ if( m_pEventBox ) ++ gtk_widget_destroy( GTK_WIDGET(m_pEventBox) ); ++ { ++ SolarMutexGuard aGuard; ++#if defined ENABLE_GMENU_INTEGRATION ++ if(m_nWatcherId) ++ g_bus_unwatch_name(m_nWatcherId); ++#endif ++ if( m_pWindow ) ++ { ++ g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", NULL ); ++ ++#if defined ENABLE_GMENU_INTEGRATION ++ if ( pSessionBus ) ++ { ++ if ( m_nHudAwarenessId ) ++ hud_awareness_unregister( pSessionBus, m_nHudAwarenessId ); ++ if ( m_nMenuExportId ) ++ g_dbus_connection_unexport_menu_model( pSessionBus, m_nMenuExportId ); ++ if ( m_nAppMenuExportId ) ++ g_dbus_connection_unexport_menu_model( pSessionBus, m_nAppMenuExportId ); ++ if ( m_nActionGroupExportId ) ++ g_dbus_connection_unexport_action_group( pSessionBus, m_nActionGroupExportId ); ++ if ( m_nAppActionGroupExportId ) ++ g_dbus_connection_unexport_action_group( pSessionBus, m_nAppActionGroupExportId ); ++ } ++#endif ++ gtk_widget_destroy( m_pWindow ); ++ } ++ } ++ if( m_pForeignParent ) ++ g_object_unref( G_OBJECT( m_pForeignParent ) ); ++ if( m_pForeignTopLevel ) ++ g_object_unref( G_OBJECT( m_pForeignTopLevel) ); ++} ++ ++void GtkSalFrame::moveWindow( long nX, long nY ) ++{ ++ if( isChild( false, true ) ) ++ { ++ if( m_pParent ) ++ gtk_fixed_move( m_pParent->getFixedContainer(), ++ m_pWindow, ++ nX - m_pParent->maGeometry.nX, nY - m_pParent->maGeometry.nY ); ++ } ++ else ++ gtk_window_move( GTK_WINDOW(m_pWindow), nX, nY ); ++} ++ ++void GtkSalFrame::widget_set_size_request(long nWidth, long nHeight) ++{ ++ gtk_widget_set_size_request(GTK_WIDGET(m_pFixedContainer), nWidth, nHeight ); ++} ++ ++void GtkSalFrame::window_resize(long nWidth, long nHeight) ++{ ++ gtk_window_resize(GTK_WINDOW(m_pWindow), nWidth, nHeight); ++} ++ ++void GtkSalFrame::resizeWindow( long nWidth, long nHeight ) ++{ ++ if( isChild( false, true ) ) ++ { ++ widget_set_size_request(nWidth, nHeight); ++ } ++ else if( ! isChild( true, false ) ) ++ window_resize(nWidth, nHeight); ++} ++ ++static void ++ooo_fixed_class_init(GtkFixedClass *klass) ++{ ++ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); ++ widget_class->get_accessible = ooo_fixed_get_accessible; ++} ++ ++/* ++ * Always use a sub-class of GtkFixed we can tag for a11y. This allows us to ++ * utilize GAIL for the toplevel window and toolkit implementation incl. ++ * key event listener support .. ++ */ ++ ++GType ++ooo_fixed_get_type() ++{ ++ static GType type = 0; ++ ++ if (!type) { ++ static const GTypeInfo tinfo = ++ { ++ sizeof (GtkFixedClass), ++ nullptr, /* base init */ ++ nullptr, /* base finalize */ ++ reinterpret_cast(ooo_fixed_class_init), /* class init */ ++ nullptr, /* class finalize */ ++ NULL, /* class data */ ++ sizeof (GtkFixed), /* instance size */ ++ 0, /* nb preallocs */ ++ (GInstanceInitFunc) NULL, /* instance init */ ++ NULL /* value table */ ++ }; ++ ++ type = g_type_register_static( GTK_TYPE_FIXED, "OOoFixed", ++ &tinfo, (GTypeFlags) 0); ++ } ++ ++ return type; ++} ++ ++void GtkSalFrame::updateScreenNumber() ++{ ++ int nScreen = 0; ++ GdkScreen *pScreen = gtk_widget_get_screen( m_pWindow ); ++ if( pScreen ) ++ nScreen = getDisplay()->getSystem()->getScreenMonitorIdx( pScreen, maGeometry.nX, maGeometry.nY ); ++ maGeometry.nDisplayScreenNumber = nScreen; ++} ++ ++GtkWidget *GtkSalFrame::getMouseEventWidget() const ++{ ++ return GTK_WIDGET(m_pEventBox); ++} ++ ++void GtkSalFrame::InitCommon() ++{ ++ m_pEventBox = GTK_EVENT_BOX(gtk_event_box_new()); ++ gtk_widget_add_events( GTK_WIDGET(m_pEventBox), ++ GDK_ALL_EVENTS_MASK ); ++ gtk_container_add( GTK_CONTAINER(m_pWindow), GTK_WIDGET(m_pEventBox) ); ++ ++ // add the fixed container child, ++ // fixed is needed since we have to position plugin windows ++ m_pFixedContainer = GTK_FIXED(g_object_new( ooo_fixed_get_type(), NULL )); ++ gtk_container_add( GTK_CONTAINER(m_pEventBox), GTK_WIDGET(m_pFixedContainer) ); ++ ++ GtkWidget *pEventWidget = getMouseEventWidget(); ++ ++ gtk_widget_set_app_paintable(GTK_WIDGET(m_pFixedContainer), true); ++ /*non-X11 displays won't show anything at all without double-buffering ++ enabled*/ ++ if (GDK_IS_X11_DISPLAY(getGdkDisplay())) ++ gtk_widget_set_double_buffered(GTK_WIDGET(m_pFixedContainer), false); ++ gtk_widget_set_redraw_on_allocate(GTK_WIDGET(m_pFixedContainer), false); ++ ++ ++ // connect signals ++ g_signal_connect( G_OBJECT(m_pWindow), "style-set", G_CALLBACK(signalStyleSet), this ); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-press-event", G_CALLBACK(signalButton), this )); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "motion-notify-event", G_CALLBACK(signalMotion), this )); ++ m_aMouseSignalIds.push_back(g_signal_connect( G_OBJECT(pEventWidget), "button-release-event", G_CALLBACK(signalButton), this )); ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "draw", G_CALLBACK(signalDraw), this ); ++ g_signal_connect( G_OBJECT(m_pFixedContainer), "size-allocate", G_CALLBACK(sizeAllocated), this ); ++ GtkGesture *pSwipe = gtk_gesture_swipe_new(pEventWidget); ++ g_signal_connect(pSwipe, "swipe", G_CALLBACK(gestureSwipe), this); ++ gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pSwipe), GTK_PHASE_TARGET); ++ g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pSwipe); ++ ++ GtkGesture *pLongPress = gtk_gesture_long_press_new(pEventWidget); ++ g_signal_connect(pLongPress, "pressed", G_CALLBACK(gestureLongPress), this); ++ gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER (pLongPress), GTK_PHASE_TARGET); ++ g_object_weak_ref(G_OBJECT(pEventWidget), reinterpret_cast(g_object_unref), pLongPress); ++ ++ g_signal_connect( G_OBJECT(m_pWindow), "focus-in-event", G_CALLBACK(signalFocus), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "focus-out-event", G_CALLBACK(signalFocus), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "map-event", G_CALLBACK(signalMap), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "unmap-event", G_CALLBACK(signalUnmap), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "configure-event", G_CALLBACK(signalConfigure), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "key-press-event", G_CALLBACK(signalKey), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "key-release-event", G_CALLBACK(signalKey), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "delete-event", G_CALLBACK(signalDelete), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "window-state-event", G_CALLBACK(signalWindowState), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "scroll-event", G_CALLBACK(signalScroll), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "leave-notify-event", G_CALLBACK(signalCrossing), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "enter-notify-event", G_CALLBACK(signalCrossing), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "visibility-notify-event", G_CALLBACK(signalVisibility), this ); ++ g_signal_connect( G_OBJECT(m_pWindow), "destroy", G_CALLBACK(signalDestroy), this ); ++ ++ // init members ++ m_pCurrentCursor = NULL; ++ m_nKeyModifiers = 0; ++ m_bFullscreen = false; ++ m_bSpanMonitorsWhenFullscreen = false; ++ m_nState = GDK_WINDOW_STATE_WITHDRAWN; ++ m_nVisibility = GDK_VISIBILITY_FULLY_OBSCURED; ++ m_nLastScrollEventTime = GDK_CURRENT_TIME; ++ m_bSendModChangeOnRelease = false; ++ m_pIMHandler = NULL; ++ m_hBackgroundPixmap = None; ++ m_nSavedScreenSaverTimeout = 0; ++ m_nGSMCookie = 0; ++ m_nExtStyle = 0; ++ m_pRegion = NULL; ++ m_ePointerStyle = static_cast(0xffff); ++ m_bSetFocusOnMap = false; ++ m_pSalMenu = NULL; ++ m_nWatcherId = 0; ++ m_nMenuExportId = 0; ++ m_nAppMenuExportId = 0; ++ m_nActionGroupExportId = 0; ++ m_nAppActionGroupExportId = 0; ++ m_nHudAwarenessId = 0; ++ ++ gtk_widget_add_events( m_pWindow, ++ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | ++ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | ++ GDK_VISIBILITY_NOTIFY_MASK | GDK_SCROLL_MASK ++ ); ++ ++ // show the widgets ++ gtk_widget_show_all( GTK_WIDGET(m_pEventBox) ); ++ ++ // realize the window, we need an XWindow id ++ gtk_widget_realize( m_pWindow ); ++ ++ //system data ++ m_aSystemData.nSize = sizeof( SystemEnvData ); ++ static int nWindow = 0; ++ m_aSystemData.aWindow = nWindow; ++ m_aSystemData.aShellWindow = nWindow; ++ ++nWindow; ++ m_aSystemData.pSalFrame = this; ++ m_aSystemData.pWidget = m_pWindow; ++ m_aSystemData.nScreen = m_nXScreen.getXScreen(); ++ m_aSystemData.pAppContext = NULL; ++ m_aSystemData.pShellWidget = m_aSystemData.pWidget; ++ ++ // fake an initial geometry, gets updated via configure event or SetPosSize ++ if( m_bDefaultPos || m_bDefaultSize ) ++ { ++ Size aDefSize = calcDefaultSize(); ++ maGeometry.nX = -1; ++ maGeometry.nY = -1; ++ maGeometry.nWidth = aDefSize.Width(); ++ maGeometry.nHeight = aDefSize.Height(); ++ if( m_pParent ) ++ { ++ // approximation ++ maGeometry.nTopDecoration = m_pParent->maGeometry.nTopDecoration; ++ maGeometry.nBottomDecoration = m_pParent->maGeometry.nBottomDecoration; ++ maGeometry.nLeftDecoration = m_pParent->maGeometry.nLeftDecoration; ++ maGeometry.nRightDecoration = m_pParent->maGeometry.nRightDecoration; ++ } ++ else ++ { ++ maGeometry.nTopDecoration = 0; ++ maGeometry.nBottomDecoration = 0; ++ maGeometry.nLeftDecoration = 0; ++ maGeometry.nRightDecoration = 0; ++ } ++ } ++ updateScreenNumber(); ++ ++ SetIcon(1); ++ ++} ++ ++GtkSalFrame *GtkSalFrame::getFromWindow( GtkWindow *pWindow ) ++{ ++ return static_cast(g_object_get_data( G_OBJECT( pWindow ), "SalFrame" )); ++} ++ ++void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) ++{ ++ if( nStyle & SAL_FRAME_STYLE_DEFAULT ) // ensure default style ++ { ++ nStyle |= SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE; ++ nStyle &= ~SAL_FRAME_STYLE_FLOAT; ++ } ++ ++ m_pParent = static_cast(pParent); ++ m_pForeignParent = NULL; ++ m_aForeignParentWindow = None; ++ m_pForeignTopLevel = NULL; ++ m_aForeignTopLevelWindow = None; ++ m_nStyle = nStyle; ++ ++ GtkWindowType eWinType = ( (nStyle & SAL_FRAME_STYLE_FLOAT) && ++ ! (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION| ++ SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ++ ) ++ ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL; ++ ++ if( nStyle & SAL_FRAME_STYLE_SYSTEMCHILD ) ++ { ++ m_pWindow = gtk_event_box_new(); ++ if( m_pParent ) ++ { ++ // insert into container ++ gtk_fixed_put( m_pParent->getFixedContainer(), ++ m_pWindow, 0, 0 ); ++ ++ } ++ } ++ else ++ { ++ m_pWindow = gtk_widget_new( GTK_TYPE_WINDOW, "type", eWinType, ++ "visible", FALSE, NULL ); ++ } ++ g_object_set_data( G_OBJECT( m_pWindow ), "SalFrame", this ); ++ g_object_set_data( G_OBJECT( m_pWindow ), "libo-version", (gpointer)LIBO_VERSION_DOTTED); ++ ++ // force wm class hint ++ m_nExtStyle = ~0; ++ if (m_pParent) ++ m_sWMClass = m_pParent->m_sWMClass; ++ SetExtendedFrameStyle( 0 ); ++ ++ if( m_pParent && m_pParent->m_pWindow && ! isChild() ) ++ gtk_window_set_screen( GTK_WINDOW(m_pWindow), gtk_window_get_screen( GTK_WINDOW(m_pParent->m_pWindow) ) ); ++ ++ if (m_pParent) ++ { ++ if (!(m_pParent->m_nStyle & SAL_FRAME_STYLE_PLUG)) ++ gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), GTK_WINDOW(m_pParent->m_pWindow) ); ++ m_pParent->m_aChildren.push_back( this ); ++ } ++ ++ InitCommon(); ++ ++ // set window type ++ bool bDecoHandling = ++ ! isChild() && ++ ( ! (nStyle & SAL_FRAME_STYLE_FLOAT) || ++ (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ); ++ ++ if( bDecoHandling ) ++ { ++ GdkWindowTypeHint eType = GDK_WINDOW_TYPE_HINT_NORMAL; ++ if( (nStyle & SAL_FRAME_STYLE_DIALOG) && m_pParent != 0 ) ++ eType = GDK_WINDOW_TYPE_HINT_DIALOG; ++ if( (nStyle & SAL_FRAME_STYLE_INTRO) ) ++ { ++ gtk_window_set_role( GTK_WINDOW(m_pWindow), "splashscreen" ); ++ eType = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN; ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_TOOLWINDOW ) ) ++ { ++ eType = GDK_WINDOW_TYPE_HINT_UTILITY; ++ gtk_window_set_skip_taskbar_hint( GTK_WINDOW(m_pWindow), true ); ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) ++ { ++ eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; ++ gtk_window_set_accept_focus(GTK_WINDOW(m_pWindow), false); ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ++ { ++ eType = GDK_WINDOW_TYPE_HINT_UTILITY; ++ } ++ gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); ++ gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); ++ } ++ else if( (nStyle & SAL_FRAME_STYLE_FLOAT) ) ++ { ++ gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_POPUP_MENU ); ++ } ++ ++ if( bDecoHandling ) ++ { ++ gtk_window_set_resizable( GTK_WINDOW(m_pWindow), (nStyle & SAL_FRAME_STYLE_SIZEABLE) != 0 ); ++ if( ( (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) ) ) ++ gtk_window_set_accept_focus(GTK_WINDOW(m_pWindow), false); ++ } ++} ++ ++GdkNativeWindow GtkSalFrame::findTopLevelSystemWindow( GdkNativeWindow aWindow ) ++{ ++ (void)aWindow; ++ //FIXME: no findToplevelSystemWindow ++ return 0; ++} ++ ++void GtkSalFrame::Init( SystemParentData* pSysData ) ++{ ++ m_pParent = NULL; ++ m_aForeignParentWindow = (GdkNativeWindow)pSysData->aWindow; ++ m_pForeignParent = NULL; ++ m_aForeignTopLevelWindow = findTopLevelSystemWindow( (GdkNativeWindow)pSysData->aWindow ); ++ m_pForeignTopLevel = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignTopLevelWindow ); ++ gdk_window_set_events( m_pForeignTopLevel, GDK_STRUCTURE_MASK ); ++ ++ if( pSysData->nSize > sizeof(pSysData->nSize)+sizeof(pSysData->aWindow) && pSysData->bXEmbedSupport ) ++ { ++ m_pWindow = gtk_plug_new_for_display( getGdkDisplay(), pSysData->aWindow ); ++ m_bWindowIsGtkPlug = true; ++ widget_set_can_default( m_pWindow, true ); ++ widget_set_can_focus( m_pWindow, true ); ++ gtk_widget_set_sensitive( m_pWindow, true ); ++ } ++ else ++ { ++ m_pWindow = gtk_window_new( GTK_WINDOW_POPUP ); ++ m_bWindowIsGtkPlug = false; ++ } ++ m_nStyle = SAL_FRAME_STYLE_PLUG; ++ InitCommon(); ++ ++ m_pForeignParent = gdk_window_foreign_new_for_display( getGdkDisplay(), m_aForeignParentWindow ); ++ gdk_window_set_events( m_pForeignParent, GDK_STRUCTURE_MASK ); ++ ++ //FIXME: Handling embedded windows, is going to be fun ... ++} ++ ++void GtkSalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode ) ++{ ++ (void) this; // loplugin:staticmethods ++ (void)i_nTimeCode; ++ //FIXME: no askForXEmbedFocus for gtk3 yet ++} ++ ++void GtkSalFrame::SetExtendedFrameStyle( SalExtStyle nStyle ) ++{ ++ if( nStyle != m_nExtStyle && ! isChild() ) ++ { ++ m_nExtStyle = nStyle; ++ updateWMClass(); ++ } ++} ++ ++SalGraphics* GtkSalFrame::AcquireGraphics() ++{ ++ if( m_pWindow ) ++ { ++ for( int i = 0; i < nMaxGraphics; i++ ) ++ { ++ if( ! m_aGraphics[i].bInUse ) ++ { ++ m_aGraphics[i].bInUse = true; ++ if( ! m_aGraphics[i].pGraphics ) ++ { ++ m_aGraphics[i].pGraphics = new GtkSalGraphics( this, m_pWindow ); ++ if( !m_aFrame.get() ) ++ { ++ AllocateFrame(); ++ TriggerPaintEvent(); ++ } ++ m_aGraphics[i].pGraphics->setDevice( m_aFrame ); ++ } ++ return m_aGraphics[i].pGraphics; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++void GtkSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) ++{ ++ for( int i = 0; i < nMaxGraphics; i++ ) ++ { ++ if( m_aGraphics[i].pGraphics == pGraphics ) ++ { ++ m_aGraphics[i].bInUse = false; ++ break; ++ } ++ } ++} ++ ++bool GtkSalFrame::PostEvent( void* pData ) ++{ ++ getDisplay()->SendInternalEvent( this, pData ); ++ return true; ++} ++ ++void GtkSalFrame::SetTitle( const OUString& rTitle ) ++{ ++ m_aTitle = rTitle; ++ if( m_pWindow && ! isChild() ) ++ gtk_window_set_title( GTK_WINDOW(m_pWindow), OUStringToOString( rTitle, RTL_TEXTENCODING_UTF8 ).getStr() ); ++} ++ ++static inline sal_uInt8 * ++getRow( BitmapBuffer *pBuffer, sal_uLong nRow ) ++{ ++ if( BMP_SCANLINE_ADJUSTMENT( pBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN ) ++ return pBuffer->mpBits + nRow * pBuffer->mnScanlineSize; ++ else ++ return pBuffer->mpBits + ( pBuffer->mnHeight - nRow - 1 ) * pBuffer->mnScanlineSize; ++} ++ ++static GdkPixbuf * ++bitmapToPixbuf( SalBitmap *pSalBitmap, SalBitmap *pSalAlpha ) ++{ ++ g_return_val_if_fail( pSalBitmap != NULL, NULL ); ++ g_return_val_if_fail( pSalAlpha != NULL, NULL ); ++ ++ BitmapBuffer *pBitmap = pSalBitmap->AcquireBuffer( BITMAP_READ_ACCESS ); ++ g_return_val_if_fail( pBitmap != NULL, NULL ); ++ g_return_val_if_fail( pBitmap->mnBitCount == 24 || pBitmap->mnBitCount == 32, NULL ); ++ ++ BitmapBuffer *pAlpha = pSalAlpha->AcquireBuffer( BITMAP_READ_ACCESS ); ++ g_return_val_if_fail( pAlpha != NULL, NULL ); ++ g_return_val_if_fail( pAlpha->mnBitCount == 8, NULL ); ++ ++ Size aSize = pSalBitmap->GetSize(); ++ g_return_val_if_fail( pSalAlpha->GetSize() == aSize, NULL ); ++ ++ int nX, nY; ++ guchar *pPixbufData = static_cast(g_malloc (4 * aSize.Width() * aSize.Height() )); ++ guchar *pDestData = pPixbufData; ++ ++ for( nY = 0; nY < pBitmap->mnHeight; nY++ ) ++ { ++ sal_uInt8 *pData = getRow( pBitmap, nY ); ++ sal_uInt8 *pAlphaData = getRow( pAlpha, nY ); ++ ++ for( nX = 0; nX < pBitmap->mnWidth; nX++ ) ++ { ++ BitmapColor aColor; ++ if (pBitmap->mnFormat == BMP_FORMAT_24BIT_TC_BGR) ++ { ++ aColor = BitmapColor(pData[2], pData[1], pData[0]); ++ pData += 3; ++ } ++ else if (pBitmap->mnFormat == BMP_FORMAT_24BIT_TC_RGB) ++ { ++ aColor = BitmapColor(pData[0], pData[1], pData[2]); ++ pData += 3; ++ } ++ else ++ { ++ pBitmap->maColorMask.GetColorFor32Bit(aColor, pData); ++ pData += 4; ++ } ++ *pDestData++ = aColor.GetRed(); ++ *pDestData++ = aColor.GetGreen(); ++ *pDestData++ = aColor.GetBlue(); ++ *pDestData++ = 255 - *pAlphaData++; ++ } ++ } ++ ++ pSalBitmap->ReleaseBuffer( pBitmap, BITMAP_READ_ACCESS ); ++ pSalAlpha->ReleaseBuffer( pAlpha, BITMAP_READ_ACCESS ); ++ ++ return gdk_pixbuf_new_from_data( pPixbufData, ++ GDK_COLORSPACE_RGB, true, 8, ++ aSize.Width(), aSize.Height(), ++ aSize.Width() * 4, ++ reinterpret_cast(g_free), ++ NULL ); ++} ++ ++void GtkSalFrame::SetIcon( sal_uInt16 nIcon ) ++{ ++ if( (m_nStyle & (SAL_FRAME_STYLE_PLUG|SAL_FRAME_STYLE_SYSTEMCHILD|SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_INTRO|SAL_FRAME_STYLE_OWNERDRAWDECORATION)) ++ || ! m_pWindow ) ++ return; ++ ++ if( !ImplGetResMgr() ) ++ return; ++ ++ GdkPixbuf *pBuf; ++ GList *pIcons = NULL; ++ ++ sal_uInt16 nOffsets[2] = { SV_ICON_SMALL_START, SV_ICON_LARGE_START }; ++ sal_uInt16 nIndex; ++ ++ for( nIndex = 0; nIndex < sizeof(nOffsets)/ sizeof(sal_uInt16); nIndex++ ) ++ { ++ // #i44723# workaround gcc temporary problem ++ ResId aResId( nOffsets[nIndex] + nIcon, *ImplGetResMgr() ); ++ BitmapEx aIcon( aResId ); ++ ++ // #i81083# convert to 24bit/8bit alpha bitmap ++ Bitmap aBmp = aIcon.GetBitmap(); ++ if( aBmp.GetBitCount() != 24 || ! aIcon.IsAlpha() ) ++ { ++ if( aBmp.GetBitCount() != 24 ) ++ aBmp.Convert( BMP_CONVERSION_24BIT ); ++ AlphaMask aMask; ++ if( ! aIcon.IsAlpha() ) ++ { ++ switch( aIcon.GetTransparentType() ) ++ { ++ case TRANSPARENT_NONE: ++ { ++ sal_uInt8 nTrans = 0; ++ aMask = AlphaMask( aBmp.GetSizePixel(), &nTrans ); ++ } ++ break; ++ case TRANSPARENT_COLOR: ++ aMask = AlphaMask( aBmp.CreateMask( aIcon.GetTransparentColor() ) ); ++ break; ++ case TRANSPARENT_BITMAP: ++ aMask = AlphaMask( aIcon.GetMask() ); ++ break; ++ default: ++ OSL_FAIL( "unhandled transparent type" ); ++ break; ++ } ++ } ++ else ++ aMask = aIcon.GetAlpha(); ++ aIcon = BitmapEx( aBmp, aMask ); ++ } ++ ++ ImpBitmap *pIconImpBitmap = aIcon.ImplGetBitmapImpBitmap(); ++ ImpBitmap *pIconImpMask = aIcon.ImplGetMaskImpBitmap(); ++ ++ if( pIconImpBitmap && pIconImpMask ) ++ { ++ SalBitmap *pIconBitmap = ++ pIconImpBitmap->ImplGetSalBitmap(); ++ SalBitmap *pIconMask = ++ pIconImpMask->ImplGetSalBitmap(); ++ ++ if( ( pBuf = bitmapToPixbuf( pIconBitmap, pIconMask ) ) ) ++ pIcons = g_list_prepend( pIcons, pBuf ); ++ } ++ } ++ ++ gtk_window_set_icon_list( GTK_WINDOW(m_pWindow), pIcons ); ++ ++ g_list_foreach( pIcons, reinterpret_cast(g_object_unref), NULL ); ++ g_list_free( pIcons ); ++} ++ ++void GtkSalFrame::SetMenu( SalMenu* pSalMenu ) ++{ ++// if(m_pSalMenu) ++// { ++// static_cast(m_pSalMenu)->DisconnectFrame(); ++// } ++ m_pSalMenu = pSalMenu; ++} ++ ++SalMenu* GtkSalFrame::GetMenu() ++{ ++ return m_pSalMenu; ++} ++ ++void GtkSalFrame::DrawMenuBar() ++{ ++} ++ ++void GtkSalFrame::Center() ++{ ++ if (m_pParent) ++ gtk_window_set_position(GTK_WINDOW(m_pWindow), GTK_WIN_POS_CENTER_ON_PARENT); ++ else ++ gtk_window_set_position(GTK_WINDOW(m_pWindow), GTK_WIN_POS_CENTER); ++} ++ ++Size GtkSalFrame::calcDefaultSize() ++{ ++ return bestmaxFrameSizeForScreenSize(getDisplay()->GetScreenSize(GetDisplayScreen())); ++} ++ ++void GtkSalFrame::SetDefaultSize() ++{ ++ Size aDefSize = calcDefaultSize(); ++ ++ SetPosSize( 0, 0, aDefSize.Width(), aDefSize.Height(), ++ SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT ); ++ ++ if( (m_nStyle & SAL_FRAME_STYLE_DEFAULT) && m_pWindow ) ++ gtk_window_maximize( GTK_WINDOW(m_pWindow) ); ++} ++ ++static void initClientId() ++{ ++ // No session management support for gtk3+ - this is now legacy. ++} ++ ++void GtkSalFrame::Show( bool bVisible, bool bNoActivate ) ++{ ++ if( m_pWindow ) ++ { ++ if( bVisible ) ++ { ++ initClientId(); ++ getDisplay()->startupNotificationCompleted(); ++ ++ if( m_bDefaultPos ) ++ Center(); ++ if( m_bDefaultSize ) ++ SetDefaultSize(); ++ setMinMaxSize(); ++ ++ if( isFloatGrabWindow() && ++ m_pParent && ++ m_nFloats == 0 && ++ ! getDisplay()->GetCaptureFrame() ) ++ { ++ /* #i63086# ++ * outsmart Metacity's "focus:mouse" mode ++ * which insists on taking the focus from the document ++ * to the new float. Grab focus to parent frame BEFORE ++ * showing the float (cannot grab it to the float ++ * before show). ++ */ ++ m_pParent->grabPointer( true, true ); ++ } ++ ++ if( ! bNoActivate && (m_nStyle & SAL_FRAME_STYLE_TOOLWINDOW) ) ++ m_bSetFocusOnMap = true; ++ ++ gtk_widget_show( m_pWindow ); ++ ++ if( isFloatGrabWindow() ) ++ { ++ m_nFloats++; ++ if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 1 ) ++ { ++ grabPointer(true, true); ++ GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; ++ pKeyboardFrame->grabKeyboard(true); ++ } ++ // #i44068# reset parent's IM context ++ if( m_pParent ) ++ m_pParent->EndExtTextInput(0); ++ } ++ if( m_bWindowIsGtkPlug ) ++ askForXEmbedFocus( 0 ); ++ } ++ else ++ { ++ if( isFloatGrabWindow() ) ++ { ++ m_nFloats--; ++ if( ! getDisplay()->GetCaptureFrame() && m_nFloats == 0) ++ { ++ GtkSalFrame *pKeyboardFrame = m_pParent ? m_pParent : this; ++ pKeyboardFrame->grabKeyboard(false); ++ grabPointer(false); ++ } ++ } ++ gtk_widget_hide( m_pWindow ); ++ if( m_pIMHandler ) ++ m_pIMHandler->focusChanged( false ); ++ // flush here; there may be a very seldom race between ++ // the display connection used for clipboard and our connection ++ Flush(); ++ } ++ } ++} ++ ++void GtkSalFrame::setMinMaxSize() ++{ ++ /* #i34504# metacity (and possibly others) do not treat ++ * _NET_WM_STATE_FULLSCREEN and max_width/height independently; ++ * whether they should is undefined. So don't set the max size hint ++ * for a full screen window. ++ */ ++ if( m_pWindow && ! isChild() ) ++ { ++ GdkGeometry aGeo; ++ int aHints = 0; ++ if( m_nStyle & SAL_FRAME_STYLE_SIZEABLE ) ++ { ++ if( m_aMinSize.Width() && m_aMinSize.Height() && ! m_bFullscreen ) ++ { ++ aGeo.min_width = m_aMinSize.Width(); ++ aGeo.min_height = m_aMinSize.Height(); ++ aHints |= GDK_HINT_MIN_SIZE; ++ } ++ if( m_aMaxSize.Width() && m_aMaxSize.Height() && ! m_bFullscreen ) ++ { ++ aGeo.max_width = m_aMaxSize.Width(); ++ aGeo.max_height = m_aMaxSize.Height(); ++ aHints |= GDK_HINT_MAX_SIZE; ++ } ++ } ++ if( m_bFullscreen && m_aMaxSize.Width() && m_aMaxSize.Height() ) ++ { ++ aGeo.max_width = m_aMaxSize.Width(); ++ aGeo.max_height = m_aMaxSize.Height(); ++ aHints |= GDK_HINT_MAX_SIZE; ++ } ++ if( aHints ) ++ { ++ gtk_window_set_geometry_hints( GTK_WINDOW(m_pWindow), ++ NULL, ++ &aGeo, ++ GdkWindowHints( aHints ) ); ++ } ++ } ++} ++ ++void GtkSalFrame::SetMaxClientSize( long nWidth, long nHeight ) ++{ ++ if( ! isChild() ) ++ { ++ m_aMaxSize = Size( nWidth, nHeight ); ++ setMinMaxSize(); ++ } ++} ++void GtkSalFrame::SetMinClientSize( long nWidth, long nHeight ) ++{ ++ if( ! isChild() ) ++ { ++ m_aMinSize = Size( nWidth, nHeight ); ++ if( m_pWindow ) ++ { ++ widget_set_size_request(nWidth, nHeight ); ++ setMinMaxSize(); ++ } ++ } ++} ++ ++// FIXME: we should really be an SvpSalFrame sub-class, and ++// share their AllocateFrame ! ++void GtkSalFrame::AllocateFrame() ++{ ++ basegfx::B2IVector aFrameSize( maGeometry.nWidth, maGeometry.nHeight ); ++ if( ! m_aFrame.get() || m_aFrame->getSize() != aFrameSize ) ++ { ++ if( aFrameSize.getX() == 0 ) ++ aFrameSize.setX( 1 ); ++ if( aFrameSize.getY() == 0 ) ++ aFrameSize.setY( 1 ); ++ m_aFrame = basebmp::createBitmapDevice(aFrameSize, true, ++ basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX); ++ m_aFrame->setDamageTracker( ++ basebmp::IBitmapDeviceDamageTrackerSharedPtr(new DamageTracker(*this)) ); ++ SAL_INFO("vcl.gtk3", "allocated m_aFrame size of " << maGeometry.nWidth << " x " << maGeometry.nHeight); ++ ++#if OSL_DEBUG_LEVEL > 0 // set background to orange ++ m_aFrame->clear( basebmp::Color( 255, 127, 0 ) ); ++#endif ++ ++ // update device in existing graphics ++ for( unsigned int i = 0; i < SAL_N_ELEMENTS( m_aGraphics ); ++i ) ++ { ++ if( !m_aGraphics[i].pGraphics ) ++ continue; ++ m_aGraphics[i].pGraphics->setDevice( m_aFrame ); ++ } ++ } ++} ++ ++void GtkSalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags ) ++{ ++ if( !m_pWindow || isChild( true, false ) ) ++ return; ++ ++ if( (nFlags & ( SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT )) && ++ (nWidth > 0 && nHeight > 0 ) // sometimes stupid things happen ++ ) ++ { ++ m_bDefaultSize = false; ++ ++ if( isChild( false, true ) ) ++ widget_set_size_request(nWidth, nHeight); ++ else if( ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ) ++ window_resize(nWidth, nHeight); ++ ++ setMinMaxSize(); ++ } ++ else if( m_bDefaultSize ) ++ SetDefaultSize(); ++ ++ m_bDefaultSize = false; ++ ++ if( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) ) ++ { ++ if( m_pParent ) ++ { ++ if( AllSettings::GetLayoutRTL() ) ++ nX = m_pParent->maGeometry.nWidth-maGeometry.nWidth-1-nX; ++ nX += m_pParent->maGeometry.nX; ++ nY += m_pParent->maGeometry.nY; ++ } ++ ++ m_bDefaultPos = false; ++ ++ moveWindow(nX, nY); ++ ++ updateScreenNumber(); ++ } ++ else if( m_bDefaultPos ) ++ Center(); ++ ++ m_bDefaultPos = false; ++} ++ ++void GtkSalFrame::GetClientSize( long& rWidth, long& rHeight ) ++{ ++ if( m_pWindow && !(m_nState & GDK_WINDOW_STATE_ICONIFIED) ) ++ { ++ rWidth = maGeometry.nWidth; ++ rHeight = maGeometry.nHeight; ++ } ++ else ++ rWidth = rHeight = 0; ++} ++ ++void GtkSalFrame::GetWorkArea( Rectangle& rRect ) ++{ ++ GdkScreen *pScreen = gtk_window_get_screen(GTK_WINDOW(m_pWindow)); ++ Rectangle aRetRect; ++ int max = gdk_screen_get_n_monitors (pScreen); ++ for (int i = 0; i < max; ++i) ++ { ++ GdkRectangle aRect; ++ gdk_screen_get_monitor_workarea(pScreen, i, &aRect); ++ Rectangle aMonitorRect(aRect.x, aRect.y, aRect.x+aRect.width, aRect.y+aRect.height); ++ aRetRect.Union(aMonitorRect); ++ } ++ rRect = aRetRect; ++} ++ ++SalFrame* GtkSalFrame::GetParent() const ++{ ++ return m_pParent; ++} ++ ++void GtkSalFrame::SetWindowState( const SalFrameState* pState ) ++{ ++ if( ! m_pWindow || ! pState || isChild( true, false ) ) ++ return; ++ ++ const sal_uLong nMaxGeometryMask = ++ WINDOWSTATE_MASK_X | WINDOWSTATE_MASK_Y | ++ WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT | ++ WINDOWSTATE_MASK_MAXIMIZED_X | WINDOWSTATE_MASK_MAXIMIZED_Y | ++ WINDOWSTATE_MASK_MAXIMIZED_WIDTH | WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; ++ ++ if( (pState->mnMask & WINDOWSTATE_MASK_STATE) && ++ ! ( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) && ++ (pState->mnState & WINDOWSTATE_STATE_MAXIMIZED) && ++ (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask ) ++ { ++ resizeWindow( pState->mnWidth, pState->mnHeight ); ++ moveWindow( pState->mnX, pState->mnY ); ++ m_bDefaultPos = m_bDefaultSize = false; ++ ++ updateScreenNumber(); ++ ++ m_nState = GdkWindowState( m_nState | GDK_WINDOW_STATE_MAXIMIZED ); ++ m_aRestorePosSize = Rectangle( Point( pState->mnX, pState->mnY ), ++ Size( pState->mnWidth, pState->mnHeight ) ); ++ } ++ else if( pState->mnMask & (WINDOWSTATE_MASK_X | WINDOWSTATE_MASK_Y | ++ WINDOWSTATE_MASK_WIDTH | WINDOWSTATE_MASK_HEIGHT ) ) ++ { ++ sal_uInt16 nPosSizeFlags = 0; ++ long nX = pState->mnX - (m_pParent ? m_pParent->maGeometry.nX : 0); ++ long nY = pState->mnY - (m_pParent ? m_pParent->maGeometry.nY : 0); ++ if( pState->mnMask & WINDOWSTATE_MASK_X ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_X; ++ else ++ nX = maGeometry.nX - (m_pParent ? m_pParent->maGeometry.nX : 0); ++ if( pState->mnMask & WINDOWSTATE_MASK_Y ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_Y; ++ else ++ nY = maGeometry.nY - (m_pParent ? m_pParent->maGeometry.nY : 0); ++ if( pState->mnMask & WINDOWSTATE_MASK_WIDTH ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH; ++ if( pState->mnMask & WINDOWSTATE_MASK_HEIGHT ) ++ nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT; ++ SetPosSize( nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags ); ++ } ++ if( pState->mnMask & WINDOWSTATE_MASK_STATE && ! isChild() ) ++ { ++ if( pState->mnState & WINDOWSTATE_STATE_MAXIMIZED ) ++ gtk_window_maximize( GTK_WINDOW(m_pWindow) ); ++ else ++ gtk_window_unmaximize( GTK_WINDOW(m_pWindow) ); ++ /* #i42379# there is no rollup state in GDK; and rolled up windows are ++ * (probably depending on the WM) reported as iconified. If we iconify a ++ * window here that was e.g. a dialog, then it will be unmapped but still ++ * not be displayed in the task list, so it's an iconified window that ++ * the user cannot get out of this state. So do not set the iconified state ++ * on windows with a parent (that is transient frames) since these tend ++ * to not be represented in an icon task list. ++ */ ++ if( (pState->mnState & WINDOWSTATE_STATE_MINIMIZED) ++ && ! m_pParent ) ++ gtk_window_iconify( GTK_WINDOW(m_pWindow) ); ++ else ++ gtk_window_deiconify( GTK_WINDOW(m_pWindow) ); ++ } ++ TriggerPaintEvent(); ++} ++ ++bool GtkSalFrame::GetWindowState( SalFrameState* pState ) ++{ ++ pState->mnState = WINDOWSTATE_STATE_NORMAL; ++ pState->mnMask = WINDOWSTATE_MASK_STATE; ++ // rollup ? gtk 2.2 does not seem to support the shaded state ++ if( (m_nState & GDK_WINDOW_STATE_ICONIFIED) ) ++ pState->mnState |= WINDOWSTATE_STATE_MINIMIZED; ++ if( m_nState & GDK_WINDOW_STATE_MAXIMIZED ) ++ { ++ pState->mnState |= WINDOWSTATE_STATE_MAXIMIZED; ++ pState->mnX = m_aRestorePosSize.Left(); ++ pState->mnY = m_aRestorePosSize.Top(); ++ pState->mnWidth = m_aRestorePosSize.GetWidth(); ++ pState->mnHeight = m_aRestorePosSize.GetHeight(); ++ pState->mnMaximizedX = maGeometry.nX; ++ pState->mnMaximizedY = maGeometry.nY; ++ pState->mnMaximizedWidth = maGeometry.nWidth; ++ pState->mnMaximizedHeight = maGeometry.nHeight; ++ pState->mnMask |= WINDOWSTATE_MASK_MAXIMIZED_X | ++ WINDOWSTATE_MASK_MAXIMIZED_Y | ++ WINDOWSTATE_MASK_MAXIMIZED_WIDTH | ++ WINDOWSTATE_MASK_MAXIMIZED_HEIGHT; ++ } ++ else ++ { ++ pState->mnX = maGeometry.nX; ++ pState->mnY = maGeometry.nY; ++ pState->mnWidth = maGeometry.nWidth; ++ pState->mnHeight = maGeometry.nHeight; ++ } ++ pState->mnMask |= WINDOWSTATE_MASK_X | ++ WINDOWSTATE_MASK_Y | ++ WINDOWSTATE_MASK_WIDTH | ++ WINDOWSTATE_MASK_HEIGHT; ++ ++ return true; ++} ++ ++typedef enum { ++ SET_RETAIN_SIZE, ++ SET_FULLSCREEN, ++ SET_UN_FULLSCREEN ++} SetType; ++ ++void GtkSalFrame::SetScreen( unsigned int nNewScreen, int eType, Rectangle *pSize ) ++{ ++ if( !m_pWindow ) ++ return; ++ ++ if (maGeometry.nDisplayScreenNumber == nNewScreen && eType == SET_RETAIN_SIZE) ++ return; ++ ++ int nX = maGeometry.nX, nY = maGeometry.nY, ++ nWidth = maGeometry.nWidth, nHeight = maGeometry.nHeight; ++ GdkScreen *pScreen = NULL; ++ GdkRectangle aNewMonitor; ++ ++ bool bSpanAllScreens = nNewScreen == (unsigned int)-1; ++ m_bSpanMonitorsWhenFullscreen = bSpanAllScreens && getDisplay()->getSystem()->GetDisplayScreenCount() > 1; ++ ++ if (m_bSpanMonitorsWhenFullscreen) //span all screens ++ { ++ pScreen = gtk_widget_get_screen( m_pWindow ); ++ aNewMonitor.x = 0; ++ aNewMonitor.y = 0; ++ aNewMonitor.width = gdk_screen_get_width(pScreen); ++ aNewMonitor.height = gdk_screen_get_height(pScreen); ++ } ++ else ++ { ++ gint nMonitor; ++ bool bSameMonitor = false; ++ ++ if (!bSpanAllScreens) ++ { ++ pScreen = getDisplay()->getSystem()->getScreenMonitorFromIdx( nNewScreen, nMonitor ); ++ if (!pScreen) ++ { ++ g_warning ("Attempt to move GtkSalFrame to invalid screen %d => " ++ "fallback to current\n", nNewScreen); ++ } ++ } ++ ++ if (!pScreen) ++ { ++ pScreen = gtk_widget_get_screen( m_pWindow ); ++ bSameMonitor = true; ++ } ++ ++ // Heavy lifting, need to move screen ... ++ if( pScreen != gtk_widget_get_screen( m_pWindow )) ++ gtk_window_set_screen( GTK_WINDOW( m_pWindow ), pScreen ); ++ ++ gint nOldMonitor = gdk_screen_get_monitor_at_window( ++ pScreen, widget_get_window( m_pWindow ) ); ++ if (bSameMonitor) ++ nMonitor = nOldMonitor; ++ ++ #if OSL_DEBUG_LEVEL > 1 ++ if( nMonitor == nOldMonitor ) ++ g_warning( "An apparently pointless SetScreen - should we elide it ?" ); ++ #endif ++ ++ GdkRectangle aOldMonitor; ++ gdk_screen_get_monitor_geometry( pScreen, nOldMonitor, &aOldMonitor ); ++ gdk_screen_get_monitor_geometry( pScreen, nMonitor, &aNewMonitor ); ++ ++ nX = aNewMonitor.x + maGeometry.nX - aOldMonitor.x; ++ nY = aNewMonitor.y + maGeometry.nY - aOldMonitor.y; ++ } ++ ++ bool bResize = false; ++ bool bVisible = IS_WIDGET_MAPPED( m_pWindow ); ++ if( bVisible ) ++ Show( false ); ++ ++ if( eType == SET_FULLSCREEN ) ++ { ++ nX = aNewMonitor.x; ++ nY = aNewMonitor.y; ++ nWidth = aNewMonitor.width; ++ nHeight = aNewMonitor.height; ++ m_nStyle |= SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; ++ bResize = true; ++ ++ // #i110881# for the benefit of compiz set a max size here ++ // else setting to fullscreen fails for unknown reasons ++ m_aMaxSize.Width() = aNewMonitor.width; ++ m_aMaxSize.Height() = aNewMonitor.height; ++ } ++ ++ if( pSize && eType == SET_UN_FULLSCREEN ) ++ { ++ nX = pSize->Left(); ++ nY = pSize->Top(); ++ nWidth = pSize->GetWidth(); ++ nHeight = pSize->GetHeight(); ++ m_nStyle &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN; ++ bResize = true; ++ } ++ ++ if (bResize) ++ { ++ // temporarily re-sizeable ++ if( !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) ++ gtk_window_set_resizable( GTK_WINDOW(m_pWindow), TRUE ); ++ window_resize(nWidth, nHeight); ++ } ++ ++ gtk_window_move(GTK_WINDOW(m_pWindow), nX, nY); ++ ++ { ++ gdk_window_set_fullscreen_mode( widget_get_window(m_pWindow), m_bSpanMonitorsWhenFullscreen ++ ? GDK_FULLSCREEN_ON_ALL_MONITORS : GDK_FULLSCREEN_ON_CURRENT_MONITOR ); ++ if( eType == SET_FULLSCREEN ) ++ gtk_window_fullscreen( GTK_WINDOW( m_pWindow ) ); ++ else if( eType == SET_UN_FULLSCREEN ) ++ gtk_window_unfullscreen( GTK_WINDOW( m_pWindow ) ); ++ } ++ ++ if( eType == SET_UN_FULLSCREEN && ++ !(m_nStyle & SAL_FRAME_STYLE_SIZEABLE) ) ++ gtk_window_set_resizable( GTK_WINDOW( m_pWindow ), FALSE ); ++ ++ // FIXME: we should really let gtk+ handle our widget hierarchy ... ++ if( m_pParent && gtk_widget_get_screen( m_pParent->m_pWindow ) != pScreen ) ++ SetParent( NULL ); ++ std::list< GtkSalFrame* > aChildren = m_aChildren; ++ for( std::list< GtkSalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it ) ++ (*it)->SetScreen( nNewScreen, SET_RETAIN_SIZE ); ++ ++ m_bDefaultPos = m_bDefaultSize = false; ++ updateScreenNumber(); ++ ++ if( bVisible ) ++ Show( true ); ++} ++ ++void GtkSalFrame::SetScreenNumber( unsigned int nNewScreen ) ++{ ++ SetScreen( nNewScreen, SET_RETAIN_SIZE ); ++} ++ ++void GtkSalFrame::updateWMClass() ++{ ++ OString aResClass = OUStringToOString(m_sWMClass, RTL_TEXTENCODING_ASCII_US); ++ const char *pResClass = !aResClass.isEmpty() ? aResClass.getStr() : ++ SalGenericSystem::getFrameClassName(); ++ Display *display; ++ ++ if (!getDisplay()->IsX11Display()) ++ return; ++ ++ display = GDK_DISPLAY_XDISPLAY(getGdkDisplay()); ++ ++ if( IS_WIDGET_REALIZED( m_pWindow ) ) ++ { ++ XClassHint* pClass = XAllocClassHint(); ++ OString aResName = SalGenericSystem::getFrameResName(); ++ pClass->res_name = const_cast(aResName.getStr()); ++ pClass->res_class = const_cast(pResClass); ++ XSetClassHint( display, ++ widget_get_xid(m_pWindow), ++ pClass ); ++ XFree( pClass ); ++ } ++} ++ ++void GtkSalFrame::SetApplicationID( const OUString &rWMClass ) ++{ ++ if( rWMClass != m_sWMClass && ! isChild() ) ++ { ++ m_sWMClass = rWMClass; ++ updateWMClass(); ++ ++ for( std::list< GtkSalFrame* >::iterator it = m_aChildren.begin(); it != m_aChildren.end(); ++it ) ++ (*it)->SetApplicationID(rWMClass); ++ } ++} ++ ++void GtkSalFrame::ShowFullScreen( bool bFullScreen, sal_Int32 nScreen ) ++{ ++ m_bFullscreen = bFullScreen; ++ ++ if( !m_pWindow || isChild() ) ++ return; ++ ++ if( bFullScreen ) ++ { ++ m_aRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), ++ Size( maGeometry.nWidth, maGeometry.nHeight ) ); ++ SetScreen( nScreen, SET_FULLSCREEN ); ++ } ++ else ++ { ++ SetScreen( nScreen, SET_UN_FULLSCREEN, ++ !m_aRestorePosSize.IsEmpty() ? &m_aRestorePosSize : NULL ); ++ m_aRestorePosSize = Rectangle(); ++ } ++} ++ ++/* definitions from xautolock.c (pl15) */ ++#define XAUTOLOCK_DISABLE 1 ++#define XAUTOLOCK_ENABLE 2 ++ ++void GtkSalFrame::setAutoLock( bool bLock ) ++{ ++ if( isChild() || !getDisplay()->IsX11Display() ) ++ return; ++ ++ GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(m_pWindow) ); ++ GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); ++ GdkWindow *pRootWin = gdk_screen_get_root_window( pScreen ); ++ ++ Atom nAtom = XInternAtom( GDK_DISPLAY_XDISPLAY( pDisplay ), ++ "XAUTOLOCK_MESSAGE", False ); ++ ++ int nMessage = bLock ? XAUTOLOCK_ENABLE : XAUTOLOCK_DISABLE; ++ ++ XChangeProperty( GDK_DISPLAY_XDISPLAY( pDisplay ), ++ GDK_WINDOW_XID( pRootWin ), ++ nAtom, XA_INTEGER, ++ 8, PropModeReplace, ++ reinterpret_cast(&nMessage), ++ sizeof( nMessage ) ); ++} ++ ++#ifdef ENABLE_DBUS ++/** cookie is returned as an unsigned integer */ ++static guint ++dbus_inhibit_gsm (const gchar *appname, ++ const gchar *reason, ++ guint xid) ++{ ++ gboolean res; ++ guint cookie; ++ GError *error = NULL; ++ DBusGProxy *proxy = NULL; ++ ++ /* get the DBUS session connection */ ++ DBusGConnection *session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); ++ if (error != NULL) { ++ g_debug ("DBUS cannot connect : %s", error->message); ++ g_error_free (error); ++ return -1; ++ } ++ ++ /* get the proxy with gnome-session-manager */ ++ proxy = dbus_g_proxy_new_for_name (session_connection, ++ GSM_DBUS_SERVICE, ++ GSM_DBUS_PATH, ++ GSM_DBUS_INTERFACE); ++ if (proxy == NULL) { ++ g_debug ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); ++ return -1; ++ } ++ ++ res = dbus_g_proxy_call (proxy, ++ "Inhibit", &error, ++ G_TYPE_STRING, appname, ++ G_TYPE_UINT, xid, ++ G_TYPE_STRING, reason, ++ G_TYPE_UINT, 8, //Inhibit the session being marked as idle ++ G_TYPE_INVALID, ++ G_TYPE_UINT, &cookie, ++ G_TYPE_INVALID); ++ ++ /* check the return value */ ++ if (! res) { ++ cookie = -1; ++ g_debug ("Inhibit method failed"); ++ } ++ ++ /* check the error value */ ++ if (error != NULL) { ++ g_debug ("Inhibit problem : %s", error->message); ++ g_error_free (error); ++ cookie = -1; ++ } ++ ++ g_object_unref (G_OBJECT (proxy)); ++ return cookie; ++} ++ ++static void ++dbus_uninhibit_gsm (guint cookie) ++{ ++ gboolean res; ++ GError *error = NULL; ++ DBusGProxy *proxy = NULL; ++ DBusGConnection *session_connection = NULL; ++ ++ if (cookie == guint(-1)) { ++ g_debug ("Invalid cookie"); ++ return; ++ } ++ ++ /* get the DBUS session connection */ ++ session_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); ++ if (error) { ++ g_debug ("DBUS cannot connect : %s", error->message); ++ g_error_free (error); ++ return; ++ } ++ ++ /* get the proxy with gnome-session-manager */ ++ proxy = dbus_g_proxy_new_for_name (session_connection, ++ GSM_DBUS_SERVICE, ++ GSM_DBUS_PATH, ++ GSM_DBUS_INTERFACE); ++ if (proxy == NULL) { ++ g_debug ("Could not get DBUS proxy: %s", GSM_DBUS_SERVICE); ++ return; ++ } ++ ++ res = dbus_g_proxy_call (proxy, ++ "Uninhibit", ++ &error, ++ G_TYPE_UINT, cookie, ++ G_TYPE_INVALID, ++ G_TYPE_INVALID); ++ ++ /* check the return value */ ++ if (! res) { ++ g_debug ("Uninhibit method failed"); ++ } ++ ++ /* check the error value */ ++ if (error != NULL) { ++ g_debug ("Uninhibit problem : %s", error->message); ++ g_error_free (error); ++ cookie = -1; ++ } ++ g_object_unref (G_OBJECT (proxy)); ++} ++#endif ++ ++void GtkSalFrame::StartPresentation( bool bStart ) ++{ ++ setAutoLock( !bStart ); ++ ++ if( !getDisplay()->IsX11Display() ) ++ return; ++ ++ if( bStart ) ++ { ++#ifdef ENABLE_DBUS ++ m_nGSMCookie = dbus_inhibit_gsm(g_get_application_name(), "presentation", ++ widget_get_xid(m_pWindow)); ++#endif ++ } ++ else ++ { ++ m_nSavedScreenSaverTimeout = 0; ++#ifdef ENABLE_DBUS ++ dbus_uninhibit_gsm(m_nGSMCookie); ++#endif ++ } ++} ++ ++void GtkSalFrame::SetAlwaysOnTop( bool bOnTop ) ++{ ++ if( m_pWindow ) ++ gtk_window_set_keep_above( GTK_WINDOW( m_pWindow ), bOnTop ); ++} ++ ++void GtkSalFrame::ToTop( sal_uInt16 nFlags ) ++{ ++ if( m_pWindow ) ++ { ++ if( isChild( false, true ) ) ++ gtk_widget_grab_focus( m_pWindow ); ++ else if( IS_WIDGET_MAPPED( m_pWindow ) ) ++ { ++ if( ! (nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY) ) ++ gtk_window_present( GTK_WINDOW(m_pWindow) ); ++ else ++ { ++ guint32 nUserTime = GDK_CURRENT_TIME; ++ gdk_window_focus( widget_get_window(m_pWindow), nUserTime ); ++ } ++ } ++ else ++ { ++ if( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN ) ++ gtk_window_present( GTK_WINDOW(m_pWindow) ); ++ } ++ } ++} ++ ++void GtkSalFrame::SetPointer( PointerStyle ePointerStyle ) ++{ ++ if( m_pWindow && ePointerStyle != m_ePointerStyle ) ++ { ++ m_ePointerStyle = ePointerStyle; ++ GdkCursor *pCursor = getDisplay()->getCursor( ePointerStyle ); ++ gdk_window_set_cursor( widget_get_window(m_pWindow), pCursor ); ++ m_pCurrentCursor = pCursor; ++ ++ // #i80791# use grabPointer the same way as CaptureMouse, respective float grab ++ if( getDisplay()->MouseCaptured( this ) ) ++ grabPointer( true, false ); ++ else if( m_nFloats > 0 ) ++ grabPointer( true, true ); ++ } ++} ++ ++void GtkSalFrame::grabPointer( bool bGrab, bool bOwnerEvents ) ++{ ++ static const char* pEnv = getenv( "SAL_NO_MOUSEGRABS" ); ++ if (pEnv && *pEnv) ++ return; ++ ++ if (!m_pWindow) ++ return; ++ ++ const int nMask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); ++ ++ GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay()); ++ GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager); ++ if (bGrab) ++ gdk_device_grab(pPointer, widget_get_window(getMouseEventWidget()), GDK_OWNERSHIP_NONE, bOwnerEvents, (GdkEventMask) nMask, m_pCurrentCursor, GDK_CURRENT_TIME); ++ else ++ gdk_device_ungrab(pPointer, GDK_CURRENT_TIME); ++} ++ ++void GtkSalFrame::grabKeyboard( bool bGrab ) ++{ ++ if (!m_pWindow) ++ return; ++ ++ GdkDeviceManager* pDeviceManager = gdk_display_get_device_manager(getGdkDisplay()); ++ GdkDevice* pPointer = gdk_device_manager_get_client_pointer(pDeviceManager); ++ GdkDevice* pKeyboard = gdk_device_get_associated_device(pPointer); ++ if (bGrab) ++ { ++ gdk_device_grab(pKeyboard, widget_get_window(m_pWindow), GDK_OWNERSHIP_NONE, ++ true, (GdkEventMask)(GDK_KEY_PRESS | GDK_KEY_RELEASE), NULL, GDK_CURRENT_TIME); ++ } ++ else ++ { ++ gdk_device_ungrab(pKeyboard, GDK_CURRENT_TIME); ++ } ++} ++ ++void GtkSalFrame::CaptureMouse( bool bCapture ) ++{ ++ getDisplay()->CaptureMouse( bCapture ? this : NULL ); ++} ++ ++void GtkSalFrame::SetPointerPos( long nX, long nY ) ++{ ++ GtkSalFrame* pFrame = this; ++ while( pFrame && pFrame->isChild( false, true ) ) ++ pFrame = pFrame->m_pParent; ++ if( ! pFrame ) ++ return; ++ ++ GdkScreen *pScreen = gtk_window_get_screen( GTK_WINDOW(pFrame->m_pWindow) ); ++ GdkDisplay *pDisplay = gdk_screen_get_display( pScreen ); ++ ++ /* when the application tries to center the mouse in the dialog the ++ * window isn't mapped already. So use coordinates relative to the root window. ++ */ ++ unsigned int nWindowLeft = maGeometry.nX + nX; ++ unsigned int nWindowTop = maGeometry.nY + nY; ++ ++ XWarpPointer( GDK_DISPLAY_XDISPLAY (pDisplay), None, ++ GDK_WINDOW_XID (gdk_screen_get_root_window( pScreen ) ), ++ 0, 0, 0, 0, nWindowLeft, nWindowTop); ++ // #i38648# ask for the next motion hint ++ gint x, y; ++ GdkModifierType mask; ++ gdk_window_get_pointer( widget_get_window(pFrame->m_pWindow) , &x, &y, &mask ); ++} ++ ++void GtkSalFrame::Flush() ++{ ++ gdk_display_flush( getGdkDisplay() ); ++} ++ ++void GtkSalFrame::Sync() ++{ ++ gdk_display_sync( getGdkDisplay() ); ++} ++ ++#ifndef GDK_Open ++#define GDK_Open 0x1008ff6b ++#endif ++#ifndef GDK_Paste ++#define GDK_Paste 0x1008ff6d ++#endif ++#ifndef GDK_Copy ++#define GDK_Copy 0x1008ff57 ++#endif ++#ifndef GDK_Cut ++#define GDK_Cut 0x1008ff58 ++#endif ++ ++void GtkSalFrame::KeyCodeToGdkKey(const vcl::KeyCode& rKeyCode, ++ guint* pGdkKeyCode, GdkModifierType *pGdkModifiers) ++{ ++ if ( pGdkKeyCode == NULL || pGdkModifiers == NULL ) ++ return; ++ ++ // Get GDK key modifiers ++ GdkModifierType nModifiers = (GdkModifierType) 0; ++ ++ if ( rKeyCode.IsShift() ) ++ nModifiers = (GdkModifierType) ( nModifiers | GDK_SHIFT_MASK ); ++ ++ if ( rKeyCode.IsMod1() ) ++ nModifiers = (GdkModifierType) ( nModifiers | GDK_CONTROL_MASK ); ++ ++ if ( rKeyCode.IsMod2() ) ++ nModifiers = (GdkModifierType) ( nModifiers | GDK_MOD1_MASK ); ++ ++ *pGdkModifiers = nModifiers; ++ ++ // Get GDK keycode. ++ guint nKeyCode = 0; ++ ++ guint nCode = rKeyCode.GetCode(); ++ ++ if ( nCode >= KEY_0 && nCode <= KEY_9 ) ++ nKeyCode = ( nCode - KEY_0 ) + GDK_0; ++ else if ( nCode >= KEY_A && nCode <= KEY_Z ) ++ nKeyCode = ( nCode - KEY_A ) + GDK_A; ++ else if ( nCode >= KEY_F1 && nCode <= KEY_F26 ) ++ nKeyCode = ( nCode - KEY_F1 ) + GDK_F1; ++ else ++ { ++ switch( nCode ) ++ { ++ case KEY_DOWN: nKeyCode = GDK_Down; break; ++ case KEY_UP: nKeyCode = GDK_Up; break; ++ case KEY_LEFT: nKeyCode = GDK_Left; break; ++ case KEY_RIGHT: nKeyCode = GDK_Right; break; ++ case KEY_HOME: nKeyCode = GDK_Home; break; ++ case KEY_END: nKeyCode = GDK_End; break; ++ case KEY_PAGEUP: nKeyCode = GDK_Page_Up; break; ++ case KEY_PAGEDOWN: nKeyCode = GDK_Page_Down; break; ++ case KEY_RETURN: nKeyCode = GDK_Return; break; ++ case KEY_ESCAPE: nKeyCode = GDK_Escape; break; ++ case KEY_TAB: nKeyCode = GDK_Tab; break; ++ case KEY_BACKSPACE: nKeyCode = GDK_BackSpace; break; ++ case KEY_SPACE: nKeyCode = GDK_space; break; ++ case KEY_INSERT: nKeyCode = GDK_Insert; break; ++ case KEY_DELETE: nKeyCode = GDK_Delete; break; ++ case KEY_ADD: nKeyCode = GDK_plus; break; ++ case KEY_SUBTRACT: nKeyCode = GDK_minus; break; ++ case KEY_MULTIPLY: nKeyCode = GDK_asterisk; break; ++ case KEY_DIVIDE: nKeyCode = GDK_slash; break; ++ case KEY_POINT: nKeyCode = GDK_period; break; ++ case KEY_COMMA: nKeyCode = GDK_comma; break; ++ case KEY_LESS: nKeyCode = GDK_less; break; ++ case KEY_GREATER: nKeyCode = GDK_greater; break; ++ case KEY_EQUAL: nKeyCode = GDK_equal; break; ++ case KEY_FIND: nKeyCode = GDK_Find; break; ++ case KEY_CONTEXTMENU: nKeyCode = GDK_Menu; break; ++ case KEY_HELP: nKeyCode = GDK_Help; break; ++ case KEY_UNDO: nKeyCode = GDK_Undo; break; ++ case KEY_REPEAT: nKeyCode = GDK_Redo; break; ++ case KEY_DECIMAL: nKeyCode = GDK_KP_Decimal; break; ++ case KEY_TILDE: nKeyCode = GDK_asciitilde; break; ++ case KEY_QUOTELEFT: nKeyCode = GDK_quoteleft; break; ++ case KEY_BRACKETLEFT: nKeyCode = GDK_bracketleft; break; ++ case KEY_BRACKETRIGHT: nKeyCode = GDK_bracketright; break; ++ case KEY_SEMICOLON: nKeyCode = GDK_semicolon; break; ++ case KEY_QUOTERIGHT: nKeyCode = GDK_quoteright; break; ++ ++ // Special cases ++ case KEY_COPY: nKeyCode = GDK_Copy; break; ++ case KEY_CUT: nKeyCode = GDK_Cut; break; ++ case KEY_PASTE: nKeyCode = GDK_Paste; break; ++ case KEY_OPEN: nKeyCode = GDK_Open; break; ++ } ++ } ++ ++ *pGdkKeyCode = nKeyCode; ++} ++ ++OUString GtkSalFrame::GetKeyName( sal_uInt16 nKeyCode ) ++{ ++ guint nGtkKeyCode; ++ GdkModifierType nGtkModifiers; ++ KeyCodeToGdkKey(nKeyCode, &nGtkKeyCode, &nGtkModifiers ); ++ ++ gchar* pName = gtk_accelerator_get_label(nGtkKeyCode, nGtkModifiers); ++ OUString aRet(pName, rtl_str_getLength(pName), RTL_TEXTENCODING_UTF8); ++ g_free(pName); ++ return aRet; ++} ++ ++GdkDisplay *GtkSalFrame::getGdkDisplay() ++{ ++ return GetGtkSalData()->GetGdkDisplay(); ++} ++ ++GtkSalDisplay *GtkSalFrame::getDisplay() ++{ ++ return GetGtkSalData()->GetGtkDisplay(); ++} ++ ++SalFrame::SalPointerState GtkSalFrame::GetPointerState() ++{ ++ SalPointerState aState; ++ GdkScreen* pScreen; ++ gint x, y; ++ GdkModifierType aMask; ++ gdk_display_get_pointer( getGdkDisplay(), &pScreen, &x, &y, &aMask ); ++ aState.maPos = Point( x - maGeometry.nX, y - maGeometry.nY ); ++ aState.mnState = GetMouseModCode( aMask ); ++ return aState; ++} ++ ++KeyIndicatorState GtkSalFrame::GetIndicatorState() ++{ ++ KeyIndicatorState nState = KeyIndicatorState::NONE; ++ ++ GdkKeymap *pKeyMap = gdk_keymap_get_for_display(getGdkDisplay()); ++ ++ if (gdk_keymap_get_caps_lock_state(pKeyMap)) ++ nState |= KeyIndicatorState::CAPSLOCK; ++ if (gdk_keymap_get_num_lock_state(pKeyMap)) ++ nState |= KeyIndicatorState::NUMLOCK; ++#if GTK_CHECK_VERSION(3,18,0) ++ if (gdk_keymap_get_scroll_lock_state(pKeyMap)) ++ nState |= KeyIndicatorState::SCROLLLOCK; ++#endif ++ return nState; ++} ++ ++void GtkSalFrame::SimulateKeyPress( sal_uInt16 nKeyCode ) ++{ ++ g_warning ("missing simulate keypress %d", nKeyCode); ++} ++ ++void GtkSalFrame::SetInputContext( SalInputContext* pContext ) ++{ ++ if( ! pContext ) ++ return; ++ ++ if( ! (pContext->mnOptions & InputContextFlags::Text) ) ++ return; ++ ++ // create a new im context ++ if( ! m_pIMHandler ) ++ m_pIMHandler = new IMHandler( this ); ++} ++ ++void GtkSalFrame::EndExtTextInput( sal_uInt16 nFlags ) ++{ ++ if( m_pIMHandler ) ++ m_pIMHandler->endExtTextInput( nFlags ); ++} ++ ++bool GtkSalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , vcl::KeyCode& ) ++{ ++ // not supported yet ++ return false; ++} ++ ++LanguageType GtkSalFrame::GetInputLanguage() ++{ ++ return LANGUAGE_DONTKNOW; ++} ++ ++void GtkSalFrame::UpdateSettings( AllSettings& rSettings ) ++{ ++ if( ! m_pWindow ) ++ return; ++ ++ GtkSalGraphics* pGraphics = static_cast(m_aGraphics[0].pGraphics); ++ bool bFreeGraphics = false; ++ if( ! pGraphics ) ++ { ++ pGraphics = static_cast(AcquireGraphics()); ++ if ( !pGraphics ) ++ { ++ SAL_WARN("vcl", "Could not get graphics - unable to update settings"); ++ return; ++ } ++ bFreeGraphics = true; ++ } ++ ++ pGraphics->updateSettings( rSettings ); ++ ++ if( bFreeGraphics ) ++ ReleaseGraphics( pGraphics ); ++} ++ ++void GtkSalFrame::Beep() ++{ ++ gdk_display_beep( getGdkDisplay() ); ++} ++ ++const SystemEnvData* GtkSalFrame::GetSystemData() const ++{ ++ return &m_aSystemData; ++} ++ ++void GtkSalFrame::SetParent( SalFrame* pNewParent ) ++{ ++ if( m_pParent ) ++ m_pParent->m_aChildren.remove( this ); ++ m_pParent = static_cast(pNewParent); ++ if( m_pParent ) ++ m_pParent->m_aChildren.push_back( this ); ++ if( ! isChild() ) ++ gtk_window_set_transient_for( GTK_WINDOW(m_pWindow), ++ (m_pParent && ! m_pParent->isChild(true,false)) ? GTK_WINDOW(m_pParent->m_pWindow) : NULL ++ ); ++} ++ ++bool GtkSalFrame::SetPluginParent( SystemParentData* pSysParent ) ++{ ++ (void)pSysParent; ++ //FIXME: no SetPluginParent impl. for gtk3 ++ return false; ++} ++ ++void GtkSalFrame::ResetClipRegion() ++{ ++ if( m_pWindow ) ++ gdk_window_shape_combine_region( widget_get_window( m_pWindow ), NULL, 0, 0 ); ++} ++ ++void GtkSalFrame::BeginSetClipRegion( sal_uLong ) ++{ ++ if( m_pRegion ) ++ cairo_region_destroy( m_pRegion ); ++ m_pRegion = cairo_region_create(); ++} ++ ++void GtkSalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight ) ++{ ++ if( m_pRegion ) ++ { ++ GdkRectangle aRect; ++ aRect.x = nX; ++ aRect.y = nY; ++ aRect.width = nWidth; ++ aRect.height = nHeight; ++ cairo_region_union_rectangle( m_pRegion, &aRect ); ++ } ++} ++ ++void GtkSalFrame::EndSetClipRegion() ++{ ++ if( m_pWindow && m_pRegion ) ++ gdk_window_shape_combine_region( widget_get_window(m_pWindow), m_pRegion, 0, 0 ); ++} ++ ++gboolean GtkSalFrame::signalButton( GtkWidget*, GdkEventButton* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalMouseEvent aEvent; ++ sal_uInt16 nEventType = 0; ++ switch( pEvent->type ) ++ { ++ case GDK_BUTTON_PRESS: ++ nEventType = SALEVENT_MOUSEBUTTONDOWN; ++ break; ++ case GDK_BUTTON_RELEASE: ++ nEventType = SALEVENT_MOUSEBUTTONUP; ++ break; ++ default: ++ return false; ++ } ++ switch( pEvent->button ) ++ { ++ case 1: aEvent.mnButton = MOUSE_LEFT; break; ++ case 2: aEvent.mnButton = MOUSE_MIDDLE; break; ++ case 3: aEvent.mnButton = MOUSE_RIGHT; break; ++ default: return false; ++ } ++ aEvent.mnTime = pEvent->time; ++ aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; ++ aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; ++ aEvent.mnCode = GetMouseModCode( pEvent->state ); ++ ++ bool bClosePopups = false; ++ if( pEvent->type == GDK_BUTTON_PRESS && ++ (pThis->m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) == 0 ++ ) ++ { ++ if( m_nFloats > 0 ) ++ { ++ // close popups if user clicks outside our application ++ gint x, y; ++ bClosePopups = (gdk_display_get_window_at_pointer( GtkSalFrame::getGdkDisplay(), &x, &y ) == NULL); ++ } ++ /* #i30306# release implicit pointer grab if no popups are open; else ++ * Drag cannot grab the pointer and will fail. ++ */ ++ if( m_nFloats < 1 || bClosePopups ) ++ gdk_display_pointer_ungrab( GtkSalFrame::getGdkDisplay(), GDK_CURRENT_TIME ); ++ } ++ ++ if( pThis->m_bWindowIsGtkPlug && ++ pEvent->type == GDK_BUTTON_PRESS && ++ pEvent->button == 1 ) ++ { ++ pThis->askForXEmbedFocus( pEvent->time ); ++ } ++ ++ // --- RTL --- (mirror mouse pos) ++ if( AllSettings::GetLayoutRTL() ) ++ aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; ++ ++ vcl::DeletionListener aDel( pThis ); ++ ++ pThis->CallCallback( nEventType, &aEvent ); ++ ++ if( ! aDel.isDeleted() ) ++ { ++ if( bClosePopups ) ++ { ++ ImplSVData* pSVData = ImplGetSVData(); ++ if ( pSVData->maWinData.mpFirstFloat ) ++ { ++ static const char* pEnv = getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" ); ++ if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FloatWinPopupFlags::NoAppFocusClose) && !(pEnv && *pEnv) ) ++ pSVData->maWinData.mpFirstFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll ); ++ } ++ } ++ ++ if( ! aDel.isDeleted() ) ++ { ++ int frame_x = (int)(pEvent->x_root - pEvent->x); ++ int frame_y = (int)(pEvent->y_root - pEvent->y); ++ if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) ++ { ++ pThis->maGeometry.nX = frame_x; ++ pThis->maGeometry.nY = frame_y; ++ pThis->CallCallback( SALEVENT_MOVE, NULL ); ++ } ++ } ++ } ++ ++ return true; ++} ++ ++gboolean GtkSalFrame::signalScroll( GtkWidget*, GdkEvent* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ GdkEventScroll* pSEvent = reinterpret_cast(pEvent); ++ ++ // gnome#726878 check for duplicate legacy scroll event ++ if (pSEvent->direction != GDK_SCROLL_SMOOTH && ++ pThis->m_nLastScrollEventTime == pSEvent->time) ++ { ++ return true; ++ } ++ ++ SalWheelMouseEvent aEvent; ++ ++ aEvent.mnTime = pSEvent->time; ++ aEvent.mnX = (sal_uLong)pSEvent->x; ++ aEvent.mnY = (sal_uLong)pSEvent->y; ++ aEvent.mnCode = GetMouseModCode( pSEvent->state ); ++ aEvent.mnScrollLines = 3; ++ ++ switch (pSEvent->direction) ++ { ++ case GDK_SCROLL_SMOOTH: ++ { ++ double delta_x, delta_y; ++ gdk_event_get_scroll_deltas(pEvent, &delta_x, &delta_y); ++ //pick the bigger one I guess ++ aEvent.mbHorz = fabs(delta_x) > fabs(delta_y); ++ if (aEvent.mbHorz) ++ aEvent.mnDelta = -delta_x; ++ else ++ aEvent.mnDelta = -delta_y; ++ aEvent.mnScrollLines = 1; ++ pThis->m_nLastScrollEventTime = pSEvent->time; ++ break; ++ } ++ case GDK_SCROLL_UP: ++ aEvent.mnDelta = 120; ++ aEvent.mbHorz = false; ++ break; ++ case GDK_SCROLL_DOWN: ++ aEvent.mnDelta = -120; ++ aEvent.mbHorz = false; ++ break; ++ case GDK_SCROLL_LEFT: ++ aEvent.mbHorz = true; ++ aEvent.mnDelta = 120; ++ break; ++ case GDK_SCROLL_RIGHT: ++ aEvent.mnDelta = -120; ++ aEvent.mbHorz = true; ++ break; ++ }; ++ ++ aEvent.mnNotchDelta = aEvent.mnDelta < 0 ? -1 : 1; ++ ++ // --- RTL --- (mirror mouse pos) ++ if( AllSettings::GetLayoutRTL() ) ++ aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; ++ ++ pThis->CallCallback( SALEVENT_WHEELMOUSE, &aEvent ); ++ ++ return true; ++} ++ ++void GtkSalFrame::gestureSwipe(GtkGestureSwipe* gesture, gdouble velocity_x, gdouble velocity_y, gpointer frame) ++{ ++ gdouble x, y; ++ GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); ++ //I feel I want the first point of the sequence, not the last point which ++ //the docs say this gives, but for the moment assume we start and end ++ //within the same vcl window ++ if (gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y)) ++ { ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalSwipeEvent aEvent; ++ aEvent.mnVelocityX = velocity_x; ++ aEvent.mnVelocityY = velocity_y; ++ aEvent.mnX = x; ++ aEvent.mnY = y; ++ ++ pThis->CallCallback(SALEVENT_SWIPE, &aEvent); ++ } ++} ++ ++void GtkSalFrame::gestureLongPress(GtkGestureLongPress* gesture, gpointer frame) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ if(pThis) ++ { ++ SalLongPressEvent aEvent; ++ ++ gdouble x, y; ++ GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)); ++ gtk_gesture_get_point(GTK_GESTURE(gesture), sequence, &x, &y); ++ aEvent.mnX = x; ++ aEvent.mnY = y; ++ ++ pThis->CallCallback(SALEVENT_LONGPRESS, &aEvent); ++ } ++} ++ ++gboolean GtkSalFrame::signalMotion( GtkWidget*, GdkEventMotion* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalMouseEvent aEvent; ++ aEvent.mnTime = pEvent->time; ++ aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; ++ aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; ++ aEvent.mnCode = GetMouseModCode( pEvent->state ); ++ aEvent.mnButton = 0; ++ ++ // --- RTL --- (mirror mouse pos) ++ if( AllSettings::GetLayoutRTL() ) ++ aEvent.mnX = pThis->maGeometry.nWidth-1-aEvent.mnX; ++ ++ vcl::DeletionListener aDel( pThis ); ++ ++ pThis->CallCallback( SALEVENT_MOUSEMOVE, &aEvent ); ++ ++ if( ! aDel.isDeleted() ) ++ { ++ int frame_x = (int)(pEvent->x_root - pEvent->x); ++ int frame_y = (int)(pEvent->y_root - pEvent->y); ++ if( frame_x != pThis->maGeometry.nX || frame_y != pThis->maGeometry.nY ) ++ { ++ pThis->maGeometry.nX = frame_x; ++ pThis->maGeometry.nY = frame_y; ++ pThis->CallCallback( SALEVENT_MOVE, NULL ); ++ } ++ ++ if( ! aDel.isDeleted() ) ++ { ++ // ask for the next hint ++ gint x, y; ++ GdkModifierType mask; ++ gdk_window_get_pointer( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &x, &y, &mask ); ++ } ++ } ++ ++ return true; ++} ++ ++gboolean GtkSalFrame::signalCrossing( GtkWidget*, GdkEventCrossing* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ SalMouseEvent aEvent; ++ aEvent.mnTime = pEvent->time; ++ aEvent.mnX = (long)pEvent->x_root - pThis->maGeometry.nX; ++ aEvent.mnY = (long)pEvent->y_root - pThis->maGeometry.nY; ++ aEvent.mnCode = GetMouseModCode( pEvent->state ); ++ aEvent.mnButton = 0; ++ ++ pThis->CallCallback( (pEvent->type == GDK_ENTER_NOTIFY) ? SALEVENT_MOUSEMOVE : SALEVENT_MOUSELEAVE, &aEvent ); ++ ++ return true; ++} ++ ++cairo_t* GtkSalFrame::getCairoContext() const ++{ ++ cairo_t* cr = SvpSalGraphics::createCairoContext(m_aFrame); ++ assert(cr); ++ return cr; ++} ++ ++void GtkSalFrame::damaged (const basegfx::B2IBox& rDamageRect) ++{ ++#if OSL_DEBUG_LEVEL > 1 ++ long long area = rDamageRect.getWidth() * rDamageRect.getHeight(); ++ if( area > 32 * 1024 ) ++ { ++ fprintf( stderr, "bitmap damaged %d %d (%dx%d) area %lld widget\n", ++ (int) rDamageRect.getMinX(), ++ (int) rDamageRect.getMinY(), ++ (int) rDamageRect.getWidth(), ++ (int) rDamageRect.getHeight(), ++ area ); ++ } ++#endif ++ ++ if (dumpframes) ++ { ++ static int frame; ++ OString tmp("/tmp/frame" + OString::number(frame++) + ".png"); ++ cairo_t* cr = getCairoContext(); ++ cairo_surface_write_to_png(cairo_get_target(cr), tmp.getStr()); ++ cairo_destroy(cr); ++ } ++ ++ gtk_widget_queue_draw_area(GTK_WIDGET(m_pFixedContainer), ++ rDamageRect.getMinX(), ++ rDamageRect.getMinY(), ++ rDamageRect.getWidth(), ++ rDamageRect.getHeight()); ++} ++ ++// blit our backing basebmp buffer to the target cairo context cr ++gboolean GtkSalFrame::signalDraw( GtkWidget*, cairo_t *cr, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ cairo_save(cr); ++ ++ cairo_t* source = pThis->getCairoContext(); ++ cairo_surface_t *pSurface = cairo_get_target(source); ++ ++ cairo_set_operator( cr, CAIRO_OPERATOR_OVER ); ++ cairo_set_source_surface(cr, pSurface, 0, 0); ++ cairo_paint(cr); ++ ++ cairo_destroy(source); ++ ++ cairo_restore(cr); ++ ++ cairo_surface_flush(cairo_get_target(cr)); ++ ++ return false; ++} ++ ++void GtkSalFrame::sizeAllocated(GtkWidget*, GdkRectangle *pAllocation, gpointer frame) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ pThis->maGeometry.nWidth = pAllocation->width; ++ pThis->maGeometry.nHeight = pAllocation->height; ++ pThis->AllocateFrame(); ++ pThis->CallCallback( SALEVENT_RESIZE, nullptr ); ++ pThis->TriggerPaintEvent(); ++} ++ ++gboolean GtkSalFrame::signalConfigure(GtkWidget*, GdkEventConfigure* pEvent, gpointer frame) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ bool bMoved = false; ++ int x = pEvent->x, y = pEvent->y; ++ ++ /* #i31785# claims we cannot trust the x,y members of the event; ++ * they are e.g. not set correctly on maximize/demaximize; ++ * yet the gdkdisplay-x11.c code handling configure_events has ++ * done this XTranslateCoordinates work since the day ~zero. ++ */ ++ if( x != pThis->maGeometry.nX || y != pThis->maGeometry.nY ) ++ { ++ bMoved = true; ++ pThis->maGeometry.nX = x; ++ pThis->maGeometry.nY = y; ++ } ++ ++ // update decoration hints ++ GdkRectangle aRect; ++ gdk_window_get_frame_extents( widget_get_window(GTK_WIDGET(pThis->m_pWindow)), &aRect ); ++ pThis->maGeometry.nTopDecoration = y - aRect.y; ++ pThis->maGeometry.nBottomDecoration = aRect.y + aRect.height - y - pEvent->height; ++ pThis->maGeometry.nLeftDecoration = x - aRect.x; ++ pThis->maGeometry.nRightDecoration = aRect.x + aRect.width - x - pEvent->width; ++ ++ pThis->updateScreenNumber(); ++ ++ if (bMoved) ++ pThis->CallCallback(SALEVENT_MOVE, nullptr); ++ ++ return false; ++} ++ ++void GtkSalFrame::TriggerPaintEvent() ++{ ++ //Under gtk2 we can basically paint directly into the XWindow and on ++ //additional "expose-event" events we can re-render the missing pieces ++ // ++ //Under gtk3 we have to keep our own buffer up to date and flush it into ++ //the given cairo context on "draw". So we emit a paint event on ++ //opportune resize trigger events to initially fill our backbuffer and then ++ //keep it up to date with our direct paints and tell gtk those regions ++ //have changed and then blit them into the provided cairo context when ++ //we get the "draw" ++ // ++ //The other alternative was to always paint everything on "draw", but ++ //that duplicates the amount of drawing and is hideously slow ++ SAL_INFO("vcl.gtk3", "force painting" << 0 << "," << 0 << " " << maGeometry.nWidth << "x" << maGeometry.nHeight); ++ SalPaintEvent aPaintEvt(0, 0, maGeometry.nWidth, maGeometry.nHeight, true); ++ CallCallback(SALEVENT_PAINT, &aPaintEvt); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pFixedContainer)); ++} ++ ++gboolean GtkSalFrame::signalFocus( GtkWidget*, GdkEventFocus* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ SalGenericInstance *pSalInstance = ++ static_cast< SalGenericInstance* >(GetSalData()->m_pInstance); ++ ++ // check if printers have changed (analogous to salframe focus handler) ++ pSalInstance->updatePrinterUpdate(); ++ ++ if( !pEvent->in ) ++ { ++ pThis->m_nKeyModifiers = 0; ++ pThis->m_bSendModChangeOnRelease = false; ++ } ++ ++ if( pThis->m_pIMHandler ) ++ pThis->m_pIMHandler->focusChanged( pEvent->in ); ++ ++ // ask for changed printers like generic implementation ++ if( pEvent->in && pSalInstance->isPrinterInit() ) ++ pSalInstance->updatePrinterUpdate(); ++ ++ // FIXME: find out who the hell steals the focus from our frame ++ // while we have the pointer grabbed, this should not come from ++ // the window manager. Is this an event that was still queued ? ++ // The focus does not seem to get set inside our process ++ ++ // in the meantime do not propagate focus get/lose if floats are open ++ if( m_nFloats == 0 ) ++ pThis->CallCallback( pEvent->in ? SALEVENT_GETFOCUS : SALEVENT_LOSEFOCUS, NULL ); ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalMap( GtkWidget *pWidget, GdkEvent*, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ bool bSetFocus = pThis->m_bSetFocusOnMap; ++ pThis->m_bSetFocusOnMap = false; ++ ++ (void)pWidget; (void)bSetFocus; ++ //FIXME: no set input focus ... ++ ++ pThis->CallCallback( SALEVENT_RESIZE, NULL ); ++ pThis->TriggerPaintEvent(); ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalUnmap( GtkWidget*, GdkEvent*, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ pThis->CallCallback( SALEVENT_RESIZE, NULL ); ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalKey( GtkWidget*, GdkEventKey* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ vcl::DeletionListener aDel( pThis ); ++ ++ if( pThis->m_pIMHandler ) ++ { ++ if( pThis->m_pIMHandler->handleKeyEvent( pEvent ) ) ++ return true; ++ } ++ ++ // handle modifiers ++ if( pEvent->keyval == GDK_Shift_L || pEvent->keyval == GDK_Shift_R || ++ pEvent->keyval == GDK_Control_L || pEvent->keyval == GDK_Control_R || ++ pEvent->keyval == GDK_Alt_L || pEvent->keyval == GDK_Alt_R || ++ pEvent->keyval == GDK_Meta_L || pEvent->keyval == GDK_Meta_R || ++ pEvent->keyval == GDK_Super_L || pEvent->keyval == GDK_Super_R ) ++ { ++ SalKeyModEvent aModEvt; ++ ++ sal_uInt16 nModCode = GetKeyModCode( pEvent->state ); ++ ++ aModEvt.mnModKeyCode = 0; // emit no MODKEYCHANGE events ++ if( pEvent->type == GDK_KEY_PRESS && !pThis->m_nKeyModifiers ) ++ pThis->m_bSendModChangeOnRelease = true; ++ ++ else if( pEvent->type == GDK_KEY_RELEASE && ++ pThis->m_bSendModChangeOnRelease ) ++ { ++ aModEvt.mnModKeyCode = pThis->m_nKeyModifiers; ++ pThis->m_nKeyModifiers = 0; ++ } ++ ++ sal_uInt16 nExtModMask = 0; ++ sal_uInt16 nModMask = 0; ++ // pressing just the ctrl key leads to a keysym of XK_Control but ++ // the event state does not contain ControlMask. In the release ++ // event its the other way round: it does contain the Control mask. ++ // The modifier mode therefore has to be adapted manually. ++ switch( pEvent->keyval ) ++ { ++ case GDK_Control_L: ++ nExtModMask = MODKEY_LMOD1; ++ nModMask = KEY_MOD1; ++ break; ++ case GDK_Control_R: ++ nExtModMask = MODKEY_RMOD1; ++ nModMask = KEY_MOD1; ++ break; ++ case GDK_Alt_L: ++ nExtModMask = MODKEY_LMOD2; ++ nModMask = KEY_MOD2; ++ break; ++ case GDK_Alt_R: ++ nExtModMask = MODKEY_RMOD2; ++ nModMask = KEY_MOD2; ++ break; ++ case GDK_Shift_L: ++ nExtModMask = MODKEY_LSHIFT; ++ nModMask = KEY_SHIFT; ++ break; ++ case GDK_Shift_R: ++ nExtModMask = MODKEY_RSHIFT; ++ nModMask = KEY_SHIFT; ++ break; ++ // Map Meta/Super to MOD3 modifier on all Unix systems ++ // except Mac OS X ++ case GDK_Meta_L: ++ case GDK_Super_L: ++ nExtModMask = MODKEY_LMOD3; ++ nModMask = KEY_MOD3; ++ break; ++ case GDK_Meta_R: ++ case GDK_Super_R: ++ nExtModMask = MODKEY_RMOD3; ++ nModMask = KEY_MOD3; ++ break; ++ } ++ if( pEvent->type == GDK_KEY_RELEASE ) ++ { ++ nModCode &= ~nModMask; ++ pThis->m_nKeyModifiers &= ~nExtModMask; ++ } ++ else ++ { ++ nModCode |= nModMask; ++ pThis->m_nKeyModifiers |= nExtModMask; ++ } ++ ++ aModEvt.mnCode = nModCode; ++ aModEvt.mnTime = pEvent->time; ++ ++ pThis->CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt ); ++ ++ } ++ else ++ { ++ pThis->doKeyCallback( pEvent->state, ++ pEvent->keyval, ++ pEvent->hardware_keycode, ++ pEvent->group, ++ pEvent->time, ++ sal_Unicode(gdk_keyval_to_unicode( pEvent->keyval )), ++ (pEvent->type == GDK_KEY_PRESS), ++ false ); ++ if( ! aDel.isDeleted() ) ++ pThis->m_bSendModChangeOnRelease = false; ++ } ++ ++ if( !aDel.isDeleted() && pThis->m_pIMHandler ) ++ pThis->m_pIMHandler->updateIMSpotLocation(); ++ ++ return true; ++} ++ ++gboolean GtkSalFrame::signalDelete( GtkWidget*, GdkEvent*, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ pThis->CallCallback( SALEVENT_CLOSE, NULL ); ++ ++ return true; ++} ++ ++void GtkSalFrame::signalStyleSet( GtkWidget*, GtkStyle* pPrevious, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ ++ // every frame gets an initial style set on creation ++ // do not post these as the whole application tends to ++ // redraw itself to adjust to the new style ++ // where there IS no new style resulting in tremendous unnecessary flickering ++ if( pPrevious != NULL ) ++ { ++ // signalStyleSet does NOT usually have the gdk lock ++ // so post user event to safely dispatch the SALEVENT_SETTINGSCHANGED ++ // note: settings changed for multiple frames is avoided in winproc.cxx ImplHandleSettings ++ GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_SETTINGSCHANGED ); ++ GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_FONTCHANGED ); ++ } ++} ++ ++gboolean GtkSalFrame::signalWindowState( GtkWidget*, GdkEvent* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ if( (pThis->m_nState & GDK_WINDOW_STATE_ICONIFIED) != (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_ICONIFIED ) ) ++ { ++ GtkSalFrame::getDisplay()->SendInternalEvent( pThis, NULL, SALEVENT_RESIZE ); ++ pThis->TriggerPaintEvent(); ++ } ++ ++ if( (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_MAXIMIZED) && ++ ! (pThis->m_nState & GDK_WINDOW_STATE_MAXIMIZED) ) ++ { ++ pThis->m_aRestorePosSize = ++ Rectangle( Point( pThis->maGeometry.nX, pThis->maGeometry.nY ), ++ Size( pThis->maGeometry.nWidth, pThis->maGeometry.nHeight ) ); ++ } ++ pThis->m_nState = pEvent->window_state.new_window_state; ++ ++ #if OSL_DEBUG_LEVEL > 1 ++ if( (pEvent->window_state.changed_mask & GDK_WINDOW_STATE_FULLSCREEN) ) ++ { ++ fprintf( stderr, "window %p %s full screen state\n", ++ pThis, ++ (pEvent->window_state.new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? "enters" : "leaves"); ++ } ++ #endif ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::signalVisibility( GtkWidget*, GdkEventVisibility* pEvent, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ pThis->m_nVisibility = pEvent->state; ++ return true; ++} ++ ++void GtkSalFrame::signalDestroy( GtkWidget* pObj, gpointer frame ) ++{ ++ GtkSalFrame* pThis = static_cast(frame); ++ if( pObj == pThis->m_pWindow ) ++ { ++ pThis->m_pFixedContainer = NULL; ++ pThis->m_pEventBox = NULL; ++ pThis->m_pWindow = NULL; ++ pThis->InvalidateGraphics(); ++ } ++} ++ ++// GtkSalFrame::IMHandler ++ ++GtkSalFrame::IMHandler::IMHandler( GtkSalFrame* pFrame ) ++: m_pFrame(pFrame), ++ m_nPrevKeyPresses( 0 ), ++ m_pIMContext( NULL ), ++ m_bFocused( true ), ++ m_bPreeditJustChanged( false ) ++{ ++ m_aInputEvent.mpTextAttr = NULL; ++ createIMContext(); ++} ++ ++GtkSalFrame::IMHandler::~IMHandler() ++{ ++ // cancel an eventual event posted to begin preedit again ++ GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ deleteIMContext(); ++} ++ ++void GtkSalFrame::IMHandler::createIMContext() ++{ ++ if( ! m_pIMContext ) ++ { ++ m_pIMContext = gtk_im_multicontext_new (); ++ g_signal_connect( m_pIMContext, "commit", ++ G_CALLBACK (signalIMCommit), this ); ++ g_signal_connect( m_pIMContext, "preedit_changed", ++ G_CALLBACK (signalIMPreeditChanged), this ); ++ g_signal_connect( m_pIMContext, "retrieve_surrounding", ++ G_CALLBACK (signalIMRetrieveSurrounding), this ); ++ g_signal_connect( m_pIMContext, "delete_surrounding", ++ G_CALLBACK (signalIMDeleteSurrounding), this ); ++ g_signal_connect( m_pIMContext, "preedit_start", ++ G_CALLBACK (signalIMPreeditStart), this ); ++ g_signal_connect( m_pIMContext, "preedit_end", ++ G_CALLBACK (signalIMPreeditEnd), this ); ++ ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_set_client_window( m_pIMContext, widget_get_window(GTK_WIDGET(m_pFrame->m_pWindow)) ); ++ gtk_im_context_focus_in( m_pIMContext ); ++ GetGenericData()->ErrorTrapPop(); ++ m_bFocused = true; ++ } ++} ++ ++void GtkSalFrame::IMHandler::deleteIMContext() ++{ ++ if( m_pIMContext ) ++ { ++ // first give IC a chance to deinitialize ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_set_client_window( m_pIMContext, NULL ); ++ GetGenericData()->ErrorTrapPop(); ++ // destroy old IC ++ g_object_unref( m_pIMContext ); ++ m_pIMContext = NULL; ++ } ++} ++ ++void GtkSalFrame::IMHandler::doCallEndExtTextInput() ++{ ++ m_aInputEvent.mpTextAttr = NULL; ++ m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); ++} ++ ++void GtkSalFrame::IMHandler::updateIMSpotLocation() ++{ ++ SalExtTextInputPosEvent aPosEvent; ++ m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUTPOS, (void*)&aPosEvent ); ++ GdkRectangle aArea; ++ aArea.x = aPosEvent.mnX; ++ aArea.y = aPosEvent.mnY; ++ aArea.width = aPosEvent.mnWidth; ++ aArea.height = aPosEvent.mnHeight; ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_set_cursor_location( m_pIMContext, &aArea ); ++ GetGenericData()->ErrorTrapPop(); ++} ++ ++void GtkSalFrame::IMHandler::sendEmptyCommit() ++{ ++ vcl::DeletionListener aDel( m_pFrame ); ++ ++ SalExtTextInputEvent aEmptyEv; ++ aEmptyEv.mnTime = 0; ++ aEmptyEv.mpTextAttr = 0; ++ aEmptyEv.maText.clear(); ++ aEmptyEv.mnCursorPos = 0; ++ aEmptyEv.mnCursorFlags = 0; ++ aEmptyEv.mbOnlyCursor = False; ++ m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&aEmptyEv ); ++ if( ! aDel.isDeleted() ) ++ m_pFrame->CallCallback( SALEVENT_ENDEXTTEXTINPUT, NULL ); ++} ++ ++void GtkSalFrame::IMHandler::endExtTextInput( sal_uInt16 /*nFlags*/ ) ++{ ++ gtk_im_context_reset ( m_pIMContext ); ++ ++ if( m_aInputEvent.mpTextAttr ) ++ { ++ vcl::DeletionListener aDel( m_pFrame ); ++ // delete preedit in sal (commit an empty string) ++ sendEmptyCommit(); ++ if( ! aDel.isDeleted() ) ++ { ++ // mark previous preedit state again (will e.g. be sent at focus gain) ++ m_aInputEvent.mpTextAttr = &m_aInputFlags[0]; ++ if( m_bFocused ) ++ { ++ // begin preedit again ++ GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ } ++ } ++ } ++} ++ ++void GtkSalFrame::IMHandler::focusChanged( bool bFocusIn ) ++{ ++ m_bFocused = bFocusIn; ++ if( bFocusIn ) ++ { ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_focus_in( m_pIMContext ); ++ GetGenericData()->ErrorTrapPop(); ++ if( m_aInputEvent.mpTextAttr ) ++ { ++ sendEmptyCommit(); ++ // begin preedit again ++ GtkSalFrame::getDisplay()->SendInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ } ++ } ++ else ++ { ++ GetGenericData()->ErrorTrapPush(); ++ gtk_im_context_focus_out( m_pIMContext ); ++ GetGenericData()->ErrorTrapPop(); ++ // cancel an eventual event posted to begin preedit again ++ GtkSalFrame::getDisplay()->CancelInternalEvent( m_pFrame, &m_aInputEvent, SALEVENT_EXTTEXTINPUT ); ++ } ++} ++ ++bool GtkSalFrame::IMHandler::handleKeyEvent( GdkEventKey* pEvent ) ++{ ++ vcl::DeletionListener aDel( m_pFrame ); ++ ++ if( pEvent->type == GDK_KEY_PRESS ) ++ { ++ // Add this key press event to the list of previous key presses ++ // to which we compare key release events. If a later key release ++ // event has a matching key press event in this list, we swallow ++ // the key release because some GTK Input Methods don't swallow it ++ // for us. ++ m_aPrevKeyPresses.push_back( PreviousKeyPress(pEvent) ); ++ m_nPrevKeyPresses++; ++ ++ // Also pop off the earliest key press event if there are more than 10 ++ // already. ++ while (m_nPrevKeyPresses > 10) ++ { ++ m_aPrevKeyPresses.pop_front(); ++ m_nPrevKeyPresses--; ++ } ++ ++ GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); ++ ++ // #i51353# update spot location on every key input since we cannot ++ // know which key may activate a preedit choice window ++ updateIMSpotLocation(); ++ if( aDel.isDeleted() ) ++ return true; ++ ++ gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); ++ g_object_unref( pRef ); ++ ++ if( aDel.isDeleted() ) ++ return true; ++ ++ m_bPreeditJustChanged = false; ++ ++ if( bResult ) ++ return true; ++ else ++ { ++ DBG_ASSERT( m_nPrevKeyPresses > 0, "key press has vanished !" ); ++ if( ! m_aPrevKeyPresses.empty() ) // sanity check ++ { ++ // event was not swallowed, do not filter a following ++ // key release event ++ // note: this relies on gtk_im_context_filter_keypress ++ // returning without calling a handler (in the "not swallowed" ++ // case ) which might change the previous key press list so ++ // we would pop the wrong event here ++ m_aPrevKeyPresses.pop_back(); ++ m_nPrevKeyPresses--; ++ } ++ } ++ } ++ ++ // Determine if we got an earlier key press event corresponding to this key release ++ if (pEvent->type == GDK_KEY_RELEASE) ++ { ++ GObject* pRef = G_OBJECT( g_object_ref( G_OBJECT( m_pIMContext ) ) ); ++ gboolean bResult = gtk_im_context_filter_keypress( m_pIMContext, pEvent ); ++ g_object_unref( pRef ); ++ ++ if( aDel.isDeleted() ) ++ return true; ++ ++ m_bPreeditJustChanged = false; ++ ++ std::list::iterator iter = m_aPrevKeyPresses.begin(); ++ std::list::iterator iter_end = m_aPrevKeyPresses.end(); ++ while (iter != iter_end) ++ { ++ // If we found a corresponding previous key press event, swallow the release ++ // and remove the earlier key press from our list ++ if (*iter == pEvent) ++ { ++ m_aPrevKeyPresses.erase(iter); ++ m_nPrevKeyPresses--; ++ return true; ++ } ++ ++iter; ++ } ++ ++ if( bResult ) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* FIXME: ++* #122282# still more hacking: some IMEs never start a preedit but simply commit ++* in this case we cannot commit a single character. Workaround: do not do the ++* single key hack for enter or space if the unicode committed does not match ++*/ ++ ++static bool checkSingleKeyCommitHack( guint keyval, sal_Unicode cCode ) ++{ ++ bool bRet = true; ++ switch( keyval ) ++ { ++ case GDK_KP_Enter: ++ case GDK_Return: ++ if( cCode != '\n' && cCode != '\r' ) ++ bRet = false; ++ break; ++ case GDK_space: ++ case GDK_KP_Space: ++ if( cCode != ' ' ) ++ bRet = false; ++ break; ++ default: ++ break; ++ } ++ return bRet; ++} ++ ++void GtkSalFrame::IMHandler::signalIMCommit( GtkIMContext* pContext, gchar* pText, gpointer im_handler ) ++{ ++ GtkSalFrame::IMHandler* pThis = static_cast(im_handler); ++ ++ SolarMutexGuard aGuard; ++ vcl::DeletionListener aDel( pThis->m_pFrame ); ++ { ++ const bool bWasPreedit = ++ (pThis->m_aInputEvent.mpTextAttr != 0) || ++ pThis->m_bPreeditJustChanged; ++ ++ pThis->m_aInputEvent.mnTime = 0; ++ pThis->m_aInputEvent.mpTextAttr = 0; ++ pThis->m_aInputEvent.maText = OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ); ++ pThis->m_aInputEvent.mnCursorPos = pThis->m_aInputEvent.maText.getLength(); ++ pThis->m_aInputEvent.mnCursorFlags = 0; ++ pThis->m_aInputEvent.mbOnlyCursor = False; ++ ++ pThis->m_aInputFlags.clear(); ++ ++ /* necessary HACK: all keyboard input comes in here as soon as a IMContext is set ++ * which is logical and consequent. But since even simple input like ++ * comes through the commit signal instead of signalKey ++ * and all kinds of windows only implement KeyInput (e.g. PushButtons, ++ * RadioButtons and a lot of other Controls), will send a single ++ * KeyInput/KeyUp sequence instead of an ExtText event if there ++ * never was a preedit and the text is only one character. ++ * ++ * In this case there the last ExtText event must have been ++ * SALEVENT_ENDEXTTEXTINPUT, either because of a regular commit ++ * or because there never was a preedit. ++ */ ++ bool bSingleCommit = false; ++ if( ! bWasPreedit ++ && pThis->m_aInputEvent.maText.getLength() == 1 ++ && ! pThis->m_aPrevKeyPresses.empty() ++ ) ++ { ++ const PreviousKeyPress& rKP = pThis->m_aPrevKeyPresses.back(); ++ sal_Unicode aOrigCode = pThis->m_aInputEvent.maText[0]; ++ ++ if( checkSingleKeyCommitHack( rKP.keyval, aOrigCode ) ) ++ { ++ pThis->m_pFrame->doKeyCallback( rKP.state, rKP.keyval, rKP.hardware_keycode, rKP.group, rKP.time, aOrigCode, true, true ); ++ bSingleCommit = true; ++ } ++ } ++ if( ! bSingleCommit ) ++ { ++ pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); ++ if( ! aDel.isDeleted() ) ++ pThis->doCallEndExtTextInput(); ++ } ++ if( ! aDel.isDeleted() ) ++ { ++ // reset input event ++ pThis->m_aInputEvent.maText.clear(); ++ pThis->m_aInputEvent.mnCursorPos = 0; ++ pThis->updateIMSpotLocation(); ++ } ++ } ++#ifdef SOLARIS ++ // #i51356# workaround a solaris IIIMP bug ++ // in case of partial commits the preedit changed signal ++ // and commit signal come in wrong order ++ if( ! aDel.isDeleted() ) ++ signalIMPreeditChanged( pContext, im_handler ); ++#else ++ (void) pContext; ++#endif ++} ++ ++void GtkSalFrame::IMHandler::signalIMPreeditChanged( GtkIMContext*, gpointer im_handler ) ++{ ++ GtkSalFrame::IMHandler* pThis = static_cast(im_handler); ++ ++ char* pText = NULL; ++ PangoAttrList* pAttrs = NULL; ++ gint nCursorPos = 0; ++ ++ gtk_im_context_get_preedit_string( pThis->m_pIMContext, ++ &pText, ++ &pAttrs, ++ &nCursorPos ); ++ if( pText && ! *pText ) // empty string ++ { ++ // change from nothing to nothing -> do not start preedit ++ // e.g. this will activate input into a calc cell without ++ // user input ++ if( pThis->m_aInputEvent.maText.getLength() == 0 ) ++ { ++ g_free( pText ); ++ pango_attr_list_unref( pAttrs ); ++ return; ++ } ++ } ++ ++ pThis->m_bPreeditJustChanged = true; ++ ++ bool bEndPreedit = (!pText || !*pText) && pThis->m_aInputEvent.mpTextAttr != NULL; ++ pThis->m_aInputEvent.mnTime = 0; ++ pThis->m_aInputEvent.maText = pText ? OUString( pText, strlen(pText), RTL_TEXTENCODING_UTF8 ) : OUString(); ++ pThis->m_aInputEvent.mnCursorPos = nCursorPos; ++ pThis->m_aInputEvent.mnCursorFlags = 0; ++ pThis->m_aInputEvent.mbOnlyCursor = False; ++ ++ pThis->m_aInputFlags = std::vector( std::max( 1, (int)pThis->m_aInputEvent.maText.getLength() ), 0 ); ++ ++ PangoAttrIterator *iter = pango_attr_list_get_iterator(pAttrs); ++ do ++ { ++ GSList *attr_list = NULL; ++ GSList *tmp_list = NULL; ++ gint start, end; ++ guint sal_attr = 0; ++ ++ pango_attr_iterator_range (iter, &start, &end); ++ if (end == G_MAXINT) ++ end = pText ? strlen (pText) : 0; ++ if (end == start) ++ continue; ++ ++ start = g_utf8_pointer_to_offset (pText, pText + start); ++ end = g_utf8_pointer_to_offset (pText, pText + end); ++ ++ tmp_list = attr_list = pango_attr_iterator_get_attrs (iter); ++ while (tmp_list) ++ { ++ PangoAttribute *pango_attr = static_cast(tmp_list->data); ++ ++ switch (pango_attr->klass->type) ++ { ++ case PANGO_ATTR_BACKGROUND: ++ sal_attr |= (EXTTEXTINPUT_ATTR_HIGHLIGHT | EXTTEXTINPUT_CURSOR_INVISIBLE); ++ break; ++ case PANGO_ATTR_UNDERLINE: ++ sal_attr |= EXTTEXTINPUT_ATTR_UNDERLINE; ++ break; ++ case PANGO_ATTR_STRIKETHROUGH: ++ sal_attr |= EXTTEXTINPUT_ATTR_REDTEXT; ++ break; ++ default: ++ break; ++ } ++ pango_attribute_destroy (pango_attr); ++ tmp_list = tmp_list->next; ++ } ++ if (sal_attr == 0) ++ sal_attr |= EXTTEXTINPUT_ATTR_UNDERLINE; ++ g_slist_free (attr_list); ++ ++ // Set the sal attributes on our text ++ for (int i = start; i < end; ++i) ++ { ++ SAL_WARN_IF(i >= static_cast(pThis->m_aInputFlags.size()), ++ "vcl.gtk", "pango attrib out of range. Broken range: " ++ << start << "," << end << " Legal range: 0," ++ << pThis->m_aInputFlags.size()); ++ if (i >= static_cast(pThis->m_aInputFlags.size())) ++ continue; ++ pThis->m_aInputFlags[i] |= sal_attr; ++ } ++ } while (pango_attr_iterator_next (iter)); ++ pango_attr_iterator_destroy(iter); ++ ++ pThis->m_aInputEvent.mpTextAttr = &pThis->m_aInputFlags[0]; ++ ++ g_free( pText ); ++ pango_attr_list_unref( pAttrs ); ++ ++ SolarMutexGuard aGuard; ++ vcl::DeletionListener aDel( pThis->m_pFrame ); ++ ++ pThis->m_pFrame->CallCallback( SALEVENT_EXTTEXTINPUT, (void*)&pThis->m_aInputEvent); ++ if( bEndPreedit && ! aDel.isDeleted() ) ++ pThis->doCallEndExtTextInput(); ++ if( ! aDel.isDeleted() ) ++ pThis->updateIMSpotLocation(); ++} ++ ++void GtkSalFrame::IMHandler::signalIMPreeditStart( GtkIMContext*, gpointer /*im_handler*/ ) ++{ ++} ++ ++void GtkSalFrame::IMHandler::signalIMPreeditEnd( GtkIMContext*, gpointer im_handler ) ++{ ++ GtkSalFrame::IMHandler* pThis = static_cast(im_handler); ++ ++ pThis->m_bPreeditJustChanged = true; ++ ++ SolarMutexGuard aGuard; ++ vcl::DeletionListener aDel( pThis->m_pFrame ); ++ pThis->doCallEndExtTextInput(); ++ if( ! aDel.isDeleted() ) ++ pThis->updateIMSpotLocation(); ++} ++ ++uno::Reference ++ FindFocus(uno::Reference< accessibility::XAccessibleContext > xContext) ++{ ++ if (!xContext.is()) ++ uno::Reference< accessibility::XAccessibleEditableText >(); ++ ++ uno::Reference xState = xContext->getAccessibleStateSet(); ++ if (xState.is()) ++ { ++ if (xState->contains(accessibility::AccessibleStateType::FOCUSED)) ++ return uno::Reference(xContext, uno::UNO_QUERY); ++ } ++ ++ for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i) ++ { ++ uno::Reference< accessibility::XAccessible > xChild = xContext->getAccessibleChild(i); ++ if (!xChild.is()) ++ continue; ++ uno::Reference< accessibility::XAccessibleContext > xChildContext = xChild->getAccessibleContext(); ++ if (!xChildContext.is()) ++ continue; ++ uno::Reference< accessibility::XAccessibleEditableText > xText = FindFocus(xChildContext); ++ if (xText.is()) ++ return xText; ++ } ++ return uno::Reference< accessibility::XAccessibleEditableText >(); ++} ++ ++static uno::Reference lcl_GetxText(vcl::Window *pFocusWin) ++{ ++ uno::Reference xText; ++ try ++ { ++ uno::Reference< accessibility::XAccessible > xAccessible( pFocusWin->GetAccessible( true ) ); ++ if (xAccessible.is()) ++ xText = FindFocus(xAccessible->getAccessibleContext()); ++ } ++ catch(const uno::Exception& e) ++ { ++ SAL_WARN( "vcl.gtk", "Exception in getting input method surrounding text: " << e.Message); ++ } ++ return xText; ++} ++ ++gboolean GtkSalFrame::IMHandler::signalIMRetrieveSurrounding( GtkIMContext* pContext, gpointer /*im_handler*/ ) ++{ ++ vcl::Window *pFocusWin = Application::GetFocusWindow(); ++ if (!pFocusWin) ++ return true; ++ ++ uno::Reference xText = lcl_GetxText(pFocusWin); ++ if (xText.is()) ++ { ++ sal_Int32 nPosition = xText->getCaretPosition(); ++ OUString sAllText = xText->getText(); ++ OString sUTF = OUStringToOString(sAllText, RTL_TEXTENCODING_UTF8); ++ OUString sCursorText(sAllText.copy(0, nPosition)); ++ gtk_im_context_set_surrounding(pContext, sUTF.getStr(), sUTF.getLength(), ++ OUStringToOString(sCursorText, RTL_TEXTENCODING_UTF8).getLength()); ++ return true; ++ } ++ ++ return false; ++} ++ ++gboolean GtkSalFrame::IMHandler::signalIMDeleteSurrounding( GtkIMContext*, gint offset, gint nchars, ++ gpointer /*im_handler*/ ) ++{ ++ vcl::Window *pFocusWin = Application::GetFocusWindow(); ++ if (!pFocusWin) ++ return true; ++ ++ uno::Reference xText = lcl_GetxText(pFocusWin); ++ if (xText.is()) ++ { ++ sal_Int32 nPosition = xText->getCaretPosition(); ++ // #i111768# range checking ++ sal_Int32 nDeletePos = nPosition + offset; ++ sal_Int32 nDeleteEnd = nDeletePos + nchars; ++ if (nDeletePos < 0) ++ nDeletePos = 0; ++ if (nDeleteEnd < 0) ++ nDeleteEnd = 0; ++ if (nDeleteEnd > xText->getCharacterCount()) ++ nDeleteEnd = xText->getCharacterCount(); ++ ++ xText->deleteText(nDeletePos, nDeleteEnd); ++ //tdf91641 adjust cursor if deleted chars shift it forward (normal case) ++ if (nDeletePos < nPosition) ++ { ++ if (nDeleteEnd <= nPosition) ++ nPosition = nPosition - (nDeleteEnd - nDeletePos); ++ else ++ nPosition = nDeletePos; ++ ++ if (xText->getCharacterCount() >= nPosition) ++ xText->setCaretPosition( nPosition ); ++ } ++ return true; ++ } ++ ++ return false; ++} ++ ++Size GtkSalDisplay::GetScreenSize( int nDisplayScreen ) ++{ ++ Rectangle aRect = m_pSys->GetDisplayScreenPosSizePixel( nDisplayScreen ); ++ return Size( aRect.GetWidth(), aRect.GetHeight() ); ++} ++ ++Window GtkSalFrame::GetX11Window() ++{ ++ return widget_get_xid(m_pWindow); ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx +new file mode 100644 +index 0000000..5716058 +--- /dev/null ++++ b/vcl/unx/gtk3/gtk3gtkinst.cxx +@@ -0,0 +1,641 @@ ++/* -*- 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 "../../gtk/app/gtkinst.cxx" ++ ++#include ++#include "com/sun/star/lang/XServiceInfo.hpp" ++#include "com/sun/star/lang/XSingleServiceFactory.hpp" ++#include "com/sun/star/lang/XInitialization.hpp" ++#include "com/sun/star/lang/DisposedException.hpp" ++#include "com/sun/star/datatransfer/XTransferable.hpp" ++#include "com/sun/star/datatransfer/clipboard/XClipboard.hpp" ++#include "com/sun/star/datatransfer/clipboard/XClipboardEx.hpp" ++#include "com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp" ++#include "com/sun/star/datatransfer/clipboard/XClipboardListener.hpp" ++#include "com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp" ++#include "com/sun/star/datatransfer/dnd/XDragSource.hpp" ++#include "com/sun/star/datatransfer/dnd/XDropTarget.hpp" ++#include "com/sun/star/datatransfer/dnd/DNDConstants.hpp" ++#include ++#include ++#include "cppuhelper/compbase.hxx" ++#include "cppuhelper/implbase1.hxx" ++#include ++ ++using namespace com::sun::star; ++using namespace com::sun::star::uno; ++using namespace com::sun::star::lang; ++ ++namespace ++{ ++ struct TypeEntry ++ { ++ const char* pNativeType; // string corresponding to nAtom for the case of nAtom being uninitialized ++ const char* pType; // Mime encoding on our side ++ }; ++ ++ static TypeEntry aConversionTab[] = ++ { ++ { "ISO10646-1", "text/plain;charset=utf-16" }, ++ { "UTF8_STRING", "text/plain;charset=utf-8" }, ++ { "UTF-8", "text/plain;charset=utf-8" }, ++ { "text/plain;charset=UTF-8", "text/plain;charset=utf-8" }, ++ // ISO encodings ++ { "ISO8859-2", "text/plain;charset=iso8859-2" }, ++ { "ISO8859-3", "text/plain;charset=iso8859-3" }, ++ { "ISO8859-4", "text/plain;charset=iso8859-4" }, ++ { "ISO8859-5", "text/plain;charset=iso8859-5" }, ++ { "ISO8859-6", "text/plain;charset=iso8859-6" }, ++ { "ISO8859-7", "text/plain;charset=iso8859-7" }, ++ { "ISO8859-8", "text/plain;charset=iso8859-8" }, ++ { "ISO8859-9", "text/plain;charset=iso8859-9" }, ++ { "ISO8859-10", "text/plain;charset=iso8859-10" }, ++ { "ISO8859-13", "text/plain;charset=iso8859-13" }, ++ { "ISO8859-14", "text/plain;charset=iso8859-14" }, ++ { "ISO8859-15", "text/plain;charset=iso8859-15" }, ++ // asian encodings ++ { "JISX0201.1976-0", "text/plain;charset=jisx0201.1976-0" }, ++ { "JISX0208.1983-0", "text/plain;charset=jisx0208.1983-0" }, ++ { "JISX0208.1990-0", "text/plain;charset=jisx0208.1990-0" }, ++ { "JISX0212.1990-0", "text/plain;charset=jisx0212.1990-0" }, ++ { "GB2312.1980-0", "text/plain;charset=gb2312.1980-0" }, ++ { "KSC5601.1992-0", "text/plain;charset=ksc5601.1992-0" }, ++ // eastern european encodings ++ { "KOI8-R", "text/plain;charset=koi8-r" }, ++ { "KOI8-U", "text/plain;charset=koi8-u" }, ++ // String (== iso8859-1) ++ { "STRING", "text/plain;charset=iso8859-1" }, ++ // special for compound text ++ { "COMPOUND_TEXT", "text/plain;charset=compound_text" }, ++ ++ // PIXMAP ++ { "PIXMAP", "image/bmp" } ++ }; ++ ++ class DataFlavorEq : public std::unary_function ++ { ++ private: ++ const css::datatransfer::DataFlavor& m_rData; ++ public: ++ explicit DataFlavorEq(const css::datatransfer::DataFlavor& rData) : m_rData(rData) {} ++ bool operator() (const css::datatransfer::DataFlavor& rData) const ++ { ++ return rData.MimeType == m_rData.MimeType && ++ rData.DataType == m_rData.DataType; ++ } ++ }; ++} ++ ++class GtkTransferable : public ::cppu::WeakImplHelper1 < ++ css::datatransfer::XTransferable > ++{ ++private: ++ GdkAtom m_nSelection; ++ std::map m_aMimeTypeToAtom; ++public: ++ ++ GtkTransferable(GdkAtom nSelection) ++ : m_nSelection(nSelection) ++ { ++ } ++ ++ /* ++ * XTransferable ++ */ ++ ++ virtual css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor& rFlavor) ++ throw(css::datatransfer::UnsupportedFlavorException, ++ css::io::IOException, ++ css::uno::RuntimeException, std::exception ++ ) SAL_OVERRIDE ++ { ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ if (rFlavor.MimeType == "text/plain;charset=utf-16") ++ { ++ OUString aStr; ++ gchar *pText = gtk_clipboard_wait_for_text(clipboard); ++ if (pText) ++ aStr = OUString(pText, rtl_str_getLength(pText), RTL_TEXTENCODING_UTF8); ++ g_free(pText); ++ css::uno::Any aRet; ++ aRet <<= aStr.replaceAll("\r\n", "\n"); ++ return aRet; ++ } ++ ++ auto it = m_aMimeTypeToAtom.find(rFlavor.MimeType); ++ if (it == m_aMimeTypeToAtom.end()) ++ return css::uno::Any(); ++ ++ css::uno::Any aRet; ++ GtkSelectionData* data = gtk_clipboard_wait_for_contents(clipboard, ++ it->second); ++ gint length; ++ const guchar *rawdata = gtk_selection_data_get_data_with_length(data, ++ &length); ++ Sequence aSeq(reinterpret_cast(rawdata), length); ++ gtk_selection_data_free(data); ++ aRet <<= aSeq; ++ return aRet; ++ } ++ ++ std::vector getTransferDataFlavorsAsVector() ++ { ++ std::vector aVector; ++ ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ ++ GdkAtom *targets; ++ gint n_targets; ++ if (gtk_clipboard_wait_for_targets(clipboard, &targets, &n_targets)) ++ { ++ bool bHaveText = false, bHaveUTF16 = false; ++ ++ for (gint i = 0; i < n_targets; ++i) ++ { ++ gchar* pName = gdk_atom_name(targets[i]); ++ const char* pFinalName = pName; ++ css::datatransfer::DataFlavor aFlavor; ++ ++ for (size_t j = 0; j < SAL_N_ELEMENTS(aConversionTab); ++j) ++ { ++ if (rtl_str_compare(pName, aConversionTab[j].pNativeType) == 0) ++ { ++ pFinalName = aConversionTab[j].pType; ++ break; ++ } ++ } ++ ++ aFlavor.MimeType = OUString(pFinalName, ++ rtl_str_getLength(pFinalName), ++ RTL_TEXTENCODING_UTF8); ++ ++ m_aMimeTypeToAtom[aFlavor.MimeType] = targets[i]; ++ ++ aFlavor.DataType = cppu::UnoType>::get(); ++ ++ sal_Int32 nIndex(0); ++ if (aFlavor.MimeType.getToken(0, ';', nIndex) == "text/plain") ++ { ++ bHaveText = true; ++ OUString aToken(aFlavor.MimeType.getToken(0, ';', nIndex)); ++ if (aToken == "charset=utf-16") ++ { ++ bHaveUTF16 = true; ++ aFlavor.DataType = cppu::UnoType::get(); ++ } ++ } ++ aVector.push_back(aFlavor); ++ g_free(pName); ++ } ++ ++ g_free(targets); ++ ++ //If we have text, but no UTF-16 format which is basically the only ++ //text-format LibreOffice supports for cnp then claim we do and we ++ //will convert on demand ++ if (bHaveText && !bHaveUTF16) ++ { ++ css::datatransfer::DataFlavor aFlavor; ++ aFlavor.MimeType = "text/plain;charset=utf-16"; ++ aFlavor.DataType = cppu::UnoType::get(); ++ aVector.push_back(aFlavor); ++ } ++ } ++ ++ return aVector; ++ } ++ ++ virtual css::uno::Sequence SAL_CALL getTransferDataFlavors() ++ throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE ++ { ++ return comphelper::containerToSequence(getTransferDataFlavorsAsVector()); ++ } ++ ++ virtual sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) ++ throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE ++ { ++ const std::vector aAll = ++ getTransferDataFlavorsAsVector(); ++ ++ return std::find_if(aAll.begin(), aAll.end(), DataFlavorEq(rFlavor)) != aAll.end(); ++ } ++}; ++ ++//We want to use gtk_clipboard_get_owner own owner-change to distinguish between ++//us gaining the clipboard ownership vs losing it. To do that we need to use ++//gtk_clipboard_set_with_owner and to do that we need a GObject, so define ++//one here for that purpose and just give it a VclGtkClipboard* member ++class VclGtkClipboard; ++ ++typedef struct _ClipboardOwner ClipboardOwner; ++typedef struct _ClipboardOwnerClass ClipboardOwnerClass; ++ ++struct _ClipboardOwner ++{ ++ GObject parent_instance; ++ ++ /* instance members */ ++ VclGtkClipboard* m_pThis; ++}; ++ ++struct _ClipboardOwnerClass ++{ ++ GObjectClass parent_class; ++ ++ /* class members */ ++}; ++ ++#define CLIPBOARD_OWNER_OBJECT (clipboard_owner_get_type ()) ++#define CLIPBOARD_OWNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLIPBOARD_OWNER_OBJECT, ClipboardOwner)) ++ ++#ifdef __GNUC__ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wunused-function" ++#endif ++G_DEFINE_TYPE(ClipboardOwner, clipboard_owner, G_TYPE_OBJECT); ++#ifdef __GNUC__ ++#pragma GCC diagnostic pop ++#endif ++ ++static void clipboard_owner_class_init (ClipboardOwnerClass *) ++{ ++} ++ ++static void clipboard_owner_init(ClipboardOwner *) ++{ ++} ++ ++class VclGtkClipboard : ++ public cppu::WeakComponentImplHelper< ++ datatransfer::clipboard::XSystemClipboard, ++ XServiceInfo> ++{ ++ GdkAtom m_nSelection; ++ osl::Mutex m_aMutex; ++ ClipboardOwner* m_pOwner; ++ gulong m_nOwnerChangedSignalId; ++ Reference m_aContents; ++ Reference m_aOwner; ++ std::list< Reference > m_aListeners; ++ std::vector m_aGtkTargets; ++ std::vector m_aInfoToFlavor; ++ ++public: ++ ++ VclGtkClipboard(GdkAtom nSelection); ++ virtual ~VclGtkClipboard(); ++ ++ /* ++ * XServiceInfo ++ */ ++ ++ virtual OUString SAL_CALL getImplementationName() throw( RuntimeException, std::exception ) SAL_OVERRIDE; ++ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw( RuntimeException, std::exception ) SAL_OVERRIDE; ++ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( RuntimeException, std::exception ) SAL_OVERRIDE; ++ ++ static OUString getImplementationName_static(); ++ static Sequence< OUString > getSupportedServiceNames_static(); ++ ++ /* ++ * XClipboard ++ */ ++ ++ virtual Reference< css::datatransfer::XTransferable > SAL_CALL getContents() ++ throw(RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ virtual void SAL_CALL setContents( ++ const Reference< css::datatransfer::XTransferable >& xTrans, ++ const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) ++ throw(RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ virtual OUString SAL_CALL getName() ++ throw(RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ /* ++ * XClipboardEx ++ */ ++ ++ virtual sal_Int8 SAL_CALL getRenderingCapabilities() ++ throw(RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ /* ++ * XClipboardNotifier ++ */ ++ virtual void SAL_CALL addClipboardListener( ++ const Reference< css::datatransfer::clipboard::XClipboardListener >& listener ) ++ throw(RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ virtual void SAL_CALL removeClipboardListener( ++ const Reference< css::datatransfer::clipboard::XClipboardListener >& listener ) ++ throw(RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ void ClipboardGet(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info); ++ void ClipboardClear(GtkClipboard *clipboard); ++ void OwnerChanged(GtkClipboard *clipboard, GdkEvent *event); ++private: ++ GtkTargetEntry makeGtkTargetEntry(const css::datatransfer::DataFlavor& rFlavor); ++}; ++ ++OUString VclGtkClipboard::getImplementationName_static() ++{ ++ return OUString( "com.sun.star.datatransfer.VclGtkClipboard" ); ++} ++ ++Sequence< OUString > VclGtkClipboard::getSupportedServiceNames_static() ++{ ++ Sequence< OUString > aRet(1); ++ aRet[0] = "com.sun.star.datatransfer.clipboard.SystemClipboard"; ++ return aRet; ++} ++ ++OUString VclGtkClipboard::getImplementationName() throw( RuntimeException, std::exception ) ++{ ++ return getImplementationName_static(); ++} ++ ++Sequence< OUString > VclGtkClipboard::getSupportedServiceNames() throw( RuntimeException, std::exception ) ++{ ++ return getSupportedServiceNames_static(); ++} ++ ++sal_Bool VclGtkClipboard::supportsService( const OUString& ServiceName ) throw( RuntimeException, std::exception ) ++{ ++ return cppu::supportsService(this, ServiceName); ++} ++ ++Reference< css::datatransfer::XTransferable > VclGtkClipboard::getContents() throw( RuntimeException, std::exception ) ++{ ++ if (G_OBJECT(m_pOwner) != gtk_clipboard_get_owner(gtk_clipboard_get(m_nSelection)) && ++ !m_aContents.is()) ++ { ++ //tdf#93887 This is the system clipboard/selection. We fetch it when we are not ++ //the owner of the clipboard and have not already fetched it. ++ m_aContents = new GtkTransferable(m_nSelection); ++ } ++ return m_aContents; ++} ++ ++void VclGtkClipboard::ClipboardGet(GtkClipboard* /*clipboard*/, GtkSelectionData *selection_data, ++ guint info) ++{ ++ if (!m_aContents.is()) ++ return; ++ ++ GdkAtom type(gdk_atom_intern(OUStringToOString(m_aInfoToFlavor[info].MimeType, ++ RTL_TEXTENCODING_UTF8).getStr(), ++ false)); ++ ++ css::datatransfer::DataFlavor aFlavor(m_aInfoToFlavor[info]); ++ if (aFlavor.MimeType == "UTF8_STRING" || aFlavor.MimeType == "STRING") ++ aFlavor.MimeType = "text/plain;charset=utf-8"; ++ ++ Sequence aData; ++ Any aValue; ++ ++ try ++ { ++ aValue = m_aContents->getTransferData(aFlavor); ++ } ++ catch(...) ++ { ++ } ++ ++ if (aValue.getValueTypeClass() == TypeClass_STRING) ++ { ++ OUString aString; ++ aValue >>= aString; ++ aData = Sequence< sal_Int8 >( reinterpret_cast(aString.getStr()), aString.getLength() * sizeof( sal_Unicode ) ); ++ } ++ else if (aValue.getValueType() == cppu::UnoType>::get()) ++ { ++ aValue >>= aData; ++ } ++ else if (aFlavor.MimeType == "text/plain;charset=utf-8") ++ { ++ //didn't have utf-8, try utf-16 and convert ++ aFlavor.MimeType = "text/plain;charset=utf-16"; ++ aFlavor.DataType = cppu::UnoType::get(); ++ try ++ { ++ aValue = m_aContents->getTransferData(aFlavor); ++ } ++ catch(...) ++ { ++ } ++ OUString aString; ++ aValue >>= aString; ++ OString aUTF8String(OUStringToOString(aString, RTL_TEXTENCODING_UTF8)); ++ gtk_selection_data_set(selection_data, type, 8, ++ reinterpret_cast(aUTF8String.getStr()), ++ aUTF8String.getLength()); ++ return; ++ } ++ ++ gtk_selection_data_set(selection_data, type, 8, ++ reinterpret_cast(aData.getArray()), ++ aData.getLength()); ++} ++ ++void VclGtkClipboard::OwnerChanged(GtkClipboard* clipboard, GdkEvent* /*event*/) ++{ ++ if (G_OBJECT(m_pOwner) != gtk_clipboard_get_owner(clipboard)) ++ { ++ //null out m_aContents to return control to the system-one which ++ //will be retrieved if getContents is called again ++ setContents(Reference(), ++ Reference()); ++ } ++} ++ ++void VclGtkClipboard::ClipboardClear(GtkClipboard * /*clipboard*/) ++{ ++ for (auto &a : m_aGtkTargets) ++ free(a.target); ++ m_aGtkTargets.clear(); ++} ++ ++GtkTargetEntry VclGtkClipboard::makeGtkTargetEntry(const css::datatransfer::DataFlavor& rFlavor) ++{ ++ GtkTargetEntry aEntry; ++ aEntry.target = ++ g_strdup(OUStringToOString(rFlavor.MimeType, RTL_TEXTENCODING_UTF8).getStr()); ++ aEntry.flags = 0; ++ auto it = std::find_if(m_aInfoToFlavor.begin(), m_aInfoToFlavor.end(), ++ DataFlavorEq(rFlavor)); ++ if (it != m_aInfoToFlavor.end()) ++ aEntry.info = std::distance(m_aInfoToFlavor.begin(), it); ++ else ++ { ++ aEntry.info = m_aInfoToFlavor.size(); ++ m_aInfoToFlavor.push_back(rFlavor); ++ } ++ return aEntry; ++} ++ ++namespace ++{ ++ void ClipboardGetFunc(GtkClipboard *clipboard, GtkSelectionData *selection_data, ++ guint info, ++ gpointer user_data_or_owner) ++ { ++ VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis; ++ pThis->ClipboardGet(clipboard, selection_data, info); ++ } ++ ++ void ClipboardClearFunc(GtkClipboard *clipboard, gpointer user_data_or_owner) ++ { ++ VclGtkClipboard* pThis = CLIPBOARD_OWNER(user_data_or_owner)->m_pThis; ++ pThis->ClipboardClear(clipboard); ++ } ++ ++ void handle_owner_change(GtkClipboard *clipboard, GdkEvent *event, gpointer user_data) ++ { ++ VclGtkClipboard* pThis = static_cast(user_data); ++ pThis->OwnerChanged(clipboard, event); ++ } ++} ++ ++VclGtkClipboard::VclGtkClipboard(GdkAtom nSelection) ++ : cppu::WeakComponentImplHelper ++ (m_aMutex) ++ , m_nSelection(nSelection) ++{ ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ m_nOwnerChangedSignalId = g_signal_connect(clipboard, "owner-change", ++ G_CALLBACK(handle_owner_change), this); ++ m_pOwner = CLIPBOARD_OWNER(g_object_new(CLIPBOARD_OWNER_OBJECT, NULL)); ++ m_pOwner->m_pThis = this; ++} ++ ++VclGtkClipboard::~VclGtkClipboard() ++{ ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ g_signal_handler_disconnect(clipboard, m_nOwnerChangedSignalId); ++ g_object_unref(m_pOwner); ++} ++ ++void VclGtkClipboard::setContents( ++ const Reference< css::datatransfer::XTransferable >& xTrans, ++ const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) ++ throw( RuntimeException, std::exception ) ++{ ++ osl::ClearableMutexGuard aGuard( m_aMutex ); ++ Reference< datatransfer::clipboard::XClipboardOwner > xOldOwner( m_aOwner ); ++ Reference< datatransfer::XTransferable > xOldContents( m_aContents ); ++ m_aContents = xTrans; ++ m_aOwner = xClipboardOwner; ++ ++ std::list< Reference< datatransfer::clipboard::XClipboardListener > > xListeners( m_aListeners ); ++ datatransfer::clipboard::ClipboardEvent aEv; ++ ++ if (m_aContents.is()) ++ { ++ css::uno::Sequence aFormats = xTrans->getTransferDataFlavors(); ++ std::vector aGtkTargets; ++ bool bHaveText(false), bHaveUTF8(false); ++ for (int i = 0; i < aFormats.getLength(); ++i) ++ { ++ const css::datatransfer::DataFlavor& rFlavor = aFormats[i]; ++ ++ sal_Int32 nIndex(0); ++ if (rFlavor.MimeType.getToken(0, ';', nIndex) == "text/plain") ++ { ++ bHaveText = true; ++ OUString aToken(rFlavor.MimeType.getToken(0, ';', nIndex)); ++ if (aToken == "charset=utf-8") ++ { ++ bHaveUTF8 = true; ++ } ++ } ++ GtkTargetEntry aEntry(makeGtkTargetEntry(rFlavor)); ++ aGtkTargets.push_back(aEntry); ++ } ++ ++ if (bHaveText) ++ { ++ css::datatransfer::DataFlavor aFlavor; ++ aFlavor.DataType = cppu::UnoType>::get(); ++ if (!bHaveUTF8) ++ { ++ aFlavor.MimeType = "text/plain;charset=utf-8"; ++ aGtkTargets.push_back(makeGtkTargetEntry(aFlavor)); ++ } ++ aFlavor.MimeType = "UTF8_STRING"; ++ aGtkTargets.push_back(makeGtkTargetEntry(aFlavor)); ++ aFlavor.MimeType = "STRING"; ++ aGtkTargets.push_back(makeGtkTargetEntry(aFlavor)); ++ } ++ ++ //if there was a previous gtk_clipboard_set_with_data call then ++ //ClipboardClearFunc will be called now ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ //use with_owner with m_pOwner so we can distinguish in handle_owner_change ++ //if we have gained or lost ownership of the clipboard ++ gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(), ++ ClipboardGetFunc, ClipboardClearFunc, G_OBJECT(m_pOwner)); ++ m_aGtkTargets = aGtkTargets; ++ } ++ ++ aEv.Contents = getContents(); ++ ++ aGuard.clear(); ++ ++ if( xOldOwner.is() && xOldOwner != xClipboardOwner ) ++ xOldOwner->lostOwnership( this, xOldContents ); ++ for( std::list< Reference< datatransfer::clipboard::XClipboardListener > >::iterator it = ++ xListeners.begin(); it != xListeners.end() ; ++it ) ++ { ++ (*it)->changedContents( aEv ); ++ } ++} ++ ++OUString VclGtkClipboard::getName() throw( RuntimeException, std::exception ) ++{ ++ return OUString( "CLIPBOARD" ); ++} ++ ++sal_Int8 VclGtkClipboard::getRenderingCapabilities() throw( RuntimeException, std::exception ) ++{ ++ return 0; ++} ++ ++void VclGtkClipboard::addClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener ) ++ throw( RuntimeException, std::exception ) ++{ ++ osl::ClearableMutexGuard aGuard( m_aMutex ); ++ ++ m_aListeners.push_back( listener ); ++} ++ ++void VclGtkClipboard::removeClipboardListener( const Reference< datatransfer::clipboard::XClipboardListener >& listener ) ++ throw( RuntimeException, std::exception ) ++{ ++ osl::ClearableMutexGuard aGuard( m_aMutex ); ++ ++ m_aListeners.remove( listener ); ++} ++ ++Reference< XInterface > GtkInstance::CreateClipboard(const Sequence< Any >& arguments) ++{ ++ OUString sel; ++ if (arguments.getLength() == 0) { ++ sel = "CLIPBOARD"; ++ } else if (arguments.getLength() != 1 || !(arguments[0] >>= sel)) { ++ throw css::lang::IllegalArgumentException( ++ "bad GtkInstance::CreateClipboard arguments", ++ css::uno::Reference(), -1); ++ } ++ ++ GdkAtom nSelection = (sel == "CLIPBOARD") ? GDK_SELECTION_CLIPBOARD : GDK_SELECTION_PRIMARY; ++ ++ return Reference< XInterface >( static_cast(new VclGtkClipboard(nSelection)) ); ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/unx/gtk3/window/gtk3gtkframe.cxx b/vcl/unx/gtk3/window/gtk3gtkframe.cxx +deleted file mode 100644 +index 5710d50..0000000 +--- a/vcl/unx/gtk3/window/gtk3gtkframe.cxx ++++ /dev/null +@@ -1,12 +0,0 @@ +-/* -*- 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 "../../gtk/window/gtksalframe.cxx" +- +-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.5.0 + diff --git a/SOURCES/0001-never-run-autogen.sh.patch b/SOURCES/0001-never-run-autogen.sh.patch new file mode 100644 index 0000000..b65f8a7 --- /dev/null +++ b/SOURCES/0001-never-run-autogen.sh.patch @@ -0,0 +1,25 @@ +From 820efe20886e41fdea8353f54e8a54bba7fccd84 Mon Sep 17 00:00:00 2001 +From: rpmbuild +Date: Thu, 20 Feb 2014 19:44:49 +0100 +Subject: [PATCH] never run autogen.sh + +--- + Makefile.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.in b/Makefile.in +index 206f5ed..14620da 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -14,7 +14,7 @@ MAKECMDGOALS?=all + SHELL := @SHELL_BASH@ + SRCDIR := @SRC_ROOT@ + BUILDDIR := @BUILDDIR@ +-GIT_BUILD := $(if $(wildcard $(SRCDIR)/.git),T) ++GIT_BUILD := + + # Run autogen.sh if needed and force make to restart itself. + # ... but there are several cases where we do not want to run +-- +1.8.5.3 + diff --git a/SOURCES/0001-ofz-372-check-if-ImplSplit-succeeded.patch b/SOURCES/0001-ofz-372-check-if-ImplSplit-succeeded.patch new file mode 100644 index 0000000..cab175c --- /dev/null +++ b/SOURCES/0001-ofz-372-check-if-ImplSplit-succeeded.patch @@ -0,0 +1,81 @@ +From f24a98badcc637ed32ce2f31e623f651c69057e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 2 Jan 2017 11:53:31 +0000 +Subject: [PATCH] ofz#372 check if ImplSplit succeeded + +Change-Id: I1e34295fe3ee5f77e787f583616d52fa92a0eca4 +--- + tools/inc/poly.h | 2 +- + tools/source/generic/poly.cxx | 23 +++++++++++++++-------- + 2 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/tools/inc/poly.h b/tools/inc/poly.h +index d677bcd8b0ac..c614401f122c 100644 +--- a/tools/inc/poly.h ++++ b/tools/inc/poly.h +@@ -42,7 +42,7 @@ public: + + void ImplSetSize( sal_uInt16 nSize, bool bResize = true ); + void ImplCreateFlagArray(); +- void ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon* pInitPoly = NULL ); ++ bool ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon* pInitPoly = NULL ); + }; + + #define MAX_POLYGONS ((sal_uInt16)0x3FF0) +diff --git a/tools/source/generic/poly.cxx b/tools/source/generic/poly.cxx +index 457a05b4d112..2c89775e79d0 100644 +--- a/tools/source/generic/poly.cxx ++++ b/tools/source/generic/poly.cxx +@@ -208,13 +208,16 @@ void ImplPolygon::ImplSetSize( sal_uInt16 nNewSize, bool bResize ) + mnPoints = nNewSize; + } + +-void ImplPolygon::ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon* pInitPoly ) ++bool ImplPolygon::ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon* pInitPoly ) + { + const sal_uIntPtr nSpaceSize = nSpace * sizeof( Point ); + + //Can't fit this in :-(, throw ? + if (mnPoints + nSpace > USHRT_MAX) +- return; ++ { ++ SAL_WARN("tools", "Polygon needs " << mnPoints + nSpace << " points, but only " << USHRT_MAX << " possible"); ++ return false; ++ } + + const sal_uInt16 nNewSize = mnPoints + nSpace; + +@@ -269,6 +272,8 @@ void ImplPolygon::ImplSplit( sal_uInt16 nPos, sal_uInt16 nSpace, ImplPolygon* pI + mpPointAry = pNewAry; + mnPoints = nNewSize; + } ++ ++ return true; + } + + void ImplPolygon::ImplCreateFlagArray() +@@ -1444,13 +1449,15 @@ void Polygon::Insert( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags ) + if( nPos >= mpImplPolygon->mnPoints ) + nPos = mpImplPolygon->mnPoints; + +- mpImplPolygon->ImplSplit( nPos, 1 ); +- mpImplPolygon->mpPointAry[ nPos ] = rPt; +- +- if( POLY_NORMAL != eFlags ) ++ if (mpImplPolygon->ImplSplit(nPos, 1)) + { +- mpImplPolygon->ImplCreateFlagArray(); +- mpImplPolygon->mpFlagAry[ nPos ] = (sal_uInt8) eFlags; ++ mpImplPolygon->mpPointAry[ nPos ] = rPt; ++ ++ if( POLY_NORMAL != eFlags ) ++ { ++ mpImplPolygon->ImplCreateFlagArray(); ++ mpImplPolygon->mpFlagAry[ nPos ] = (sal_uInt8) eFlags; ++ } + } + } + +-- +2.12.2 + diff --git a/SOURCES/0001-only-set-cur.-page-once-when-removing-mult.-pages.patch b/SOURCES/0001-only-set-cur.-page-once-when-removing-mult.-pages.patch new file mode 100644 index 0000000..c52de74 --- /dev/null +++ b/SOURCES/0001-only-set-cur.-page-once-when-removing-mult.-pages.patch @@ -0,0 +1,54 @@ +From 3643ea7b660a1f8263d05ffa9be47e8180fd2504 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 5 May 2016 17:47:03 +0200 +Subject: [PATCH] only set cur. page once when removing mult. pages + +Change-Id: Id9da135a91d9591eed04fb25d2891169c45ecaaf +--- + .../ui/slidesorter/controller/SlsSelectionManager.cxx | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +index 0768a1e..1e913b3 100644 +--- a/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx ++++ b/sd/source/ui/slidesorter/controller/SlsSelectionManager.cxx +@@ -36,6 +36,9 @@ + #include "view/SlideSorterView.hxx" + #include "view/SlsLayouter.hxx" + #include "drawdoc.hxx" ++#include "drawview.hxx" ++#include "DrawViewShell.hxx" ++#include "ViewShellBase.hxx" + #include "Window.hxx" + #include + #include +@@ -117,6 +120,13 @@ void SelectionManager::DeleteSelectedPages (const bool bSelectFollowingPage) + else + --nNewCurrentSlide; + ++ const auto pViewShell = mrSlideSorter.GetViewShell(); ++ const auto pDrawViewShell = pViewShell ? dynamic_cast(pViewShell->GetViewShellBase().GetMainViewShell().get()) : nullptr; ++ const auto pDrawView = pDrawViewShell ? dynamic_cast(pDrawViewShell->GetDrawView()) : nullptr; ++ ++ if (pDrawView) ++ pDrawView->BlockPageOrderChangedHint(true); ++ + // The actual deletion of the selected pages is done in one of two + // helper functions. They are specialized for normal respectively for + // master pages. +@@ -129,6 +139,12 @@ void SelectionManager::DeleteSelectedPages (const bool bSelectFollowingPage) + + mrController.HandleModelChange(); + aLock.Release(); ++ if (pDrawView) ++ { ++ assert(pDrawViewShell); ++ pDrawView->BlockPageOrderChangedHint(false); ++ pDrawViewShell->ResetActualPage(); ++ } + + // Show focus and move it to next valid location. + if (bIsFocusShowing) +-- +2.7.4 + diff --git a/SOURCES/0001-rerun-autoconf-after-remove-BOOST_SYSTEM.patch b/SOURCES/0001-rerun-autoconf-after-remove-BOOST_SYSTEM.patch new file mode 100644 index 0000000..bb0cbac --- /dev/null +++ b/SOURCES/0001-rerun-autoconf-after-remove-BOOST_SYSTEM.patch @@ -0,0 +1,2651 @@ +From 6fa818c04cd6b011a281ab02ab861e84a94ee549 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 22 Jan 2016 14:38:59 +0000 +Subject: [PATCH] rerun autoconf after remove BOOST_SYSTEM + +Change-Id: Id9afe7150ad721ba1d728cbb3e9b496d15f0896f +--- + external/liborcus/unusedheader.patch.0 | 2630 ++++++++++++++++++++++++++++++++ + 1 file changed, 2630 insertions(+) + +diff --git a/external/liborcus/unusedheader.patch.0 b/external/liborcus/unusedheader.patch.0 +index 4f7a77b..54f2fe6 100644 +--- a/external/liborcus/unusedheader.patch.0 ++++ b/external/liborcus/unusedheader.patch.0 +@@ -9,3 +9,2633 @@ + using namespace std; + + namespace orcus { ++--- ./configure.orig 2016-01-22 14:33:55.601487405 +0000 +++++ ./configure 2016-01-22 14:35:45.219928835 +0000 ++@@ -640,10 +640,14 @@ ++ BOOST_FILESYSTEM_LIBS ++ BOOST_FILESYSTEM_LDPATH ++ BOOST_FILESYSTEM_LDFLAGS +++BOOST_SYSTEM_LIBS +++BOOST_SYSTEM_LDPATH +++BOOST_SYSTEM_LDFLAGS ++ BOOST_PROGRAM_OPTIONS_LIBS ++ BOOST_PROGRAM_OPTIONS_LDPATH ++ BOOST_PROGRAM_OPTIONS_LDFLAGS ++ BOOST_IOSTREAMS_LIBS +++BOOST_LDPATH ++ BOOST_IOSTREAMS_LDPATH ++ BOOST_IOSTREAMS_LDFLAGS ++ WITH_TOOLS_FALSE ++@@ -660,10 +664,6 @@ ++ ZLIB_CFLAGS ++ HAVE_STATIC_LIB_FALSE ++ HAVE_STATIC_LIB_TRUE ++-BOOST_SYSTEM_LIBS ++-BOOST_LDPATH ++-BOOST_SYSTEM_LDPATH ++-BOOST_SYSTEM_LDFLAGS ++ BOOST_CPPFLAGS ++ DISTCHECK_CONFIGURE_FLAGS ++ BOOST_ROOT ++@@ -807,14 +807,13 @@ ++ with_sysroot ++ enable_libtool_lock ++ with_boost ++-enable_static_boost ++-enable_werror ++ enable_debug ++ with_tools ++ with_ods_filter ++ with_xlsx_filter ++ with_xls_xml_filter ++ with_gnumeric_filter +++enable_static_boost ++ enable_spreadsheet_model ++ ' ++ ac_precious_vars='build_alias ++@@ -1469,10 +1468,9 @@ ++ --enable-fast-install[=PKGS] ++ optimize for fast installation [default=yes] ++ --disable-libtool-lock avoid locking (might break parallel builds) +++ --enable-debug Build with debug features in mind.] ++ --enable-static-boost Prefer the static boost libraries over the shared ++ ones [no] ++- --enable-werror Treat all warnings as errors, useful for development ++- --enable-debug Build with debug features in mind.] ++ --disable-spreadsheet-model ++ Disable the spreadsheet model implementation in ++ orcus. Note that the spreadsheet-specific command ++@@ -2592,7 +2590,7 @@ ++ ++ ac_config_headers="$ac_config_headers config.h" ++ ++-am__api_version='1.14' +++am__api_version='1.12' ++ ++ ac_aux_dir= ++ for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do ++@@ -2805,8 +2803,8 @@ ++ esac ++ fi ++ # Use eval to expand $SHELL ++-if eval "$MISSING --is-lightweight"; then ++- am_missing_run="$MISSING " +++if eval "$MISSING --run true"; then +++ am_missing_run="$MISSING --run " ++ else ++ am_missing_run= ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 ++@@ -3046,45 +3044,6 @@ ++ fi ++ rmdir .tst 2>/dev/null ++ ++-# Check whether --enable-silent-rules was given. ++-if test "${enable_silent_rules+set}" = set; then : ++- enableval=$enable_silent_rules; ++-fi ++- ++-case $enable_silent_rules in # ((( ++- yes) AM_DEFAULT_VERBOSITY=0;; ++- no) AM_DEFAULT_VERBOSITY=1;; ++- *) AM_DEFAULT_VERBOSITY=1;; ++-esac ++-am_make=${MAKE-make} ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 ++-$as_echo_n "checking whether $am_make supports nested variables... " >&6; } ++-if ${am_cv_make_support_nested_variables+:} false; then : ++- $as_echo_n "(cached) " >&6 ++-else ++- if $as_echo 'TRUE=$(BAR$(V)) ++-BAR0=false ++-BAR1=true ++-V=1 ++-am__doit: ++- @$(TRUE) ++-.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then ++- am_cv_make_support_nested_variables=yes ++-else ++- am_cv_make_support_nested_variables=no ++-fi ++-fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 ++-$as_echo "$am_cv_make_support_nested_variables" >&6; } ++-if test $am_cv_make_support_nested_variables = yes; then ++- AM_V='$(V)' ++- AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' ++-else ++- AM_V=$AM_DEFAULT_VERBOSITY ++- AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY ++-fi ++-AM_BACKSLASH='\' ++- ++ if test "`cd $srcdir && pwd`" != "`pwd`"; then ++ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output ++ # is not polluted with repeated "-I." ++@@ -3135,70 +3094,19 @@ ++ ++ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} ++ ++-# For better backward compatibility. To be removed once Automake 1.9.x ++-# dies out for good. For more background, see: ++-# ++-# ++-mkdir_p='$(MKDIR_P)' ++- +++mkdir_p="$MKDIR_P" ++ # We need awk for the "check" target. The system "awk" is bad on ++ # some platforms. ++ # Always define AMTAR for backward compatibility. Yes, it's still used ++ # in the wild :-( We should find a proper way to deprecate it ... ++ AMTAR='$${TAR-tar}' ++ ++- ++-# We'll loop over all known methods to create a tar archive until one works. ++-_am_tools='gnutar pax cpio none' ++- ++ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' ++ ++ ++ ++ ++ ++- ++-# POSIX will say in a future version that running "rm -f" with no argument ++-# is OK; and we want to be able to make that assumption in our Makefile ++-# recipes. So use an aggressive probe to check that the usage we want is ++-# actually supported "in the wild" to an acceptable degree. ++-# See automake bug#10828. ++-# To make any issue more visible, cause the running configure to be aborted ++-# by default if the 'rm' program in use doesn't match our expectations; the ++-# user can still override this though. ++-if rm -f && rm -fr && rm -rf; then : OK; else ++- cat >&2 <<'END' ++-Oops! ++- ++-Your 'rm' program seems unable to run without file operands specified ++-on the command line, even when the '-f' option is present. This is contrary ++-to the behaviour of most rm programs out there, and not conforming with ++-the upcoming POSIX standard: ++- ++-Please tell bug-automake@gnu.org about your system, including the value ++-of your $PATH and any error possibly output before this message. This ++-can help us improve future automake versions. ++- ++-END ++- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then ++- echo 'Configuration will proceed anyway, since you have set the' >&2 ++- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 ++- echo >&2 ++- else ++- cat >&2 <<'END' ++-Aborting the configuration process, to ensure you take notice of the issue. ++- ++-You can download and install GNU coreutils to get an 'rm' implementation ++-that behaves properly: . ++- ++-If you want to complete the configuration process using your problematic ++-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM ++-to "yes", and re-run configure. ++- ++-END ++- as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 ++- fi ++-fi ++ # Check whether --enable-silent-rules was given. ++ if test "${enable_silent_rules+set}" = set; then : ++ enableval=$enable_silent_rules; ++@@ -4101,65 +4009,6 @@ ++ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++-ac_ext=c ++-ac_cpp='$CPP $CPPFLAGS' ++-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_c_compiler_gnu ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 ++-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } ++-if ${am_cv_prog_cc_c_o+:} false; then : ++- $as_echo_n "(cached) " >&6 ++-else ++- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++-/* end confdefs.h. */ ++- ++-int ++-main () ++-{ ++- ++- ; ++- return 0; ++-} ++-_ACEOF ++- # Make sure it works both with $CC and with simple cc. ++- # Following AC_PROG_CC_C_O, we do the test twice because some ++- # compilers refuse to overwrite an existing .o file with -o, ++- # though they will create one. ++- am_cv_prog_cc_c_o=yes ++- for am_i in 1 2; do ++- if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ++- ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ++- ac_status=$? ++- echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++- (exit $ac_status); } \ ++- && test -f conftest2.$ac_objext; then ++- : OK ++- else ++- am_cv_prog_cc_c_o=no ++- break ++- fi ++- done ++- rm -f core conftest* ++- unset am_i ++-fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 ++-$as_echo "$am_cv_prog_cc_c_o" >&6; } ++-if test "$am_cv_prog_cc_c_o" != yes; then ++- # Losing compiler, so override with the script. ++- # FIXME: It is wrong to rewrite CC. ++- # But if we don't then we get into trouble of one sort or another. ++- # A longer-term fix would be to have automake use am__CC in this case, ++- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" ++- CC="$am_aux_dir/compile $CC" ++-fi ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++- ++- ++ depcc="$CC" am_compiler_list= ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 ++@@ -7222,7 +7071,7 @@ ++ rm -rf conftest* ++ ;; ++ ++-x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +++x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ ++ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ++ # Find out which ABI we are using. ++ echo 'int i;' > conftest.$ac_ext ++@@ -7240,10 +7089,7 @@ ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_i386" ++ ;; ++- powerpc64le-*linux*) ++- LD="${LD-ld} -m elf32lppclinux" ++- ;; ++- powerpc64-*linux*) +++ ppc64-*linux*|powerpc64-*linux*) ++ LD="${LD-ld} -m elf32ppclinux" ++ ;; ++ s390x-*linux*) ++@@ -7262,10 +7108,7 @@ ++ x86_64-*linux*) ++ LD="${LD-ld} -m elf_x86_64" ++ ;; ++- powerpcle-*linux*) ++- LD="${LD-ld} -m elf64lppc" ++- ;; ++- powerpc-*linux*) +++ ppc*-*linux*|powerpc*-*linux*) ++ LD="${LD-ld} -m elf64ppc" ++ ;; ++ s390*-*linux*|s390*-*tpf*) ++@@ -11288,14 +11131,10 @@ ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++- # Add ABI-specific directories to the system library path. ++- sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" ++- ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++- sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" ++- +++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++@@ -15123,14 +14962,10 @@ ++ # before this can be enabled. ++ hardcode_into_libs=yes ++ ++- # Add ABI-specific directories to the system library path. ++- sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" ++- ++ # Append ld.so.conf contents to the search path ++ if test -f /etc/ld.so.conf; then ++ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` ++- sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" ++- +++ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ fi ++ ++ # We used to test for /lib/ld.so.1 and disable shared libraries on ++@@ -16203,7 +16038,7 @@ ++ # ====================== ++ # Set required ixion api ++ # ====================== ++-IXION_REQUIRED_API_VERSION=0.10 +++IXION_REQUIRED_API_VERSION=0.8 ++ ++ ++ # ============= ++@@ -16212,7 +16047,7 @@ ++ ORCUS_API_VERSION=0.8 ++ ++ ++-echo "$as_me: this is boost.m4 serial 24" >&5 +++echo "$as_me: this is boost.m4 serial 18" >&5 ++ boost_save_IFS=$IFS ++ boost_version_req=1.36 ++ IFS=. ++@@ -16356,30 +16191,17 @@ ++ if ${boost_cv_lib_version+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ /* end confdefs.h. */ ++ #include ++ boost-lib-version = BOOST_LIB_VERSION ++ _ACEOF ++ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ++- grep -v '#' | ++- grep -Ev '^(conftest.cpp| *command-line arguments :)' | ++ tr -d '\r' | ++- tr -s '\n' ' ' | ++- $SED -n -e "/^ *boost-lib-version = /{s///;s/[\" ]//g;p;q;}" >conftest.i 2>&1; then : +++ $SED -n -e "/^boost-lib-version = /{s///;s/\"//g;p;q;}" >conftest.i 2>&1; then : ++ boost_cv_lib_version=`cat conftest.i` ++ fi ++ rm -rf conftest* ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_version" >&5 ++@@ -16388,536 +16210,40 @@ ++ boost_major_version=`echo "$boost_cv_lib_version" | sed 's/_//;s/_.*//'` ++ case $boost_major_version in #( ++ '' | *[!0-9]*) ++- as_fn_error $? "invalid value: boost_major_version='$boost_major_version'" "$LINENO" 5 +++ as_fn_error $? "invalid value: boost_major_version=$boost_major_version" "$LINENO" 5 ++ ;; ++ esac ++ fi ++ CPPFLAGS=$boost_save_CPPFLAGS ++ ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the toolset name used by Boost for $CXX" >&5 ++-$as_echo_n "checking for the toolset name used by Boost for $CXX... " >&6; } ++-if ${boost_cv_lib_tag+:} false; then : ++- $as_echo_n "(cached) " >&6 +++ +++# ========================================================= +++# Determine if we are going to build static lib (for MinGW) +++# ========================================================= +++ if test "$enable_shared" = no -a "$enable_static" = yes; then +++ HAVE_STATIC_LIB_TRUE= +++ HAVE_STATIC_LIB_FALSE='#' ++ else ++- boost_cv_lib_tag=unknown ++-if test x$boost_cv_inc_path != xno; then ++- ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++- # The following tests are mostly inspired by boost/config/auto_link.hpp ++- # The list is sorted to most recent/common to oldest compiler (in order ++- # to increase the likelihood of finding the right compiler with the ++- # least number of compilation attempt). ++- # Beware that some tests are sensible to the order (for instance, we must ++- # look for MinGW before looking for GCC3). ++- # I used one compilation test per compiler with a #error to recognize ++- # each compiler so that it works even when cross-compiling (let me know ++- # if you know a better approach). ++- # Known missing tags (known from Boost's tools/build/v2/tools/common.jam): ++- # como, edg, kcc, bck, mp, sw, tru, xlc ++- # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines ++- # the same defines as GCC's). ++- for i in \ ++- "defined __GNUC__ && __GNUC__ == 5 && __GNUC_MINOR__ == 0 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw50" \ ++- "defined __GNUC__ && __GNUC__ == 5 && __GNUC_MINOR__ == 0 && !defined __ICC @ gcc50" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 10 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw410" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 10 && !defined __ICC @ gcc410" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 9 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw49" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 9 && !defined __ICC @ gcc49" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 8 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw48" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 8 && !defined __ICC @ gcc48" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 7 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw47" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 7 && !defined __ICC @ gcc47" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 6 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw46" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 6 && !defined __ICC @ gcc46" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 5 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw45" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 5 && !defined __ICC @ gcc45" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 4 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw44" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 4 && !defined __ICC @ gcc44" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 3 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw43" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 3 && !defined __ICC @ gcc43" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw42" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined __ICC @ gcc42" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 1 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw41" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 1 && !defined __ICC @ gcc41" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && !defined __ICC && \ ++- (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw40" \ ++- "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && !defined __ICC @ gcc40" \ ++- "defined __GNUC__ && __GNUC__ == 3 && !defined __ICC \ ++- && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ ++- || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw" \ ++- "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 4 && !defined __ICC @ gcc34" \ ++- "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 3 && !defined __ICC @ gcc33" \ ++- "defined _MSC_VER && _MSC_VER >= 1500 @ vc90" \ ++- "defined _MSC_VER && _MSC_VER == 1400 @ vc80" \ ++- "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 2 && !defined __ICC @ gcc32" \ ++- "defined _MSC_VER && _MSC_VER == 1310 @ vc71" \ ++- "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 1 && !defined __ICC @ gcc31" \ ++- "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 0 && !defined __ICC @ gcc30" \ ++- "defined __BORLANDC__ @ bcb" \ ++- "defined __ICC && (defined __unix || defined ) @ il" \ ++- "defined __ICL @ iw" \ ++- "defined _MSC_VER && _MSC_VER == 1300 @ vc7" \ ++- "defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ == 95 && !defined __ICC @ gcc295" \ ++- "defined __MWERKS__ && __MWERKS__ <= 0x32FF @ cw9" \ ++- "defined _MSC_VER && _MSC_VER < 1300 && !defined UNDER_CE @ vc6" \ ++- "defined _MSC_VER && _MSC_VER < 1300 && defined UNDER_CE @ evc4" \ ++- "defined __MWERKS__ && __MWERKS__ <= 0x31FF @ cw8" ++- do ++- boost_tag_test=`expr "X$i" : 'X\([^@]*\) @ '` ++- boost_tag=`expr "X$i" : 'X[^@]* @ \(.*\)'` ++- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++-/* end confdefs.h. */ +++ HAVE_STATIC_LIB_TRUE='#' +++ HAVE_STATIC_LIB_FALSE= +++fi ++ ++-#if $boost_tag_test ++-/* OK */ ++-#else ++-# error $boost_tag_test ++-#endif ++ ++-int ++-main () ++-{ +++# ===== +++# Debug +++# ===== +++# Check whether --enable-debug was given. +++if test "${enable_debug+set}" = set; then : +++ enableval=$enable_debug; enable_debug="$enableval" +++else +++ enable_debug=no ++ ++- ; ++- return 0; ++-} ++-_ACEOF ++-if ac_fn_cxx_try_compile "$LINENO"; then : ++- boost_cv_lib_tag=$boost_tag; break ++-fi ++-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++- done ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++- case $boost_cv_lib_tag in #( ++- # Some newer (>= 1.35?) versions of Boost seem to only use "gcc" as opposed ++- # to "gcc41" for instance. ++- *-gcc | *'-gcc ') :;; #( Don't re-add -gcc: it's already in there. ++- gcc*) ++- boost_tag_x= ++- case $host_os in #( ++- darwin*) ++- if test $boost_major_version -ge 136; then ++- # The `x' added in r46793 of Boost. ++- boost_tag_x=x ++- fi;; ++- esac ++- # We can specify multiple tags in this variable because it's used by ++- # BOOST_FIND_LIB that does a `for tag in -$boost_cv_lib_tag' ... ++- boost_cv_lib_tag="$boost_tag_x$boost_cv_lib_tag -${boost_tag_x}gcc" ++- ;; #( ++- unknown) ++- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not figure out which toolset name to use for $CXX" >&5 ++-$as_echo "$as_me: WARNING: could not figure out which toolset name to use for $CXX" >&2;} ++- boost_cv_lib_tag= ++- ;; ++- esac ++ fi ++-fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_tag" >&5 ++-$as_echo "$boost_cv_lib_tag" >&6; } ++-# Check whether --enable-static-boost was given. ++-if test "${enable_static_boost+set}" = set; then : ++- enableval=$enable_static_boost; enable_static_boost=yes ++-else ++- enable_static_boost=no ++-fi ++- ++-# Check whether we do better use `mt' even though we weren't ask to. ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++-/* end confdefs.h. */ ++- ++-#if defined _REENTRANT || defined _MT || defined __MT__ ++-/* use -mt */ ++-#else ++-# error MT not needed ++-#endif ++- ++-int ++-main () ++-{ ++- ++- ; ++- return 0; ++-} ++-_ACEOF ++-if ac_fn_cxx_try_compile "$LINENO"; then : ++- boost_guess_use_mt=: ++-else ++- boost_guess_use_mt=false ++-fi ++-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++- ++-if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost system library" >&5 ++-$as_echo "$as_me: Boost not available, not searching for the Boost system library" >&6;} ++-else ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/system/error_code.hpp" >&5 ++-$as_echo "$as_me: Boost not available, not searching for boost/system/error_code.hpp" >&6;} ++-else ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-boost_save_CPPFLAGS=$CPPFLAGS ++-CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-ac_fn_cxx_check_header_mongrel "$LINENO" "boost/system/error_code.hpp" "ac_cv_header_boost_system_error_code_hpp" "$ac_includes_default" ++-if test "x$ac_cv_header_boost_system_error_code_hpp" = xyes; then : ++- ++-$as_echo "#define HAVE_BOOST_SYSTEM_ERROR_CODE_HPP 1" >>confdefs.h ++- ++-else ++- as_fn_error $? "cannot find boost/system/error_code.hpp" "$LINENO" 5 ++-fi ++- ++- ++-CPPFLAGS=$boost_save_CPPFLAGS ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-fi ++- ++-boost_save_CPPFLAGS=$CPPFLAGS ++-CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost system library" >&5 ++-$as_echo_n "checking for the Boost system library... " >&6; } ++-if ${boost_cv_lib_system+:} false; then : ++- $as_echo_n "(cached) " >&6 ++-else ++- boost_cv_lib_system=no ++- case "" in #( ++- (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( ++- (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( ++- (*) boost_mt=; boost_rtopt=;; ++- esac ++- if test $enable_static_boost = yes; then ++- boost_rtopt="s$boost_rtopt" ++- fi ++- # Find the proper debug variant depending on what we've been asked to find. ++- case $boost_rtopt in #( ++- (*d*) boost_rt_d=$boost_rtopt;; #( ++- (*[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') ++- boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( ++- (*) boost_rt_d='-d';; ++- esac ++- # If the PREFERRED-RT-OPT are not empty, prepend a `-'. ++- test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" ++- $boost_guess_use_mt && boost_mt=-mt ++- # Look for the abs path the static archive. ++- # $libext is computed by Libtool but let's make sure it's non empty. ++- test -z "$libext" && ++- as_fn_error $? "the libext variable is empty, did you invoke Libtool?" "$LINENO" 5 ++- boost_save_ac_objext=$ac_objext ++- # Generate the test file. ++- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++-/* end confdefs.h. */ ++-#include ++- ++-int ++-main () ++-{ ++-boost::system::error_code e; e.clear(); ++- ; ++- return 0; ++-} ++-_ACEOF ++- if ac_fn_cxx_try_compile "$LINENO"; then : ++- ac_objext=do_not_rm_me_plz ++-else ++- as_fn_error $? "cannot compile a test that uses Boost system" "$LINENO" 5 ++-fi ++-rm -f core conftest.err conftest.$ac_objext ++- ac_objext=$boost_save_ac_objext ++- boost_failed_libs= ++-# Don't bother to ident the following nested for loops, only the 2 ++-# innermost ones matter. ++-for boost_lib_ in system; do ++-for boost_tag_ in -$boost_cv_lib_tag ''; do ++-for boost_ver_ in -$boost_cv_lib_version ''; do ++-for boost_mt_ in $boost_mt -mt ''; do ++-for boost_rtopt_ in $boost_rtopt '' -d; do ++- for boost_lib in \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_ver_ ++- do ++- # Avoid testing twice the same lib ++- case $boost_failed_libs in #( ++- (*@$boost_lib@*) continue;; ++- esac ++- # If with_boost is empty, we'll search in /lib first, which is not quite ++- # right so instead we'll try to a location based on where the headers are. ++- boost_tmp_lib=$with_boost ++- test x"$with_boost" = x && boost_tmp_lib=${boost_cv_inc_path%/include} ++- for boost_ldpath in "$boost_tmp_lib/lib" '' \ ++- /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ ++- "$with_boost" C:/Boost/lib /lib* ++- do ++- # Don't waste time with directories that don't exist. ++- if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then ++- continue ++- fi ++- boost_save_LDFLAGS=$LDFLAGS ++- # Are we looking for a static library? ++- case $boost_ldpath:$boost_rtopt_ in #( ++- (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) ++- boost_cv_lib_system_LIBS="$boost_ldpath/lib$boost_lib.$libext" ++- test -e "$boost_cv_lib_system_LIBS" || continue;; #( ++- (*) # No: use -lboost_foo to find the shared library. ++- boost_cv_lib_system_LIBS="-l$boost_lib";; ++- esac ++- boost_save_LIBS=$LIBS ++- LIBS="$boost_cv_lib_system_LIBS $LIBS" ++- test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" ++- rm -f conftest$ac_exeext ++-boost_save_ac_ext=$ac_ext ++-boost_use_source=: ++-# If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++-# tries to link the existing object file instead of compiling from source. ++-test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && ++- $as_echo "$as_me:${as_lineno-$LINENO}: re-using the existing conftest.$ac_objext" >&5 ++-if { { ac_try="$ac_link" ++-case "(($ac_try" in ++- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++- *) ac_try_echo=$ac_try;; ++-esac ++-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++-$as_echo "$ac_try_echo"; } >&5 ++- (eval "$ac_link") 2>conftest.err ++- ac_status=$? ++- if test -s conftest.err; then ++- grep -v '^ *+' conftest.err >conftest.er1 ++- cat conftest.er1 >&5 ++- mv -f conftest.er1 conftest.err ++- fi ++- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++- test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err ++- } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext ++- }; then : ++- boost_cv_lib_system=yes ++-else ++- if $boost_use_source; then ++- $as_echo "$as_me: failed program was:" >&5 ++-sed 's/^/| /' conftest.$ac_ext >&5 ++- ++- fi ++- boost_cv_lib_system=no ++-fi ++-ac_objext=$boost_save_ac_objext ++-ac_ext=$boost_save_ac_ext ++-rm -f core conftest.err conftest_ipa8_conftest.oo \ ++- conftest$ac_exeext ++- ac_objext=$boost_save_ac_objext ++- LDFLAGS=$boost_save_LDFLAGS ++- LIBS=$boost_save_LIBS ++- if test x"$boost_cv_lib_system" = xyes; then ++- # Check or used cached result of whether or not using -R or ++- # -rpath makes sense. Some implementations of ld, such as for ++- # Mac OSX, require -rpath but -R is the flag known to work on ++- # other systems. https://github.com/tsuna/boost.m4/issues/19 ++- if ${boost_cv_rpath_link_ldflag+:} false; then : ++- $as_echo_n "(cached) " >&6 ++-else ++- case $boost_ldpath in ++- '') # Nothing to do. ++- boost_cv_rpath_link_ldflag= ++- boost_rpath_link_ldflag_found=yes;; ++- *) ++- for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do ++- LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- LIBS="$boost_save_LIBS $boost_cv_lib_system_LIBS" ++- rm -f conftest$ac_exeext ++-boost_save_ac_ext=$ac_ext ++-boost_use_source=: ++-# If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++-# tries to link the existing object file instead of compiling from source. ++-test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && ++- $as_echo "$as_me:${as_lineno-$LINENO}: re-using the existing conftest.$ac_objext" >&5 ++-if { { ac_try="$ac_link" ++-case "(($ac_try" in ++- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++- *) ac_try_echo=$ac_try;; ++-esac ++-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++-$as_echo "$ac_try_echo"; } >&5 ++- (eval "$ac_link") 2>conftest.err ++- ac_status=$? ++- if test -s conftest.err; then ++- grep -v '^ *+' conftest.err >conftest.er1 ++- cat conftest.er1 >&5 ++- mv -f conftest.er1 conftest.err ++- fi ++- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++- test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err ++- } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext ++- }; then : ++- boost_rpath_link_ldflag_found=yes ++- break ++-else ++- if $boost_use_source; then ++- $as_echo "$as_me: failed program was:" >&5 ++-sed 's/^/| /' conftest.$ac_ext >&5 ++- ++- fi ++- boost_rpath_link_ldflag_found=no ++-fi ++-ac_objext=$boost_save_ac_objext ++-ac_ext=$boost_save_ac_ext ++-rm -f core conftest.err conftest_ipa8_conftest.oo \ ++- conftest$ac_exeext ++- done ++- ;; ++- esac ++- if test "x$boost_rpath_link_ldflag_found" != "xyes"; then : ++- as_fn_error $? "Unable to determine whether to use -R or -rpath" "$LINENO" 5 ++-fi ++- LDFLAGS=$boost_save_LDFLAGS ++- LIBS=$boost_save_LIBS ++- ++-fi ++- ++- test x"$boost_ldpath" != x && ++- boost_cv_lib_system_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- boost_cv_lib_system_LDPATH="$boost_ldpath" ++- break 7 ++- else ++- boost_failed_libs="$boost_failed_libs@$boost_lib@" ++- fi ++- done ++- done ++-done ++-done ++-done ++-done ++-done # boost_lib_ ++-rm -f conftest.$ac_objext ++- ++-fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_system" >&5 ++-$as_echo "$boost_cv_lib_system" >&6; } ++-case $boost_cv_lib_system in #( ++- (no) $as_echo "$as_me: failed program was:" >&5 ++-sed 's/^/| /' conftest.$ac_ext >&5 ++- ++- as_fn_error $? "cannot find the flags to link with Boost system" "$LINENO" 5 ++- ;; ++-esac ++-BOOST_SYSTEM_LDFLAGS=$boost_cv_lib_system_LDFLAGS ++-BOOST_SYSTEM_LDPATH=$boost_cv_lib_system_LDPATH ++-BOOST_LDPATH=$boost_cv_lib_system_LDPATH ++-BOOST_SYSTEM_LIBS=$boost_cv_lib_system_LIBS ++-CPPFLAGS=$boost_save_CPPFLAGS ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-fi ++- ++- ++- ++- ++-# ============== ++-# Werror support ++-# ============== ++-# Check whether --enable-werror was given. ++-if test "${enable_werror+set}" = set; then : ++- enableval=$enable_werror; enable_werror="$enableval" ++-else ++- enable_werror=no ++- ++-fi ++- ++-if test x"$enable_werror" == "xyes"; then : ++- ++- CXXFLAGS="$CXXFLAGS -Werror" ++- ++-fi ++- ++-# ========================================================= ++-# Determine if we are going to build static lib (for MinGW) ++-# ========================================================= ++- if test "$enable_shared" = no -a "$enable_static" = yes; then ++- HAVE_STATIC_LIB_TRUE= ++- HAVE_STATIC_LIB_FALSE='#' ++-else ++- HAVE_STATIC_LIB_TRUE='#' ++- HAVE_STATIC_LIB_FALSE= ++-fi ++- ++- ++-# ===== ++-# Debug ++-# ===== ++-# Check whether --enable-debug was given. ++-if test "${enable_debug+set}" = set; then : ++- enableval=$enable_debug; enable_debug="$enableval" ++-else ++- enable_debug=no ++- ++-fi ++- ++-if test "x$enable_debug" != "xno"; then : ++- ++- CXXFLAGS="$CXXFLAGS -g" ++- +++ +++if test "x$enable_debug" != "xno"; then : +++ +++ CXXFLAGS="$CXXFLAGS -g" +++ ++ else ++ ++ ++@@ -17123,7 +16449,151 @@ ++ WITH_TOOLS_TRUE='#' ++ WITH_TOOLS_FALSE= ++ fi ++- +++ +++ +++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the toolset name used by Boost for $CXX" >&5 +++$as_echo_n "checking for the toolset name used by Boost for $CXX... " >&6; } +++if ${boost_cv_lib_tag+:} false; then : +++ $as_echo_n "(cached) " >&6 +++else +++ boost_cv_lib_tag=unknown +++if test x$boost_cv_inc_path != xno; then +++ ac_ext=cpp +++ac_cpp='$CXXCPP $CPPFLAGS' +++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +++ # The following tests are mostly inspired by boost/config/auto_link.hpp +++ # The list is sorted to most recent/common to oldest compiler (in order +++ # to increase the likelihood of finding the right compiler with the +++ # least number of compilation attempt). +++ # Beware that some tests are sensible to the order (for instance, we must +++ # look for MinGW before looking for GCC3). +++ # I used one compilation test per compiler with a #error to recognize +++ # each compiler so that it works even when cross-compiling (let me know +++ # if you know a better approach). +++ # Known missing tags (known from Boost's tools/build/v2/tools/common.jam): +++ # como, edg, kcc, bck, mp, sw, tru, xlc +++ # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines +++ # the same defines as GCC's). +++ for i in \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 8 && !defined __ICC @ gcc48" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 7 && !defined __ICC @ gcc47" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 6 && !defined __ICC @ gcc46" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 5 && !defined __ICC @ gcc45" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 4 && !defined __ICC @ gcc44" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 3 && !defined __ICC @ gcc43" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined __ICC @ gcc42" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 1 && !defined __ICC @ gcc41" \ +++ "defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && !defined __ICC @ gcc40" \ +++ "defined __GNUC__ && __GNUC__ == 3 && !defined __ICC \ +++ && (defined WIN32 || defined WINNT || defined _WIN32 || defined __WIN32 \ +++ || defined __WIN32__ || defined __WINNT || defined __WINNT__) @ mgw" \ +++ "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 4 && !defined __ICC @ gcc34" \ +++ "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 3 && !defined __ICC @ gcc33" \ +++ "defined _MSC_VER && _MSC_VER >= 1500 @ vc90" \ +++ "defined _MSC_VER && _MSC_VER == 1400 @ vc80" \ +++ "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 2 && !defined __ICC @ gcc32" \ +++ "defined _MSC_VER && _MSC_VER == 1310 @ vc71" \ +++ "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 1 && !defined __ICC @ gcc31" \ +++ "defined __GNUC__ && __GNUC__ == 3 && __GNUC_MINOR__ == 0 && !defined __ICC @ gcc30" \ +++ "defined __BORLANDC__ @ bcb" \ +++ "defined __ICC && (defined __unix || defined ) @ il" \ +++ "defined __ICL @ iw" \ +++ "defined _MSC_VER && _MSC_VER == 1300 @ vc7" \ +++ "defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ == 95 && !defined __ICC @ gcc295" \ +++ "defined __MWERKS__ && __MWERKS__ <= 0x32FF @ cw9" \ +++ "defined _MSC_VER && _MSC_VER < 1300 && !defined UNDER_CE @ vc6" \ +++ "defined _MSC_VER && _MSC_VER < 1300 && defined UNDER_CE @ evc4" \ +++ "defined __MWERKS__ && __MWERKS__ <= 0x31FF @ cw8" +++ do +++ boost_tag_test=`expr "X$i" : 'X\([^@]*\) @ '` +++ boost_tag=`expr "X$i" : 'X[^@]* @ \(.*\)'` +++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext +++/* end confdefs.h. */ +++ +++#if $boost_tag_test +++/* OK */ +++#else +++# error $boost_tag_test +++#endif +++ +++int +++main () +++{ +++ +++ ; +++ return 0; +++} +++_ACEOF +++if ac_fn_cxx_try_compile "$LINENO"; then : +++ boost_cv_lib_tag=$boost_tag; break +++fi +++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +++ done +++ac_ext=cpp +++ac_cpp='$CXXCPP $CPPFLAGS' +++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +++ case $boost_cv_lib_tag in #( +++ # Some newer (>= 1.35?) versions of Boost seem to only use "gcc" as opposed +++ # to "gcc41" for instance. +++ *-gcc | *'-gcc ') :;; #( Don't re-add -gcc: it's already in there. +++ gcc*) +++ boost_tag_x= +++ case $host_os in #( +++ darwin*) +++ if test $boost_major_version -ge 136; then +++ # The `x' added in r46793 of Boost. +++ boost_tag_x=x +++ fi;; +++ esac +++ # We can specify multiple tags in this variable because it's used by +++ # BOOST_FIND_LIB that does a `for tag in -$boost_cv_lib_tag' ... +++ boost_cv_lib_tag="$boost_tag_x$boost_cv_lib_tag -${boost_tag_x}gcc" +++ ;; #( +++ unknown) +++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not figure out which toolset name to use for $CXX" >&5 +++$as_echo "$as_me: WARNING: could not figure out which toolset name to use for $CXX" >&2;} +++ boost_cv_lib_tag= +++ ;; +++ esac +++fi +++fi +++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_tag" >&5 +++$as_echo "$boost_cv_lib_tag" >&6; } +++# Check whether --enable-static-boost was given. +++if test "${enable_static_boost+set}" = set; then : +++ enableval=$enable_static_boost; enable_static_boost=yes +++else +++ enable_static_boost=no +++fi +++ +++# Check whether we do better use `mt' even though we weren't ask to. +++cat confdefs.h - <<_ACEOF >conftest.$ac_ext +++/* end confdefs.h. */ +++ +++#if defined _REENTRANT || defined _MT || defined __MT__ +++/* use -mt */ +++#else +++# error MT not needed +++#endif +++ +++int +++main () +++{ +++ +++ ; +++ return 0; +++} +++_ACEOF +++if ac_fn_cxx_try_compile "$LINENO"; then : +++ boost_guess_use_mt=: +++else +++ boost_guess_use_mt=false +++fi +++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ ++ if test "x$with_gnumeric_filter" != "xno"; then : ++ ++@@ -17167,6 +16637,13 @@ ++ ++ boost_save_CPPFLAGS=$CPPFLAGS ++ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" +++# Now let's try to find the library. The algorithm is as follows: first look +++# for a given library name according to the user's PREFERRED-RT-OPT. For each +++# library name, we prefer to use the ones that carry the tag (toolset name). +++# Each library is searched through the various standard paths were Boost is +++# usually installed. If we can't find the standard variants, we try to +++# enforce -mt (for instance on MacOSX, libboost_threads.dylib doesn't exist +++# but there's -obviously- libboost_threads-mt.dylib). ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost iostreams library" >&5 ++ $as_echo_n "checking for the Boost iostreams library... " >&6; } ++ if ${boost_cv_lib_iostreams+:} false; then : ++@@ -17174,19 +16651,19 @@ ++ else ++ boost_cv_lib_iostreams=no ++ case "" in #( ++- (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( ++- (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( ++- (*) boost_mt=; boost_rtopt=;; +++ mt | mt-) boost_mt=-mt; boost_rtopt=;; #( +++ mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( +++ *) boost_mt=; boost_rtopt=;; ++ esac ++ if test $enable_static_boost = yes; then ++ boost_rtopt="s$boost_rtopt" ++ fi ++ # Find the proper debug variant depending on what we've been asked to find. ++ case $boost_rtopt in #( ++- (*d*) boost_rt_d=$boost_rtopt;; #( ++- (*[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') +++ *d*) boost_rt_d=$boost_rtopt;; #( +++ *[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') ++ boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( ++- (*) boost_rt_d='-d';; +++ *) boost_rt_d='-d';; ++ esac ++ # If the PREFERRED-RT-OPT are not empty, prepend a `-'. ++ test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" ++@@ -17217,22 +16694,21 @@ ++ rm -f core conftest.err conftest.$ac_objext ++ ac_objext=$boost_save_ac_objext ++ boost_failed_libs= ++-# Don't bother to ident the following nested for loops, only the 2 ++-# innermost ones matter. ++-for boost_lib_ in iostreams; do +++# Don't bother to ident the 6 nested for loops, only the 2 innermost ones +++# matter. ++ for boost_tag_ in -$boost_cv_lib_tag ''; do ++ for boost_ver_ in -$boost_cv_lib_version ''; do ++ for boost_mt_ in $boost_mt -mt ''; do ++ for boost_rtopt_ in $boost_rtopt '' -d; do ++ for boost_lib in \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_ver_ +++ boost_iostreams$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ +++ boost_iostreams$boost_tag_$boost_rtopt_$boost_ver_ \ +++ boost_iostreams$boost_tag_$boost_mt_$boost_ver_ \ +++ boost_iostreams$boost_tag_$boost_ver_ ++ do ++ # Avoid testing twice the same lib ++ case $boost_failed_libs in #( ++- (*@$boost_lib@*) continue;; +++ *@$boost_lib@*) continue;; ++ esac ++ # If with_boost is empty, we'll search in /lib first, which is not quite ++ # right so instead we'll try to a location based on where the headers are. ++@@ -17242,17 +16718,14 @@ ++ /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ ++ "$with_boost" C:/Boost/lib /lib* ++ do ++- # Don't waste time with directories that don't exist. ++- if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then ++- continue ++- fi +++ test -e "$boost_ldpath" || continue ++ boost_save_LDFLAGS=$LDFLAGS ++ # Are we looking for a static library? ++ case $boost_ldpath:$boost_rtopt_ in #( ++- (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) +++ *?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) ++ boost_cv_lib_iostreams_LIBS="$boost_ldpath/lib$boost_lib.$libext" ++ test -e "$boost_cv_lib_iostreams_LIBS" || continue;; #( ++- (*) # No: use -lboost_foo to find the shared library. +++ *) # No: use -lboost_foo to find the shared library. ++ boost_cv_lib_iostreams_LIBS="-l$boost_lib";; ++ esac ++ boost_save_LIBS=$LIBS ++@@ -17281,11 +16754,11 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++ boost_cv_lib_iostreams=yes ++ else ++@@ -17304,22 +16777,17 @@ ++ LDFLAGS=$boost_save_LDFLAGS ++ LIBS=$boost_save_LIBS ++ if test x"$boost_cv_lib_iostreams" = xyes; then ++- # Check or used cached result of whether or not using -R or ++- # -rpath makes sense. Some implementations of ld, such as for ++- # Mac OSX, require -rpath but -R is the flag known to work on ++- # other systems. https://github.com/tsuna/boost.m4/issues/19 +++ # Check or used cached result of whether or not using -R or -rpath makes sense. +++ # Some implementations of ld, such as for Mac OSX, require -rpath but +++ # -R is the flag known to work on other systems. +++ # https://github.com/tsuna/boost.m4/issues/19 ++ if ${boost_cv_rpath_link_ldflag+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- case $boost_ldpath in ++- '') # Nothing to do. ++- boost_cv_rpath_link_ldflag= ++- boost_rpath_link_ldflag_found=yes;; ++- *) ++- for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do ++- LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- LIBS="$boost_save_LIBS $boost_cv_lib_iostreams_LIBS" ++- rm -f conftest$ac_exeext +++ for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do +++ LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ LIBS="$boost_save_LIBS $boost_cv_lib_iostreams_LIBS" +++ rm -f conftest$ac_exeext ++ boost_save_ac_ext=$ac_ext ++ boost_use_source=: ++ # If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++@@ -17342,14 +16810,14 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++ boost_rpath_link_ldflag_found=yes ++- break +++ break ++ else ++ if $boost_use_source; then ++ $as_echo "$as_me: failed program was:" >&5 ++@@ -17362,9 +16830,7 @@ ++ ac_ext=$boost_save_ac_ext ++ rm -f core conftest.err conftest_ipa8_conftest.oo \ ++ conftest$ac_exeext ++- done ++- ;; ++- esac +++ done ++ if test "x$boost_rpath_link_ldflag_found" != "xyes"; then : ++ as_fn_error $? "Unable to determine whether to use -R or -rpath" "$LINENO" 5 ++ fi ++@@ -17373,10 +16839,9 @@ ++ ++ fi ++ ++- test x"$boost_ldpath" != x && ++- boost_cv_lib_iostreams_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ boost_cv_lib_iostreams_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++ boost_cv_lib_iostreams_LDPATH="$boost_ldpath" ++- break 7 +++ break 6 ++ else ++ boost_failed_libs="$boost_failed_libs@$boost_lib@" ++ fi ++@@ -17386,314 +16851,22 @@ ++ done ++ done ++ done ++-done # boost_lib_ ++ rm -f conftest.$ac_objext ++ ++ fi ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_iostreams" >&5 ++ $as_echo "$boost_cv_lib_iostreams" >&6; } ++ case $boost_cv_lib_iostreams in #( ++- (no) $as_echo "$as_me: failed program was:" >&5 +++ no) $as_echo "$as_me: failed program was:" >&5 ++ sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ as_fn_error $? "cannot find the flags to link with Boost iostreams" "$LINENO" 5 ++ ;; ++ esac ++-BOOST_IOSTREAMS_LDFLAGS=$boost_cv_lib_iostreams_LDFLAGS ++-BOOST_IOSTREAMS_LDPATH=$boost_cv_lib_iostreams_LDPATH ++-BOOST_LDPATH=$boost_cv_lib_iostreams_LDPATH ++-BOOST_IOSTREAMS_LIBS=$boost_cv_lib_iostreams_LIBS ++-CPPFLAGS=$boost_save_CPPFLAGS ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-fi ++- ++- ++- ++- ++-fi ++- ++-if test "x$with_tools" != "xno"; then : ++- ++- if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost program_options library" >&5 ++-$as_echo "$as_me: Boost not available, not searching for the Boost program_options library" >&6;} ++-else ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/program_options.hpp" >&5 ++-$as_echo "$as_me: Boost not available, not searching for boost/program_options.hpp" >&6;} ++-else ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-boost_save_CPPFLAGS=$CPPFLAGS ++-CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-ac_fn_cxx_check_header_mongrel "$LINENO" "boost/program_options.hpp" "ac_cv_header_boost_program_options_hpp" "$ac_includes_default" ++-if test "x$ac_cv_header_boost_program_options_hpp" = xyes; then : ++- ++-$as_echo "#define HAVE_BOOST_PROGRAM_OPTIONS_HPP 1" >>confdefs.h ++- ++-else ++- as_fn_error $? "cannot find boost/program_options.hpp" "$LINENO" 5 ++-fi ++- ++- ++-CPPFLAGS=$boost_save_CPPFLAGS ++-ac_ext=cpp ++-ac_cpp='$CXXCPP $CPPFLAGS' ++-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++-fi ++- ++-boost_save_CPPFLAGS=$CPPFLAGS ++-CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost program_options library" >&5 ++-$as_echo_n "checking for the Boost program_options library... " >&6; } ++-if ${boost_cv_lib_program_options+:} false; then : ++- $as_echo_n "(cached) " >&6 ++-else ++- boost_cv_lib_program_options=no ++- case "" in #( ++- (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( ++- (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( ++- (*) boost_mt=; boost_rtopt=;; ++- esac ++- if test $enable_static_boost = yes; then ++- boost_rtopt="s$boost_rtopt" ++- fi ++- # Find the proper debug variant depending on what we've been asked to find. ++- case $boost_rtopt in #( ++- (*d*) boost_rt_d=$boost_rtopt;; #( ++- (*[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') ++- boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( ++- (*) boost_rt_d='-d';; ++- esac ++- # If the PREFERRED-RT-OPT are not empty, prepend a `-'. ++- test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" ++- $boost_guess_use_mt && boost_mt=-mt ++- # Look for the abs path the static archive. ++- # $libext is computed by Libtool but let's make sure it's non empty. ++- test -z "$libext" && ++- as_fn_error $? "the libext variable is empty, did you invoke Libtool?" "$LINENO" 5 ++- boost_save_ac_objext=$ac_objext ++- # Generate the test file. ++- cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++-/* end confdefs.h. */ ++-#include ++- ++-int ++-main () ++-{ ++-boost::program_options::options_description d("test"); ++- ; ++- return 0; ++-} ++-_ACEOF ++- if ac_fn_cxx_try_compile "$LINENO"; then : ++- ac_objext=do_not_rm_me_plz ++-else ++- as_fn_error $? "cannot compile a test that uses Boost program_options" "$LINENO" 5 ++-fi ++-rm -f core conftest.err conftest.$ac_objext ++- ac_objext=$boost_save_ac_objext ++- boost_failed_libs= ++-# Don't bother to ident the following nested for loops, only the 2 ++-# innermost ones matter. ++-for boost_lib_ in program_options; do ++-for boost_tag_ in -$boost_cv_lib_tag ''; do ++-for boost_ver_ in -$boost_cv_lib_version ''; do ++-for boost_mt_ in $boost_mt -mt ''; do ++-for boost_rtopt_ in $boost_rtopt '' -d; do ++- for boost_lib in \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_ver_ ++- do ++- # Avoid testing twice the same lib ++- case $boost_failed_libs in #( ++- (*@$boost_lib@*) continue;; ++- esac ++- # If with_boost is empty, we'll search in /lib first, which is not quite ++- # right so instead we'll try to a location based on where the headers are. ++- boost_tmp_lib=$with_boost ++- test x"$with_boost" = x && boost_tmp_lib=${boost_cv_inc_path%/include} ++- for boost_ldpath in "$boost_tmp_lib/lib" '' \ ++- /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ ++- "$with_boost" C:/Boost/lib /lib* ++- do ++- # Don't waste time with directories that don't exist. ++- if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then ++- continue ++- fi ++- boost_save_LDFLAGS=$LDFLAGS ++- # Are we looking for a static library? ++- case $boost_ldpath:$boost_rtopt_ in #( ++- (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) ++- boost_cv_lib_program_options_LIBS="$boost_ldpath/lib$boost_lib.$libext" ++- test -e "$boost_cv_lib_program_options_LIBS" || continue;; #( ++- (*) # No: use -lboost_foo to find the shared library. ++- boost_cv_lib_program_options_LIBS="-l$boost_lib";; ++- esac ++- boost_save_LIBS=$LIBS ++- LIBS="$boost_cv_lib_program_options_LIBS $LIBS" ++- test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" ++- rm -f conftest$ac_exeext ++-boost_save_ac_ext=$ac_ext ++-boost_use_source=: ++-# If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++-# tries to link the existing object file instead of compiling from source. ++-test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && ++- $as_echo "$as_me:${as_lineno-$LINENO}: re-using the existing conftest.$ac_objext" >&5 ++-if { { ac_try="$ac_link" ++-case "(($ac_try" in ++- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++- *) ac_try_echo=$ac_try;; ++-esac ++-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++-$as_echo "$ac_try_echo"; } >&5 ++- (eval "$ac_link") 2>conftest.err ++- ac_status=$? ++- if test -s conftest.err; then ++- grep -v '^ *+' conftest.err >conftest.er1 ++- cat conftest.er1 >&5 ++- mv -f conftest.er1 conftest.err ++- fi ++- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++- test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err ++- } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext ++- }; then : ++- boost_cv_lib_program_options=yes ++-else ++- if $boost_use_source; then ++- $as_echo "$as_me: failed program was:" >&5 ++-sed 's/^/| /' conftest.$ac_ext >&5 ++- ++- fi ++- boost_cv_lib_program_options=no ++-fi ++-ac_objext=$boost_save_ac_objext ++-ac_ext=$boost_save_ac_ext ++-rm -f core conftest.err conftest_ipa8_conftest.oo \ ++- conftest$ac_exeext ++- ac_objext=$boost_save_ac_objext ++- LDFLAGS=$boost_save_LDFLAGS ++- LIBS=$boost_save_LIBS ++- if test x"$boost_cv_lib_program_options" = xyes; then ++- # Check or used cached result of whether or not using -R or ++- # -rpath makes sense. Some implementations of ld, such as for ++- # Mac OSX, require -rpath but -R is the flag known to work on ++- # other systems. https://github.com/tsuna/boost.m4/issues/19 ++- if ${boost_cv_rpath_link_ldflag+:} false; then : ++- $as_echo_n "(cached) " >&6 ++-else ++- case $boost_ldpath in ++- '') # Nothing to do. ++- boost_cv_rpath_link_ldflag= ++- boost_rpath_link_ldflag_found=yes;; ++- *) ++- for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do ++- LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- LIBS="$boost_save_LIBS $boost_cv_lib_program_options_LIBS" ++- rm -f conftest$ac_exeext ++-boost_save_ac_ext=$ac_ext ++-boost_use_source=: ++-# If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++-# tries to link the existing object file instead of compiling from source. ++-test -f conftest.$ac_objext && ac_ext=$ac_objext && boost_use_source=false && ++- $as_echo "$as_me:${as_lineno-$LINENO}: re-using the existing conftest.$ac_objext" >&5 ++-if { { ac_try="$ac_link" ++-case "(($ac_try" in ++- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++- *) ac_try_echo=$ac_try;; ++-esac ++-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" ++-$as_echo "$ac_try_echo"; } >&5 ++- (eval "$ac_link") 2>conftest.err ++- ac_status=$? ++- if test -s conftest.err; then ++- grep -v '^ *+' conftest.err >conftest.er1 ++- cat conftest.er1 >&5 ++- mv -f conftest.er1 conftest.err ++- fi ++- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++- test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err ++- } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext ++- }; then : ++- boost_rpath_link_ldflag_found=yes ++- break ++-else ++- if $boost_use_source; then ++- $as_echo "$as_me: failed program was:" >&5 ++-sed 's/^/| /' conftest.$ac_ext >&5 ++- ++- fi ++- boost_rpath_link_ldflag_found=no ++-fi ++-ac_objext=$boost_save_ac_objext ++-ac_ext=$boost_save_ac_ext ++-rm -f core conftest.err conftest_ipa8_conftest.oo \ ++- conftest$ac_exeext ++- done ++- ;; ++- esac ++- if test "x$boost_rpath_link_ldflag_found" != "xyes"; then : ++- as_fn_error $? "Unable to determine whether to use -R or -rpath" "$LINENO" 5 ++-fi ++- LDFLAGS=$boost_save_LDFLAGS ++- LIBS=$boost_save_LIBS ++- ++-fi ++- ++- test x"$boost_ldpath" != x && ++- boost_cv_lib_program_options_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- boost_cv_lib_program_options_LDPATH="$boost_ldpath" ++- break 7 ++- else ++- boost_failed_libs="$boost_failed_libs@$boost_lib@" ++- fi ++- done ++- done ++-done ++-done ++-done ++-done ++-done # boost_lib_ ++-rm -f conftest.$ac_objext ++- ++-fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_program_options" >&5 ++-$as_echo "$boost_cv_lib_program_options" >&6; } ++-case $boost_cv_lib_program_options in #( ++- (no) $as_echo "$as_me: failed program was:" >&5 ++-sed 's/^/| /' conftest.$ac_ext >&5 ++- ++- as_fn_error $? "cannot find the flags to link with Boost program_options" "$LINENO" 5 ++- ;; ++-esac ++-BOOST_PROGRAM_OPTIONS_LDFLAGS=$boost_cv_lib_program_options_LDFLAGS ++-BOOST_PROGRAM_OPTIONS_LDPATH=$boost_cv_lib_program_options_LDPATH ++-BOOST_LDPATH=$boost_cv_lib_program_options_LDPATH ++-BOOST_PROGRAM_OPTIONS_LIBS=$boost_cv_lib_program_options_LIBS +++BOOST_IOSTREAMS_LDFLAGS=$boost_cv_lib_iostreams_LDFLAGS +++BOOST_IOSTREAMS_LDPATH=$boost_cv_lib_iostreams_LDPATH +++BOOST_LDPATH=$boost_cv_lib_iostreams_LDPATH +++BOOST_IOSTREAMS_LIBS=$boost_cv_lib_iostreams_LIBS ++ CPPFLAGS=$boost_save_CPPFLAGS ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -17704,13 +16877,14 @@ ++ ++ ++ ++- # Do we have to check for Boost.System? This link-time dependency was ++-# added as of 1.35.0. If we have a version <1.35, we must not attempt to ++-# find Boost.System as it didn't exist by then. ++-if test $boost_major_version -ge 135; then ++- if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost system library" >&5 ++-$as_echo "$as_me: Boost not available, not searching for the Boost system library" >&6;} +++ +++fi +++ +++if test "x$with_tools" != "xno"; then : +++ +++ if test x"$boost_cv_inc_path" = xno; then +++ { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost program_options library" >&5 +++$as_echo "$as_me: Boost not available, not searching for the Boost program_options library" >&6;} ++ else ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -17718,8 +16892,8 @@ ++ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/system/error_code.hpp" >&5 ++-$as_echo "$as_me: Boost not available, not searching for boost/system/error_code.hpp" >&6;} +++ { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/program_options.hpp" >&5 +++$as_echo "$as_me: Boost not available, not searching for boost/program_options.hpp" >&6;} ++ else ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -17728,13 +16902,13 @@ ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ boost_save_CPPFLAGS=$CPPFLAGS ++ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-ac_fn_cxx_check_header_mongrel "$LINENO" "boost/system/error_code.hpp" "ac_cv_header_boost_system_error_code_hpp" "$ac_includes_default" ++-if test "x$ac_cv_header_boost_system_error_code_hpp" = xyes; then : +++ac_fn_cxx_check_header_mongrel "$LINENO" "boost/program_options.hpp" "ac_cv_header_boost_program_options_hpp" "$ac_includes_default" +++if test "x$ac_cv_header_boost_program_options_hpp" = xyes; then : ++ ++-$as_echo "#define HAVE_BOOST_SYSTEM_ERROR_CODE_HPP 1" >>confdefs.h +++$as_echo "#define HAVE_BOOST_PROGRAM_OPTIONS_HPP 1" >>confdefs.h ++ ++ else ++- as_fn_error $? "cannot find boost/system/error_code.hpp" "$LINENO" 5 +++ as_fn_error $? "cannot find boost/program_options.hpp" "$LINENO" 5 ++ fi ++ ++ ++@@ -17748,26 +16922,33 @@ ++ ++ boost_save_CPPFLAGS=$CPPFLAGS ++ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost system library" >&5 ++-$as_echo_n "checking for the Boost system library... " >&6; } ++-if ${boost_cv_lib_system+:} false; then : +++# Now let's try to find the library. The algorithm is as follows: first look +++# for a given library name according to the user's PREFERRED-RT-OPT. For each +++# library name, we prefer to use the ones that carry the tag (toolset name). +++# Each library is searched through the various standard paths were Boost is +++# usually installed. If we can't find the standard variants, we try to +++# enforce -mt (for instance on MacOSX, libboost_threads.dylib doesn't exist +++# but there's -obviously- libboost_threads-mt.dylib). +++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost program_options library" >&5 +++$as_echo_n "checking for the Boost program_options library... " >&6; } +++if ${boost_cv_lib_program_options+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- boost_cv_lib_system=no +++ boost_cv_lib_program_options=no ++ case "" in #( ++- (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( ++- (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( ++- (*) boost_mt=; boost_rtopt=;; +++ mt | mt-) boost_mt=-mt; boost_rtopt=;; #( +++ mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( +++ *) boost_mt=; boost_rtopt=;; ++ esac ++ if test $enable_static_boost = yes; then ++ boost_rtopt="s$boost_rtopt" ++ fi ++ # Find the proper debug variant depending on what we've been asked to find. ++ case $boost_rtopt in #( ++- (*d*) boost_rt_d=$boost_rtopt;; #( ++- (*[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') +++ *d*) boost_rt_d=$boost_rtopt;; #( +++ *[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') ++ boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( ++- (*) boost_rt_d='-d';; +++ *) boost_rt_d='-d';; ++ esac ++ # If the PREFERRED-RT-OPT are not empty, prepend a `-'. ++ test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" ++@@ -17780,12 +16961,12 @@ ++ # Generate the test file. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ /* end confdefs.h. */ ++-#include +++#include ++ ++ int ++ main () ++ { ++-boost::system::error_code e; e.clear(); +++boost::program_options::options_description d("test"); ++ ; ++ return 0; ++ } ++@@ -17793,27 +16974,26 @@ ++ if ac_fn_cxx_try_compile "$LINENO"; then : ++ ac_objext=do_not_rm_me_plz ++ else ++- as_fn_error $? "cannot compile a test that uses Boost system" "$LINENO" 5 +++ as_fn_error $? "cannot compile a test that uses Boost program_options" "$LINENO" 5 ++ fi ++ rm -f core conftest.err conftest.$ac_objext ++ ac_objext=$boost_save_ac_objext ++ boost_failed_libs= ++-# Don't bother to ident the following nested for loops, only the 2 ++-# innermost ones matter. ++-for boost_lib_ in system; do +++# Don't bother to ident the 6 nested for loops, only the 2 innermost ones +++# matter. ++ for boost_tag_ in -$boost_cv_lib_tag ''; do ++ for boost_ver_ in -$boost_cv_lib_version ''; do ++ for boost_mt_ in $boost_mt -mt ''; do ++ for boost_rtopt_ in $boost_rtopt '' -d; do ++ for boost_lib in \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_ver_ +++ boost_program_options$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ +++ boost_program_options$boost_tag_$boost_rtopt_$boost_ver_ \ +++ boost_program_options$boost_tag_$boost_mt_$boost_ver_ \ +++ boost_program_options$boost_tag_$boost_ver_ ++ do ++ # Avoid testing twice the same lib ++ case $boost_failed_libs in #( ++- (*@$boost_lib@*) continue;; +++ *@$boost_lib@*) continue;; ++ esac ++ # If with_boost is empty, we'll search in /lib first, which is not quite ++ # right so instead we'll try to a location based on where the headers are. ++@@ -17823,21 +17003,18 @@ ++ /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ ++ "$with_boost" C:/Boost/lib /lib* ++ do ++- # Don't waste time with directories that don't exist. ++- if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then ++- continue ++- fi +++ test -e "$boost_ldpath" || continue ++ boost_save_LDFLAGS=$LDFLAGS ++ # Are we looking for a static library? ++ case $boost_ldpath:$boost_rtopt_ in #( ++- (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) ++- boost_cv_lib_system_LIBS="$boost_ldpath/lib$boost_lib.$libext" ++- test -e "$boost_cv_lib_system_LIBS" || continue;; #( ++- (*) # No: use -lboost_foo to find the shared library. ++- boost_cv_lib_system_LIBS="-l$boost_lib";; +++ *?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) +++ boost_cv_lib_program_options_LIBS="$boost_ldpath/lib$boost_lib.$libext" +++ test -e "$boost_cv_lib_program_options_LIBS" || continue;; #( +++ *) # No: use -lboost_foo to find the shared library. +++ boost_cv_lib_program_options_LIBS="-l$boost_lib";; ++ esac ++ boost_save_LIBS=$LIBS ++- LIBS="$boost_cv_lib_system_LIBS $LIBS" +++ LIBS="$boost_cv_lib_program_options_LIBS $LIBS" ++ test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" ++ rm -f conftest$ac_exeext ++ boost_save_ac_ext=$ac_ext ++@@ -17862,20 +17039,20 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++- boost_cv_lib_system=yes +++ boost_cv_lib_program_options=yes ++ else ++ if $boost_use_source; then ++ $as_echo "$as_me: failed program was:" >&5 ++ sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ fi ++- boost_cv_lib_system=no +++ boost_cv_lib_program_options=no ++ fi ++ ac_objext=$boost_save_ac_objext ++ ac_ext=$boost_save_ac_ext ++@@ -17884,23 +17061,18 @@ ++ ac_objext=$boost_save_ac_objext ++ LDFLAGS=$boost_save_LDFLAGS ++ LIBS=$boost_save_LIBS ++- if test x"$boost_cv_lib_system" = xyes; then ++- # Check or used cached result of whether or not using -R or ++- # -rpath makes sense. Some implementations of ld, such as for ++- # Mac OSX, require -rpath but -R is the flag known to work on ++- # other systems. https://github.com/tsuna/boost.m4/issues/19 +++ if test x"$boost_cv_lib_program_options" = xyes; then +++ # Check or used cached result of whether or not using -R or -rpath makes sense. +++ # Some implementations of ld, such as for Mac OSX, require -rpath but +++ # -R is the flag known to work on other systems. +++ # https://github.com/tsuna/boost.m4/issues/19 ++ if ${boost_cv_rpath_link_ldflag+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- case $boost_ldpath in ++- '') # Nothing to do. ++- boost_cv_rpath_link_ldflag= ++- boost_rpath_link_ldflag_found=yes;; ++- *) ++- for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do ++- LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- LIBS="$boost_save_LIBS $boost_cv_lib_system_LIBS" ++- rm -f conftest$ac_exeext +++ for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do +++ LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ LIBS="$boost_save_LIBS $boost_cv_lib_program_options_LIBS" +++ rm -f conftest$ac_exeext ++ boost_save_ac_ext=$ac_ext ++ boost_use_source=: ++ # If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++@@ -17923,14 +17095,14 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++ boost_rpath_link_ldflag_found=yes ++- break +++ break ++ else ++ if $boost_use_source; then ++ $as_echo "$as_me: failed program was:" >&5 ++@@ -17943,9 +17115,7 @@ ++ ac_ext=$boost_save_ac_ext ++ rm -f core conftest.err conftest_ipa8_conftest.oo \ ++ conftest$ac_exeext ++- done ++- ;; ++- esac +++ done ++ if test "x$boost_rpath_link_ldflag_found" != "xyes"; then : ++ as_fn_error $? "Unable to determine whether to use -R or -rpath" "$LINENO" 5 ++ fi ++@@ -17954,10 +17124,9 @@ ++ ++ fi ++ ++- test x"$boost_ldpath" != x && ++- boost_cv_lib_system_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- boost_cv_lib_system_LDPATH="$boost_ldpath" ++- break 7 +++ boost_cv_lib_program_options_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ boost_cv_lib_program_options_LDPATH="$boost_ldpath" +++ break 6 ++ else ++ boost_failed_libs="$boost_failed_libs@$boost_lib@" ++ fi ++@@ -17967,23 +17136,22 @@ ++ done ++ done ++ done ++-done # boost_lib_ ++ rm -f conftest.$ac_objext ++ ++ fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_system" >&5 ++-$as_echo "$boost_cv_lib_system" >&6; } ++-case $boost_cv_lib_system in #( ++- (no) $as_echo "$as_me: failed program was:" >&5 +++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_program_options" >&5 +++$as_echo "$boost_cv_lib_program_options" >&6; } +++case $boost_cv_lib_program_options in #( +++ no) $as_echo "$as_me: failed program was:" >&5 ++ sed 's/^/| /' conftest.$ac_ext >&5 ++ ++- as_fn_error $? "cannot find the flags to link with Boost system" "$LINENO" 5 +++ as_fn_error $? "cannot find the flags to link with Boost program_options" "$LINENO" 5 ++ ;; ++ esac ++-BOOST_SYSTEM_LDFLAGS=$boost_cv_lib_system_LDFLAGS ++-BOOST_SYSTEM_LDPATH=$boost_cv_lib_system_LDPATH ++-BOOST_LDPATH=$boost_cv_lib_system_LDPATH ++-BOOST_SYSTEM_LIBS=$boost_cv_lib_system_LIBS +++BOOST_PROGRAM_OPTIONS_LDFLAGS=$boost_cv_lib_program_options_LDFLAGS +++BOOST_PROGRAM_OPTIONS_LDPATH=$boost_cv_lib_program_options_LDPATH +++BOOST_LDPATH=$boost_cv_lib_program_options_LDPATH +++BOOST_PROGRAM_OPTIONS_LIBS=$boost_cv_lib_program_options_LIBS ++ CPPFLAGS=$boost_save_CPPFLAGS ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -17994,14 +17162,13 @@ ++ ++ ++ ++-fi # end of the Boost.System check. ++-boost_filesystem_save_LIBS=$LIBS ++-boost_filesystem_save_LDFLAGS=$LDFLAGS ++-LIBS="$LIBS $BOOST_SYSTEM_LIBS" ++-LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +++ # Do we have to check for Boost.System? This link-time dependency was +++# added as of 1.35.0. If we have a version <1.35, we must not attempt to +++# find Boost.System as it didn't exist by then. +++if test $boost_major_version -ge 135; then ++ if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost filesystem library" >&5 ++-$as_echo "$as_me: Boost not available, not searching for the Boost filesystem library" >&6;} +++ { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost system library" >&5 +++$as_echo "$as_me: Boost not available, not searching for the Boost system library" >&6;} ++ else ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -18009,8 +17176,8 @@ ++ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/filesystem/path.hpp" >&5 ++-$as_echo "$as_me: Boost not available, not searching for boost/filesystem/path.hpp" >&6;} +++ { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/system/error_code.hpp" >&5 +++$as_echo "$as_me: Boost not available, not searching for boost/system/error_code.hpp" >&6;} ++ else ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -18019,13 +17186,13 @@ ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ boost_save_CPPFLAGS=$CPPFLAGS ++ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-ac_fn_cxx_check_header_mongrel "$LINENO" "boost/filesystem/path.hpp" "ac_cv_header_boost_filesystem_path_hpp" "$ac_includes_default" ++-if test "x$ac_cv_header_boost_filesystem_path_hpp" = xyes; then : +++ac_fn_cxx_check_header_mongrel "$LINENO" "boost/system/error_code.hpp" "ac_cv_header_boost_system_error_code_hpp" "$ac_includes_default" +++if test "x$ac_cv_header_boost_system_error_code_hpp" = xyes; then : ++ ++-$as_echo "#define HAVE_BOOST_FILESYSTEM_PATH_HPP 1" >>confdefs.h +++$as_echo "#define HAVE_BOOST_SYSTEM_ERROR_CODE_HPP 1" >>confdefs.h ++ ++ else ++- as_fn_error $? "cannot find boost/filesystem/path.hpp" "$LINENO" 5 +++ as_fn_error $? "cannot find boost/system/error_code.hpp" "$LINENO" 5 ++ fi ++ ++ ++@@ -18039,26 +17206,33 @@ ++ ++ boost_save_CPPFLAGS=$CPPFLAGS ++ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost filesystem library" >&5 ++-$as_echo_n "checking for the Boost filesystem library... " >&6; } ++-if ${boost_cv_lib_filesystem+:} false; then : +++# Now let's try to find the library. The algorithm is as follows: first look +++# for a given library name according to the user's PREFERRED-RT-OPT. For each +++# library name, we prefer to use the ones that carry the tag (toolset name). +++# Each library is searched through the various standard paths were Boost is +++# usually installed. If we can't find the standard variants, we try to +++# enforce -mt (for instance on MacOSX, libboost_threads.dylib doesn't exist +++# but there's -obviously- libboost_threads-mt.dylib). +++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost system library" >&5 +++$as_echo_n "checking for the Boost system library... " >&6; } +++if ${boost_cv_lib_system+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- boost_cv_lib_filesystem=no +++ boost_cv_lib_system=no ++ case "" in #( ++- (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( ++- (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( ++- (*) boost_mt=; boost_rtopt=;; +++ mt | mt-) boost_mt=-mt; boost_rtopt=;; #( +++ mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( +++ *) boost_mt=; boost_rtopt=;; ++ esac ++ if test $enable_static_boost = yes; then ++ boost_rtopt="s$boost_rtopt" ++ fi ++ # Find the proper debug variant depending on what we've been asked to find. ++ case $boost_rtopt in #( ++- (*d*) boost_rt_d=$boost_rtopt;; #( ++- (*[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') +++ *d*) boost_rt_d=$boost_rtopt;; #( +++ *[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') ++ boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( ++- (*) boost_rt_d='-d';; +++ *) boost_rt_d='-d';; ++ esac ++ # If the PREFERRED-RT-OPT are not empty, prepend a `-'. ++ test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" ++@@ -18071,12 +17245,12 @@ ++ # Generate the test file. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ /* end confdefs.h. */ ++-#include +++#include ++ ++ int ++ main () ++ { ++-boost::filesystem::path p; +++boost::system::error_code e; e.clear(); ++ ; ++ return 0; ++ } ++@@ -18084,27 +17258,26 @@ ++ if ac_fn_cxx_try_compile "$LINENO"; then : ++ ac_objext=do_not_rm_me_plz ++ else ++- as_fn_error $? "cannot compile a test that uses Boost filesystem" "$LINENO" 5 +++ as_fn_error $? "cannot compile a test that uses Boost system" "$LINENO" 5 ++ fi ++ rm -f core conftest.err conftest.$ac_objext ++ ac_objext=$boost_save_ac_objext ++ boost_failed_libs= ++-# Don't bother to ident the following nested for loops, only the 2 ++-# innermost ones matter. ++-for boost_lib_ in filesystem; do +++# Don't bother to ident the 6 nested for loops, only the 2 innermost ones +++# matter. ++ for boost_tag_ in -$boost_cv_lib_tag ''; do ++ for boost_ver_ in -$boost_cv_lib_version ''; do ++ for boost_mt_ in $boost_mt -mt ''; do ++ for boost_rtopt_ in $boost_rtopt '' -d; do ++ for boost_lib in \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_ver_ +++ boost_system$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ +++ boost_system$boost_tag_$boost_rtopt_$boost_ver_ \ +++ boost_system$boost_tag_$boost_mt_$boost_ver_ \ +++ boost_system$boost_tag_$boost_ver_ ++ do ++ # Avoid testing twice the same lib ++ case $boost_failed_libs in #( ++- (*@$boost_lib@*) continue;; +++ *@$boost_lib@*) continue;; ++ esac ++ # If with_boost is empty, we'll search in /lib first, which is not quite ++ # right so instead we'll try to a location based on where the headers are. ++@@ -18114,21 +17287,18 @@ ++ /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ ++ "$with_boost" C:/Boost/lib /lib* ++ do ++- # Don't waste time with directories that don't exist. ++- if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then ++- continue ++- fi +++ test -e "$boost_ldpath" || continue ++ boost_save_LDFLAGS=$LDFLAGS ++ # Are we looking for a static library? ++ case $boost_ldpath:$boost_rtopt_ in #( ++- (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) ++- boost_cv_lib_filesystem_LIBS="$boost_ldpath/lib$boost_lib.$libext" ++- test -e "$boost_cv_lib_filesystem_LIBS" || continue;; #( ++- (*) # No: use -lboost_foo to find the shared library. ++- boost_cv_lib_filesystem_LIBS="-l$boost_lib";; +++ *?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) +++ boost_cv_lib_system_LIBS="$boost_ldpath/lib$boost_lib.$libext" +++ test -e "$boost_cv_lib_system_LIBS" || continue;; #( +++ *) # No: use -lboost_foo to find the shared library. +++ boost_cv_lib_system_LIBS="-l$boost_lib";; ++ esac ++ boost_save_LIBS=$LIBS ++- LIBS="$boost_cv_lib_filesystem_LIBS $LIBS" +++ LIBS="$boost_cv_lib_system_LIBS $LIBS" ++ test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" ++ rm -f conftest$ac_exeext ++ boost_save_ac_ext=$ac_ext ++@@ -18153,20 +17323,20 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++- boost_cv_lib_filesystem=yes +++ boost_cv_lib_system=yes ++ else ++ if $boost_use_source; then ++ $as_echo "$as_me: failed program was:" >&5 ++ sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ fi ++- boost_cv_lib_filesystem=no +++ boost_cv_lib_system=no ++ fi ++ ac_objext=$boost_save_ac_objext ++ ac_ext=$boost_save_ac_ext ++@@ -18175,23 +17345,18 @@ ++ ac_objext=$boost_save_ac_objext ++ LDFLAGS=$boost_save_LDFLAGS ++ LIBS=$boost_save_LIBS ++- if test x"$boost_cv_lib_filesystem" = xyes; then ++- # Check or used cached result of whether or not using -R or ++- # -rpath makes sense. Some implementations of ld, such as for ++- # Mac OSX, require -rpath but -R is the flag known to work on ++- # other systems. https://github.com/tsuna/boost.m4/issues/19 +++ if test x"$boost_cv_lib_system" = xyes; then +++ # Check or used cached result of whether or not using -R or -rpath makes sense. +++ # Some implementations of ld, such as for Mac OSX, require -rpath but +++ # -R is the flag known to work on other systems. +++ # https://github.com/tsuna/boost.m4/issues/19 ++ if ${boost_cv_rpath_link_ldflag+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- case $boost_ldpath in ++- '') # Nothing to do. ++- boost_cv_rpath_link_ldflag= ++- boost_rpath_link_ldflag_found=yes;; ++- *) ++- for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do ++- LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- LIBS="$boost_save_LIBS $boost_cv_lib_filesystem_LIBS" ++- rm -f conftest$ac_exeext +++ for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do +++ LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ LIBS="$boost_save_LIBS $boost_cv_lib_system_LIBS" +++ rm -f conftest$ac_exeext ++ boost_save_ac_ext=$ac_ext ++ boost_use_source=: ++ # If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++@@ -18214,14 +17379,14 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++ boost_rpath_link_ldflag_found=yes ++- break +++ break ++ else ++ if $boost_use_source; then ++ $as_echo "$as_me: failed program was:" >&5 ++@@ -18234,9 +17399,7 @@ ++ ac_ext=$boost_save_ac_ext ++ rm -f core conftest.err conftest_ipa8_conftest.oo \ ++ conftest$ac_exeext ++- done ++- ;; ++- esac +++ done ++ if test "x$boost_rpath_link_ldflag_found" != "xyes"; then : ++ as_fn_error $? "Unable to determine whether to use -R or -rpath" "$LINENO" 5 ++ fi ++@@ -18245,10 +17408,9 @@ ++ ++ fi ++ ++- test x"$boost_ldpath" != x && ++- boost_cv_lib_filesystem_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- boost_cv_lib_filesystem_LDPATH="$boost_ldpath" ++- break 7 +++ boost_cv_lib_system_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ boost_cv_lib_system_LDPATH="$boost_ldpath" +++ break 6 ++ else ++ boost_failed_libs="$boost_failed_libs@$boost_lib@" ++ fi ++@@ -18258,23 +17420,22 @@ ++ done ++ done ++ done ++-done # boost_lib_ ++ rm -f conftest.$ac_objext ++ ++ fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_filesystem" >&5 ++-$as_echo "$boost_cv_lib_filesystem" >&6; } ++-case $boost_cv_lib_filesystem in #( ++- (no) $as_echo "$as_me: failed program was:" >&5 +++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_system" >&5 +++$as_echo "$boost_cv_lib_system" >&6; } +++case $boost_cv_lib_system in #( +++ no) $as_echo "$as_me: failed program was:" >&5 ++ sed 's/^/| /' conftest.$ac_ext >&5 ++ ++- as_fn_error $? "cannot find the flags to link with Boost filesystem" "$LINENO" 5 +++ as_fn_error $? "cannot find the flags to link with Boost system" "$LINENO" 5 ++ ;; ++ esac ++-BOOST_FILESYSTEM_LDFLAGS=$boost_cv_lib_filesystem_LDFLAGS ++-BOOST_FILESYSTEM_LDPATH=$boost_cv_lib_filesystem_LDPATH ++-BOOST_LDPATH=$boost_cv_lib_filesystem_LDPATH ++-BOOST_FILESYSTEM_LIBS=$boost_cv_lib_filesystem_LIBS +++BOOST_SYSTEM_LDFLAGS=$boost_cv_lib_system_LDFLAGS +++BOOST_SYSTEM_LDPATH=$boost_cv_lib_system_LDPATH +++BOOST_LDPATH=$boost_cv_lib_system_LDPATH +++BOOST_SYSTEM_LIBS=$boost_cv_lib_system_LIBS ++ CPPFLAGS=$boost_save_CPPFLAGS ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -18283,16 +17444,16 @@ ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ fi ++ ++-if test $enable_static_boost = yes && test $boost_major_version -ge 135; then ++- BOOST_FILESYSTEM_LIBS="$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" ++-fi ++-LIBS=$boost_filesystem_save_LIBS ++-LDFLAGS=$boost_filesystem_save_LDFLAGS ++ ++ ++- if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost system library" >&5 ++-$as_echo "$as_me: Boost not available, not searching for the Boost system library" >&6;} +++fi # end of the Boost.System check. +++boost_filesystem_save_LIBS=$LIBS +++boost_filesystem_save_LDFLAGS=$LDFLAGS +++LIBS="$LIBS $BOOST_SYSTEM_LIBS" +++LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LDFLAGS" +++if test x"$boost_cv_inc_path" = xno; then +++ { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for the Boost filesystem library" >&5 +++$as_echo "$as_me: Boost not available, not searching for the Boost filesystem library" >&6;} ++ else ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -18300,8 +17461,8 @@ ++ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ if test x"$boost_cv_inc_path" = xno; then ++- { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/system/error_code.hpp" >&5 ++-$as_echo "$as_me: Boost not available, not searching for boost/system/error_code.hpp" >&6;} +++ { $as_echo "$as_me:${as_lineno-$LINENO}: Boost not available, not searching for boost/filesystem/path.hpp" >&5 +++$as_echo "$as_me: Boost not available, not searching for boost/filesystem/path.hpp" >&6;} ++ else ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -18310,13 +17471,13 @@ ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ boost_save_CPPFLAGS=$CPPFLAGS ++ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-ac_fn_cxx_check_header_mongrel "$LINENO" "boost/system/error_code.hpp" "ac_cv_header_boost_system_error_code_hpp" "$ac_includes_default" ++-if test "x$ac_cv_header_boost_system_error_code_hpp" = xyes; then : +++ac_fn_cxx_check_header_mongrel "$LINENO" "boost/filesystem/path.hpp" "ac_cv_header_boost_filesystem_path_hpp" "$ac_includes_default" +++if test "x$ac_cv_header_boost_filesystem_path_hpp" = xyes; then : ++ ++-$as_echo "#define HAVE_BOOST_SYSTEM_ERROR_CODE_HPP 1" >>confdefs.h +++$as_echo "#define HAVE_BOOST_FILESYSTEM_PATH_HPP 1" >>confdefs.h ++ ++ else ++- as_fn_error $? "cannot find boost/system/error_code.hpp" "$LINENO" 5 +++ as_fn_error $? "cannot find boost/filesystem/path.hpp" "$LINENO" 5 ++ fi ++ ++ ++@@ -18330,26 +17491,33 @@ ++ ++ boost_save_CPPFLAGS=$CPPFLAGS ++ CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost system library" >&5 ++-$as_echo_n "checking for the Boost system library... " >&6; } ++-if ${boost_cv_lib_system+:} false; then : +++# Now let's try to find the library. The algorithm is as follows: first look +++# for a given library name according to the user's PREFERRED-RT-OPT. For each +++# library name, we prefer to use the ones that carry the tag (toolset name). +++# Each library is searched through the various standard paths were Boost is +++# usually installed. If we can't find the standard variants, we try to +++# enforce -mt (for instance on MacOSX, libboost_threads.dylib doesn't exist +++# but there's -obviously- libboost_threads-mt.dylib). +++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Boost filesystem library" >&5 +++$as_echo_n "checking for the Boost filesystem library... " >&6; } +++if ${boost_cv_lib_filesystem+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- boost_cv_lib_system=no +++ boost_cv_lib_filesystem=no ++ case "" in #( ++- (mt | mt-) boost_mt=-mt; boost_rtopt=;; #( ++- (mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( ++- (*) boost_mt=; boost_rtopt=;; +++ mt | mt-) boost_mt=-mt; boost_rtopt=;; #( +++ mt* | mt-*) boost_mt=-mt; boost_rtopt=`expr "X" : 'Xmt-*\(.*\)'`;; #( +++ *) boost_mt=; boost_rtopt=;; ++ esac ++ if test $enable_static_boost = yes; then ++ boost_rtopt="s$boost_rtopt" ++ fi ++ # Find the proper debug variant depending on what we've been asked to find. ++ case $boost_rtopt in #( ++- (*d*) boost_rt_d=$boost_rtopt;; #( ++- (*[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') +++ *d*) boost_rt_d=$boost_rtopt;; #( +++ *[sgpn]*) # Insert the `d' at the right place (in between `sg' and `pn') ++ boost_rt_d=`echo "$boost_rtopt" | sed 's/\(s*g*\)\(p*n*\)/\1\2/'`;; #( ++- (*) boost_rt_d='-d';; +++ *) boost_rt_d='-d';; ++ esac ++ # If the PREFERRED-RT-OPT are not empty, prepend a `-'. ++ test -n "$boost_rtopt" && boost_rtopt="-$boost_rtopt" ++@@ -18362,12 +17530,12 @@ ++ # Generate the test file. ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++ /* end confdefs.h. */ ++-#include +++#include ++ ++ int ++ main () ++ { ++-boost::system::error_code e; e.clear(); +++boost::filesystem::path p; ++ ; ++ return 0; ++ } ++@@ -18375,27 +17543,26 @@ ++ if ac_fn_cxx_try_compile "$LINENO"; then : ++ ac_objext=do_not_rm_me_plz ++ else ++- as_fn_error $? "cannot compile a test that uses Boost system" "$LINENO" 5 +++ as_fn_error $? "cannot compile a test that uses Boost filesystem" "$LINENO" 5 ++ fi ++ rm -f core conftest.err conftest.$ac_objext ++ ac_objext=$boost_save_ac_objext ++ boost_failed_libs= ++-# Don't bother to ident the following nested for loops, only the 2 ++-# innermost ones matter. ++-for boost_lib_ in system; do +++# Don't bother to ident the 6 nested for loops, only the 2 innermost ones +++# matter. ++ for boost_tag_ in -$boost_cv_lib_tag ''; do ++ for boost_ver_ in -$boost_cv_lib_version ''; do ++ for boost_mt_ in $boost_mt -mt ''; do ++ for boost_rtopt_ in $boost_rtopt '' -d; do ++ for boost_lib in \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_rtopt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_mt_$boost_ver_ \ ++- boost_$boost_lib_$boost_tag_$boost_ver_ +++ boost_filesystem$boost_tag_$boost_mt_$boost_rtopt_$boost_ver_ \ +++ boost_filesystem$boost_tag_$boost_rtopt_$boost_ver_ \ +++ boost_filesystem$boost_tag_$boost_mt_$boost_ver_ \ +++ boost_filesystem$boost_tag_$boost_ver_ ++ do ++ # Avoid testing twice the same lib ++ case $boost_failed_libs in #( ++- (*@$boost_lib@*) continue;; +++ *@$boost_lib@*) continue;; ++ esac ++ # If with_boost is empty, we'll search in /lib first, which is not quite ++ # right so instead we'll try to a location based on where the headers are. ++@@ -18405,21 +17572,18 @@ ++ /opt/local/lib* /usr/local/lib* /opt/lib* /usr/lib* \ ++ "$with_boost" C:/Boost/lib /lib* ++ do ++- # Don't waste time with directories that don't exist. ++- if test x"$boost_ldpath" != x && test ! -e "$boost_ldpath"; then ++- continue ++- fi +++ test -e "$boost_ldpath" || continue ++ boost_save_LDFLAGS=$LDFLAGS ++ # Are we looking for a static library? ++ case $boost_ldpath:$boost_rtopt_ in #( ++- (*?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) ++- boost_cv_lib_system_LIBS="$boost_ldpath/lib$boost_lib.$libext" ++- test -e "$boost_cv_lib_system_LIBS" || continue;; #( ++- (*) # No: use -lboost_foo to find the shared library. ++- boost_cv_lib_system_LIBS="-l$boost_lib";; +++ *?*:*s*) # Yes (Non empty boost_ldpath + s in rt opt) +++ boost_cv_lib_filesystem_LIBS="$boost_ldpath/lib$boost_lib.$libext" +++ test -e "$boost_cv_lib_filesystem_LIBS" || continue;; #( +++ *) # No: use -lboost_foo to find the shared library. +++ boost_cv_lib_filesystem_LIBS="-l$boost_lib";; ++ esac ++ boost_save_LIBS=$LIBS ++- LIBS="$boost_cv_lib_system_LIBS $LIBS" +++ LIBS="$boost_cv_lib_filesystem_LIBS $LIBS" ++ test x"$boost_ldpath" != x && LDFLAGS="$LDFLAGS -L$boost_ldpath" ++ rm -f conftest$ac_exeext ++ boost_save_ac_ext=$ac_ext ++@@ -18444,20 +17608,20 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++- boost_cv_lib_system=yes +++ boost_cv_lib_filesystem=yes ++ else ++ if $boost_use_source; then ++ $as_echo "$as_me: failed program was:" >&5 ++ sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ fi ++- boost_cv_lib_system=no +++ boost_cv_lib_filesystem=no ++ fi ++ ac_objext=$boost_save_ac_objext ++ ac_ext=$boost_save_ac_ext ++@@ -18466,23 +17630,18 @@ ++ ac_objext=$boost_save_ac_objext ++ LDFLAGS=$boost_save_LDFLAGS ++ LIBS=$boost_save_LIBS ++- if test x"$boost_cv_lib_system" = xyes; then ++- # Check or used cached result of whether or not using -R or ++- # -rpath makes sense. Some implementations of ld, such as for ++- # Mac OSX, require -rpath but -R is the flag known to work on ++- # other systems. https://github.com/tsuna/boost.m4/issues/19 +++ if test x"$boost_cv_lib_filesystem" = xyes; then +++ # Check or used cached result of whether or not using -R or -rpath makes sense. +++ # Some implementations of ld, such as for Mac OSX, require -rpath but +++ # -R is the flag known to work on other systems. +++ # https://github.com/tsuna/boost.m4/issues/19 ++ if ${boost_cv_rpath_link_ldflag+:} false; then : ++ $as_echo_n "(cached) " >&6 ++ else ++- case $boost_ldpath in ++- '') # Nothing to do. ++- boost_cv_rpath_link_ldflag= ++- boost_rpath_link_ldflag_found=yes;; ++- *) ++- for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do ++- LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- LIBS="$boost_save_LIBS $boost_cv_lib_system_LIBS" ++- rm -f conftest$ac_exeext +++ for boost_cv_rpath_link_ldflag in -Wl,-R, -Wl,-rpath,; do +++ LDFLAGS="$boost_save_LDFLAGS -L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ LIBS="$boost_save_LIBS $boost_cv_lib_filesystem_LIBS" +++ rm -f conftest$ac_exeext ++ boost_save_ac_ext=$ac_ext ++ boost_use_source=: ++ # If we already have a .o, re-use it. We change $ac_ext so that $ac_link ++@@ -18505,14 +17664,14 @@ ++ fi ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; } && { ++- test -z "$ac_cxx_werror_flag" || ++- test ! -s conftest.err +++ test -z "$ac_cxx_werror_flag" || +++ test ! -s conftest.err ++ } && test -s conftest$ac_exeext && { ++- test "$cross_compiling" = yes || ++- $as_executable_p conftest$ac_exeext +++ test "$cross_compiling" = yes || +++ $as_executable_p conftest$ac_exeext ++ }; then : ++ boost_rpath_link_ldflag_found=yes ++- break +++ break ++ else ++ if $boost_use_source; then ++ $as_echo "$as_me: failed program was:" >&5 ++@@ -18525,9 +17684,7 @@ ++ ac_ext=$boost_save_ac_ext ++ rm -f core conftest.err conftest_ipa8_conftest.oo \ ++ conftest$ac_exeext ++- done ++- ;; ++- esac +++ done ++ if test "x$boost_rpath_link_ldflag_found" != "xyes"; then : ++ as_fn_error $? "Unable to determine whether to use -R or -rpath" "$LINENO" 5 ++ fi ++@@ -18536,10 +17693,9 @@ ++ ++ fi ++ ++- test x"$boost_ldpath" != x && ++- boost_cv_lib_system_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" ++- boost_cv_lib_system_LDPATH="$boost_ldpath" ++- break 7 +++ boost_cv_lib_filesystem_LDFLAGS="-L$boost_ldpath $boost_cv_rpath_link_ldflag$boost_ldpath" +++ boost_cv_lib_filesystem_LDPATH="$boost_ldpath" +++ break 6 ++ else ++ boost_failed_libs="$boost_failed_libs@$boost_lib@" ++ fi ++@@ -18549,23 +17705,22 @@ ++ done ++ done ++ done ++-done # boost_lib_ ++ rm -f conftest.$ac_objext ++ ++ fi ++-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_system" >&5 ++-$as_echo "$boost_cv_lib_system" >&6; } ++-case $boost_cv_lib_system in #( ++- (no) $as_echo "$as_me: failed program was:" >&5 +++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $boost_cv_lib_filesystem" >&5 +++$as_echo "$boost_cv_lib_filesystem" >&6; } +++case $boost_cv_lib_filesystem in #( +++ no) $as_echo "$as_me: failed program was:" >&5 ++ sed 's/^/| /' conftest.$ac_ext >&5 ++ ++- as_fn_error $? "cannot find the flags to link with Boost system" "$LINENO" 5 +++ as_fn_error $? "cannot find the flags to link with Boost filesystem" "$LINENO" 5 ++ ;; ++ esac ++-BOOST_SYSTEM_LDFLAGS=$boost_cv_lib_system_LDFLAGS ++-BOOST_SYSTEM_LDPATH=$boost_cv_lib_system_LDPATH ++-BOOST_LDPATH=$boost_cv_lib_system_LDPATH ++-BOOST_SYSTEM_LIBS=$boost_cv_lib_system_LIBS +++BOOST_FILESYSTEM_LDFLAGS=$boost_cv_lib_filesystem_LDFLAGS +++BOOST_FILESYSTEM_LDPATH=$boost_cv_lib_filesystem_LDPATH +++BOOST_LDPATH=$boost_cv_lib_filesystem_LDPATH +++BOOST_FILESYSTEM_LIBS=$boost_cv_lib_filesystem_LIBS ++ CPPFLAGS=$boost_save_CPPFLAGS ++ ac_ext=cpp ++ ac_cpp='$CXXCPP $CPPFLAGS' ++@@ -18574,6 +17729,12 @@ ++ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ fi ++ +++if test $enable_static_boost = yes && test $boost_major_version -ge 135; then +++ BOOST_FILESYSTEM_LIBS="$BOOST_FILESYSTEM_LIBS $BOOST_SYSTEM_LIBS" +++ +++fi +++LIBS=$boost_filesystem_save_LIBS +++LDFLAGS=$boost_filesystem_save_LDFLAGS ++ ++ ++ ++@@ -18591,12 +17752,12 @@ ++ pkg_cv_MDDS_CFLAGS="$MDDS_CFLAGS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mdds >= 0.11.0\""; } >&5 ++- ($PKG_CONFIG --exists --print-errors "mdds >= 0.11.0") 2>&5 +++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mdds >= 0.8.0\""; } >&5 +++ ($PKG_CONFIG --exists --print-errors "mdds >= 0.8.0") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++- pkg_cv_MDDS_CFLAGS=`$PKG_CONFIG --cflags "mdds >= 0.11.0" 2>/dev/null` +++ pkg_cv_MDDS_CFLAGS=`$PKG_CONFIG --cflags "mdds >= 0.8.0" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++ else ++ pkg_failed=yes ++@@ -18608,12 +17769,12 @@ ++ pkg_cv_MDDS_LIBS="$MDDS_LIBS" ++ elif test -n "$PKG_CONFIG"; then ++ if test -n "$PKG_CONFIG" && \ ++- { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mdds >= 0.11.0\""; } >&5 ++- ($PKG_CONFIG --exists --print-errors "mdds >= 0.11.0") 2>&5 +++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"mdds >= 0.8.0\""; } >&5 +++ ($PKG_CONFIG --exists --print-errors "mdds >= 0.8.0") 2>&5 ++ ac_status=$? ++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 ++ test $ac_status = 0; }; then ++- pkg_cv_MDDS_LIBS=`$PKG_CONFIG --libs "mdds >= 0.11.0" 2>/dev/null` +++ pkg_cv_MDDS_LIBS=`$PKG_CONFIG --libs "mdds >= 0.8.0" 2>/dev/null` ++ test "x$?" != "x0" && pkg_failed=yes ++ else ++ pkg_failed=yes ++@@ -18634,14 +17795,14 @@ ++ _pkg_short_errors_supported=no ++ fi ++ if test $_pkg_short_errors_supported = yes; then ++- MDDS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "mdds >= 0.11.0" 2>&1` +++ MDDS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "mdds >= 0.8.0" 2>&1` ++ else ++- MDDS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "mdds >= 0.11.0" 2>&1` +++ MDDS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "mdds >= 0.8.0" 2>&1` ++ fi ++ # Put the nasty error message in config.log where it belongs ++ echo "$MDDS_PKG_ERRORS" >&5 ++ ++- as_fn_error $? "Package requirements (mdds >= 0.11.0) were not met: +++ as_fn_error $? "Package requirements (mdds >= 0.8.0) were not met: ++ ++ $MDDS_PKG_ERRORS ++ ++@@ -20538,7 +19699,7 @@ ++ ++ case $ac_file$ac_mode in ++ "depfiles":C) test x"$AMDEP_TRUE" != x"" || { ++- # Older Autoconf quotes --file arguments for eval, but not when files +++ # Autoconf 2.62 quotes --file arguments for eval, but not when files ++ # are listed without --file. Let's play safe and only enable the eval ++ # if we detect the quoting. ++ case $CONFIG_FILES in ++@@ -20589,7 +19750,7 @@ ++ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` ++ test -z "$DEPDIR" && continue ++ am__include=`sed -n 's/^am__include = //p' < "$mf"` ++- test -z "$am__include" && continue +++ test -z "am__include" && continue ++ am__quote=`sed -n 's/^am__quote = //p' < "$mf"` ++ # Find all dependency output files, they are included files with ++ # $(DEPDIR) in their names. We invoke sed twice because it is the ++@@ -21476,7 +20637,6 @@ ++ ============================================================================== ++ Build configuration: ++ debug: $enable_debug ++- werror: $enable_werror ++ spreadsheet-model: $enable_spreadsheet_model ++ gnumeric-filter: $with_gnumeric_filter ++ ods-filter: $with_ods_filter ++@@ -21489,7 +20649,6 @@ ++ ============================================================================== ++ Build configuration: ++ debug: $enable_debug ++- werror: $enable_werror ++ spreadsheet-model: $enable_spreadsheet_model ++ gnumeric-filter: $with_gnumeric_filter ++ ods-filter: $with_ods_filter +-- +2.5.0 + diff --git a/SOURCES/0001-rhbz-1168757-propagate-selected-slides-to-print-dial.patch b/SOURCES/0001-rhbz-1168757-propagate-selected-slides-to-print-dial.patch new file mode 100644 index 0000000..592c15d --- /dev/null +++ b/SOURCES/0001-rhbz-1168757-propagate-selected-slides-to-print-dial.patch @@ -0,0 +1,111 @@ +From 6184f8debb94571c11ab085ccbc5f431459fe1d5 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 20 Jan 2016 18:40:06 +0100 +Subject: [PATCH] rhbz#1168757 propagate selected slides to print dialog + +(cherry picked from commit f90f8329fe5e95f25ba449e307fd40d56d68d3bb) + +Change-Id: Icef119baffb8985ea0cb94d7e59f0daae88023ac +--- + sd/source/ui/view/DocumentRenderer.cxx | 41 ++++++++++++++++++++++++++++++---- + 1 file changed, 37 insertions(+), 4 deletions(-) + +diff --git a/sd/source/ui/view/DocumentRenderer.cxx b/sd/source/ui/view/DocumentRenderer.cxx +index 734c61a..8924468 100644 +--- a/sd/source/ui/view/DocumentRenderer.cxx ++++ b/sd/source/ui/view/DocumentRenderer.cxx +@@ -33,10 +33,12 @@ + #include "FrameView.hxx" + #include "Outliner.hxx" + #include "OutlineViewShell.hxx" ++#include "SlideSorterViewShell.hxx" + + #include + #include + #include ++#include + #include + #include + #include +@@ -333,8 +335,9 @@ namespace { + class DialogCreator : Resource + { + public: +- DialogCreator (bool bImpress, sal_Int32 nCurPage) ++ DialogCreator (ViewShellBase &rBase, bool bImpress, sal_Int32 nCurPage) + : Resource(SdResId(_STR_IMPRESS_PRINT_UI_OPTIONS)) ++ , mrBase(rBase) + , mbImpress(bImpress) + , mnCurPage(nCurPage) + { +@@ -359,6 +362,7 @@ namespace { + } + + private: ++ ViewShellBase &mrBase; + ::std::vector maProperties; + ::std::vector maSlidesPerPage; + bool mbImpress; +@@ -584,19 +588,48 @@ namespace { + aWidgetIds[0] = "printallpages"; + aWidgetIds[1] = "printpages"; + aWidgetIds[2] = "printselection"; ++ ++ // check if there is a selection of slides ++ OUString aPageRange(OUString::number(mnCurPage + 1)); ++ int nPrintRange(0); ++ using sd::slidesorter::SlideSorterViewShell; ++ SlideSorterViewShell* const pSSViewSh(SlideSorterViewShell::GetSlideSorter(mrBase)); ++ if (pSSViewSh) ++ { ++ const boost::shared_ptr pPageSelection(pSSViewSh->GetPageSelection()); ++ if (bool(pPageSelection) && pPageSelection->size() > 1) ++ { ++ OUStringBuffer aBuf; ++ // TODO: this could be improved by writing ranges instead of consecutive page ++ // numbers if appropriate. Do we have a helper function for that somewhere? ++ bool bFirst(true); ++ for (auto pPage: *pPageSelection) ++ { ++ if (!bFirst) ++ { ++ aBuf.append(','); ++ bFirst = false; ++ } ++ aBuf.append(OUString::number(pPage->GetPageNum() / 2 + 1)); ++ } ++ aPageRange = aBuf.getStr(); ++ nPrintRange = 1; ++ } ++ } ++ + AddDialogControl( vcl::PrinterOptionsHelper::setChoiceRadiosControlOpt(aWidgetIds, "", + aHelpIds, + aPrintRangeName, + CreateChoice(mbImpress + ? _STR_IMPRESS_PRINT_UI_PAGE_RANGE_CHOICE + : _STR_DRAW_PRINT_UI_PAGE_RANGE_CHOICE), +- 0 ) ++ nPrintRange ) + ); + // create a an Edit dependent on "Pages" selected + vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, true ); + AddDialogControl(vcl::PrinterOptionsHelper::setEditControlOpt("pagerange", "", + ".HelpID:vcl:PrintDialog:PageRange:Edit", "PageRange", +- OUString::number(mnCurPage + 1), aPageRangeOpt)); ++ aPageRange, aPageRangeOpt)); + + FreeResource(); + } +@@ -1140,7 +1173,7 @@ public: + , mpPrintView() + , mbHasOrientationWarningBeenShown(false) + { +- DialogCreator aCreator( mrBase.GetDocShell()->GetDocumentType() == DOCUMENT_TYPE_IMPRESS, GetCurrentPageIndex() ); ++ DialogCreator aCreator( mrBase, mrBase.GetDocShell()->GetDocumentType() == DOCUMENT_TYPE_IMPRESS, GetCurrentPageIndex() ); + m_aUIProperties = aCreator.GetDialogControls(); + maSlidesPerPage = aCreator.GetSlidesPerPage(); + +-- +2.5.0 + diff --git a/SOURCES/0001-rhbz-1233420-handle-inexistent-cond.-format.patch b/SOURCES/0001-rhbz-1233420-handle-inexistent-cond.-format.patch new file mode 100644 index 0000000..63f3948 --- /dev/null +++ b/SOURCES/0001-rhbz-1233420-handle-inexistent-cond.-format.patch @@ -0,0 +1,97 @@ +From b12cd99fd46e81e710479e2530e80c75404f3443 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 Jun 2015 13:52:49 +0200 +Subject: [PATCH] rhbz#1233420 handle inexistent cond. format + +Change-Id: I3fbbd0f3b42a3be1c2a9c54eb8f35dd18f550b16 +--- + sc/source/core/data/table4.cxx | 45 ++++++++++++++++++++++++++++-------------- + 1 file changed, 30 insertions(+), 15 deletions(-) + +diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx +index a1bc8ee5..bc8e40e 100644 +--- a/sc/source/core/data/table4.cxx ++++ b/sc/source/core/data/table4.cxx +@@ -618,9 +618,12 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + itr != itrEnd; ++itr) + { + ScConditionalFormat* pCondFormat = mpCondFormatList->GetFormat(*itr); +- ScRangeList aRange = pCondFormat->GetRange(); +- aRange.Join(ScRange(nCol, nY1, nTab, nCol, nY2, nTab)); +- pCondFormat->SetRange(aRange); ++ if (pCondFormat) ++ { ++ ScRangeList aRange = pCondFormat->GetRange(); ++ aRange.Join(ScRange(nCol, nY1, nTab, nCol, nY2, nTab)); ++ pCondFormat->SetRange(aRange); ++ } + } + } + +@@ -648,9 +651,12 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + itr != itrEnd; ++itr) + { + ScConditionalFormat* pCondFormat = mpCondFormatList->GetFormat(*itr); +- ScRangeList aRange = pCondFormat->GetRange(); +- aRange.Join(ScRange(nCol, nRow, nTab, nCol, nRow, nTab)); +- pCondFormat->SetRange(aRange); ++ if (pCondFormat) ++ { ++ ScRangeList aRange = pCondFormat->GetRange(); ++ aRange.Join(ScRange(nCol, nRow, nTab, nCol, nRow, nTab)); ++ pCondFormat->SetRange(aRange); ++ } + } + } + +@@ -1568,9 +1574,12 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + itr != itrEnd; ++itr) + { + ScConditionalFormat* pCondFormat = mpCondFormatList->GetFormat(*itr); +- ScRangeList aRange = pCondFormat->GetRange(); +- aRange.Join(ScRange(nCol, nIMin, nTab, nCol, nIMax, nTab)); +- pCondFormat->SetRange(aRange); ++ if (pCondFormat) ++ { ++ ScRangeList aRange = pCondFormat->GetRange(); ++ aRange.Join(ScRange(nCol, nIMin, nTab, nCol, nIMax, nTab)); ++ pCondFormat->SetRange(aRange); ++ } + } + } + else +@@ -1585,9 +1594,12 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + itr != itrEnd; ++itr) + { + ScConditionalFormat* pCondFormat = mpCondFormatList->GetFormat(*itr); +- ScRangeList aRange = pCondFormat->GetRange(); +- aRange.Join(ScRange(nCol, nAtRow, nTab, nCol, nAtRow, nTab)); +- pCondFormat->SetRange(aRange); ++ if (pCondFormat) ++ { ++ ScRangeList aRange = pCondFormat->GetRange(); ++ aRange.Join(ScRange(nCol, nAtRow, nTab, nCol, nAtRow, nTab)); ++ pCondFormat->SetRange(aRange); ++ } + } + } + } +@@ -1603,9 +1615,12 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, + itr != itrEnd; ++itr) + { + ScConditionalFormat* pCondFormat = mpCondFormatList->GetFormat(*itr); +- ScRangeList aRange = pCondFormat->GetRange(); +- aRange.Join(ScRange(nAtCol, static_cast(nRow), nTab, nAtCol, static_cast(nRow), nTab)); +- pCondFormat->SetRange(aRange); ++ if (pCondFormat) ++ { ++ ScRangeList aRange = pCondFormat->GetRange(); ++ aRange.Join(ScRange(nAtCol, static_cast(nRow), nTab, nAtCol, static_cast(nRow), nTab)); ++ pCondFormat->SetRange(aRange); ++ } + } + } + } +-- +2.4.2 + diff --git a/SOURCES/0001-rhbz-1283420-cairo-text-xrender-bodge.patch b/SOURCES/0001-rhbz-1283420-cairo-text-xrender-bodge.patch new file mode 100644 index 0000000..9250596 --- /dev/null +++ b/SOURCES/0001-rhbz-1283420-cairo-text-xrender-bodge.patch @@ -0,0 +1,49 @@ +From 98dedb1abb5197ca9bf823ddbcf0b0e55a260505 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 15 Dec 2015 12:35:05 +0000 +Subject: [PATCH] rhbz#1283420: cairo text + xrender bodge + +Change-Id: I926881bcfa4911f3d7f4899711be44a2f6d82026 +--- + vcl/unx/generic/gdi/x11cairotextrender.cxx | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/vcl/unx/generic/gdi/x11cairotextrender.cxx b/vcl/unx/generic/gdi/x11cairotextrender.cxx +index 8734526..17cb462 100644 +--- a/vcl/unx/generic/gdi/x11cairotextrender.cxx ++++ b/vcl/unx/generic/gdi/x11cairotextrender.cxx +@@ -42,6 +42,10 @@ struct _XRegion + BOX extents; + }; + ++#if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 10, 0) ++# define CAIRO_OPERATOR_DIFFERENCE (static_cast(23)) ++#endif ++ + X11CairoTextRender::X11CairoTextRender(X11SalGraphics& rParent) + : mrParent(rParent) + { +@@ -78,6 +82,20 @@ cairo_t* X11CairoTextRender::getCairoContext() + + cairo_t *cr = cairo_create(surface); + cairo_surface_destroy(surface); ++ ++ //rhbz#1283420 bodge to draw and undraw something which has the side effect ++ //of making the mysterious xrender related problem go away ++ if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 10, 0)) ++ { ++ cairo_save(cr); ++ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); ++ cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE); ++ cairo_rectangle(cr, 0, 0, 1, 1); ++ cairo_fill_preserve(cr); ++ cairo_fill(cr); ++ cairo_restore(cr); ++ } ++ + return cr; + } + +-- +2.5.0 + diff --git a/SOURCES/0001-rhbz-1326602-avoid-exp.-bg-bitmaps-from-deleted-slid.patch b/SOURCES/0001-rhbz-1326602-avoid-exp.-bg-bitmaps-from-deleted-slid.patch new file mode 100644 index 0000000..ea6562f --- /dev/null +++ b/SOURCES/0001-rhbz-1326602-avoid-exp.-bg-bitmaps-from-deleted-slid.patch @@ -0,0 +1,301 @@ +From 9a36cf42d6ea424a2ca5c92f8bf1546ab618dc5d Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 26 Apr 2016 09:17:11 +0200 +Subject: [PATCH] rhbz#1326602 avoid exp. bg bitmaps from deleted slides + +ODF export uses SvxUnoBitmapTable (impl. of +com.sun.star.drawing.BitmapTable) to create fill bitmap styles. That +returns all XATTR_FILLBITMAP items that are in the document's pool. So +we ensure that bitmaps that are only used on deleted (either explicitly +or by undoing their insertion) slides are not in the pool. + +(cherry picked from commit b876bbe2cacce8af379b10d82da6c7e7d229b361) + +Change-Id: I54c594a94989158f22b156fe660c1e716b988b3e +--- + include/svx/svdundo.hxx | 13 ++++++++ + sd/source/ui/func/undoback.cxx | 44 ++++++++++++++++++++++++-- + sd/source/ui/inc/undoback.hxx | 6 ++++ + svx/source/svdraw/svdundo.cxx | 70 ++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 131 insertions(+), 2 deletions(-) + +diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx +index a6c9f24..6472946 100644 +--- a/include/svx/svdundo.hxx ++++ b/include/svx/svdundo.hxx +@@ -20,6 +20,11 @@ + #ifndef INCLUDED_SVX_SVDUNDO_HXX + #define INCLUDED_SVX_SVDUNDO_HXX + ++#include ++ ++#include ++#include ++ + #include + #include + #include +@@ -29,6 +34,7 @@ + #include + + class SfxItemSet; ++class SfxPoolItem; + class SfxStyleSheet; + class SdrView; + class SdrPageView; +@@ -589,6 +595,8 @@ class SVX_DLLPUBLIC SdrUndoDelPage : public SdrUndoPageList + // When deleting a MasterPage, we remember all relations of the + // Character Page with the MasterPage in this UndoGroup. + SdrUndoGroup* pUndoGroup; ++ std::unique_ptr mpFillBitmapItem; ++ bool mbHasFillBitmap; + + public: + SdrUndoDelPage(SdrPage& rNewPg); +@@ -602,6 +610,11 @@ public: + + virtual void SdrRepeat(SdrView& rView) SAL_OVERRIDE; + virtual bool CanSdrRepeat(SdrView& rView) const SAL_OVERRIDE; ++ ++private: ++ void queryFillBitmap(const SfxItemSet &rItemSet); ++ void clearFillBitmap(); ++ void restoreFillBitmap(); + }; + + /** +diff --git a/sd/source/ui/func/undoback.cxx b/sd/source/ui/func/undoback.cxx +index bfb421b..3e3575a 100644 +--- a/sd/source/ui/func/undoback.cxx ++++ b/sd/source/ui/func/undoback.cxx +@@ -21,8 +21,13 @@ + #include "sdpage.hxx" + #include "sdresid.hxx" + #include "strings.hrc" ++ ++#include ++ + #include + ++#include ++ + TYPEINIT1( SdBackgroundObjUndoAction, SdUndoAction ); + + SdBackgroundObjUndoAction::SdBackgroundObjUndoAction( +@@ -31,10 +38,12 @@ SdBackgroundObjUndoAction::SdBackgroundObjUndoAction( + const SfxItemSet& rItenSet) + : SdUndoAction(&rDoc), + mrPage(rPage), +- mpItemSet(new SfxItemSet(rItenSet)) ++ mpItemSet(new SfxItemSet(rItenSet)), ++ mbHasFillBitmap(false) + { + OUString aString( SdResId( STR_UNDO_CHANGE_PAGEFORMAT ) ); + SetComment( aString ); ++ saveFillBitmap(*mpItemSet); + } + + SdBackgroundObjUndoAction::~SdBackgroundObjUndoAction() +@@ -46,9 +55,14 @@ void SdBackgroundObjUndoAction::ImplRestoreBackgroundObj() + { + SfxItemSet* pNew = new SfxItemSet(mrPage.getSdrPageProperties().GetItemSet()); + mrPage.getSdrPageProperties().ClearItem(); ++ if (bool(mpFillBitmapItem)) ++ restoreFillBitmap(*mpItemSet); ++ mpFillBitmapItem.reset(); ++ mbHasFillBitmap = false; + mrPage.getSdrPageProperties().PutItemSet(*mpItemSet); + delete mpItemSet; + mpItemSet = pNew; ++ saveFillBitmap(*mpItemSet); + + // tell the page that it's visualization has changed + mrPage.ActionChanged(); +@@ -66,7 +80,33 @@ void SdBackgroundObjUndoAction::Redo() + + SdUndoAction* SdBackgroundObjUndoAction::Clone() const + { +- return new SdBackgroundObjUndoAction(*mpDoc, mrPage, *mpItemSet); ++ std::unique_ptr pCopy(new SdBackgroundObjUndoAction(*mpDoc, mrPage, *mpItemSet)); ++ if (mpFillBitmapItem) ++ pCopy->mpFillBitmapItem.reset(mpFillBitmapItem->Clone()); ++ pCopy->mbHasFillBitmap = mbHasFillBitmap; ++ return pCopy.release(); ++} ++ ++void SdBackgroundObjUndoAction::saveFillBitmap(SfxItemSet &rItemSet) ++{ ++ const SfxPoolItem *pItem = nullptr; ++ if (rItemSet.GetItemState(XATTR_FILLBITMAP, false, &pItem) == SfxItemState::SET) ++ mpFillBitmapItem.reset(pItem->Clone()); ++ if (bool(mpFillBitmapItem)) ++ { ++ if (rItemSet.GetItemState(XATTR_FILLSTYLE, false, &pItem) == SfxItemState::SET) ++ mbHasFillBitmap = static_cast(pItem)->GetValue() == css::drawing::FillStyle_BITMAP; ++ rItemSet.ClearItem(XATTR_FILLBITMAP); ++ if (mbHasFillBitmap) ++ rItemSet.ClearItem(XATTR_FILLSTYLE); ++ } ++} ++ ++void SdBackgroundObjUndoAction::restoreFillBitmap(SfxItemSet &rItemSet) ++{ ++ rItemSet.Put(*mpFillBitmapItem); ++ if (mbHasFillBitmap) ++ rItemSet.Put(XFillStyleItem(css::drawing::FillStyle_BITMAP)); + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/sd/source/ui/inc/undoback.hxx b/sd/source/ui/inc/undoback.hxx +index 360f7f5..4234424 100644 +--- a/sd/source/ui/inc/undoback.hxx ++++ b/sd/source/ui/inc/undoback.hxx +@@ -20,11 +20,13 @@ + #ifndef INCLUDED_SD_SOURCE_UI_INC_UNDOBACK_HXX + #define INCLUDED_SD_SOURCE_UI_INC_UNDOBACK_HXX + ++#include + #include "sdundo.hxx" + + class SdDrawDocument; + class SdPage; + class SfxItemSet; ++class SfxPoolItem; + + // SdBackgroundObjUndoAction + class SdBackgroundObjUndoAction : public SdUndoAction +@@ -33,8 +35,12 @@ private: + + SdPage& mrPage; + SfxItemSet* mpItemSet; ++ std::unique_ptr mpFillBitmapItem; ++ bool mbHasFillBitmap; + + void ImplRestoreBackgroundObj(); ++ void saveFillBitmap(SfxItemSet &rItemSet); ++ void restoreFillBitmap(SfxItemSet &rItemSet); + + public: + +diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx +index 7466532..e4dfa12 100644 +--- a/svx/source/svdraw/svdundo.cxx ++++ b/svx/source/svdraw/svdundo.cxx +@@ -17,6 +17,7 @@ + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + ++#include + + #include + +@@ -27,6 +28,7 @@ + #include + #include + #include ++#include + #include "svx/svdstr.hrc" + #include "svdglob.hxx" + #include +@@ -1483,9 +1485,24 @@ SdrUndoPageList::~SdrUndoPageList() + SdrUndoDelPage::SdrUndoDelPage(SdrPage& rNewPg) + : SdrUndoPageList(rNewPg) + , pUndoGroup(NULL) ++ , mbHasFillBitmap(false) + { + bItsMine = true; + ++ // keep fill bitmap separately to remove it from pool if not used elsewhere ++ if (mrPage.IsMasterPage()) ++ { ++ SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet(); ++ if (pStyleSheet) ++ queryFillBitmap(pStyleSheet->GetItemSet()); ++ } ++ else ++ { ++ queryFillBitmap(mrPage.getSdrPageProperties().GetItemSet()); ++ } ++ if (bool(mpFillBitmapItem)) ++ clearFillBitmap(); ++ + // now remember the master page relationships + if(mrPage.IsMasterPage()) + { +@@ -1520,6 +1537,8 @@ SdrUndoDelPage::~SdrUndoDelPage() + + void SdrUndoDelPage::Undo() + { ++ if (bool(mpFillBitmapItem)) ++ restoreFillBitmap(); + ImpInsertPage(nPageNum); + if (pUndoGroup!=NULL) + { +@@ -1533,6 +1552,8 @@ void SdrUndoDelPage::Undo() + void SdrUndoDelPage::Redo() + { + ImpRemovePage(nPageNum); ++ if (bool(mpFillBitmapItem)) ++ clearFillBitmap(); + // master page relations are dissolved automatically + DBG_ASSERT(!bItsMine,"RedoDeletePage: mrPage already belongs to UndoAction."); + bItsMine=true; +@@ -1561,6 +1582,55 @@ bool SdrUndoDelPage::CanSdrRepeat(SdrView& /*rView*/) const + return false; + } + ++void SdrUndoDelPage::queryFillBitmap(const SfxItemSet& rItemSet) ++{ ++ const SfxPoolItem *pItem = nullptr; ++ if (rItemSet.GetItemState(XATTR_FILLBITMAP, false, &pItem) == SfxItemState::SET) ++ mpFillBitmapItem.reset(pItem->Clone()); ++ if (rItemSet.GetItemState(XATTR_FILLSTYLE, false, &pItem) == SfxItemState::SET) ++ mbHasFillBitmap = static_cast(pItem)->GetValue() == css::drawing::FillStyle_BITMAP; ++} ++ ++void SdrUndoDelPage::clearFillBitmap() ++{ ++ if (mrPage.IsMasterPage()) ++ { ++ SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet(); ++ assert(bool(pStyleSheet)); // who took away my stylesheet? ++ SfxItemSet& rItemSet = pStyleSheet->GetItemSet(); ++ rItemSet.ClearItem(XATTR_FILLBITMAP); ++ if (mbHasFillBitmap) ++ rItemSet.ClearItem(XATTR_FILLSTYLE); ++ } ++ else ++ { ++ SdrPageProperties &rPageProps = mrPage.getSdrPageProperties(); ++ rPageProps.ClearItem(XATTR_FILLBITMAP); ++ if (mbHasFillBitmap) ++ rPageProps.ClearItem(XATTR_FILLSTYLE); ++ } ++} ++ ++void SdrUndoDelPage::restoreFillBitmap() ++{ ++ if (mrPage.IsMasterPage()) ++ { ++ SfxStyleSheet* const pStyleSheet = mrPage.getSdrPageProperties().GetStyleSheet(); ++ assert(bool(pStyleSheet)); // who took away my stylesheet? ++ SfxItemSet& rItemSet = pStyleSheet->GetItemSet(); ++ rItemSet.Put(*mpFillBitmapItem); ++ if (mbHasFillBitmap) ++ rItemSet.Put(XFillStyleItem(css::drawing::FillStyle_BITMAP)); ++ } ++ else ++ { ++ SdrPageProperties &rPageProps = mrPage.getSdrPageProperties(); ++ rPageProps.PutItem(*mpFillBitmapItem); ++ if (mbHasFillBitmap) ++ rPageProps.PutItem(XFillStyleItem(css::drawing::FillStyle_BITMAP)); ++ } ++} ++ + + + void SdrUndoNewPage::Undo() +-- +2.7.4 + diff --git a/SOURCES/0001-rtf-m_aStates-can-be-empty-in-the-inner-condition.patch b/SOURCES/0001-rtf-m_aStates-can-be-empty-in-the-inner-condition.patch new file mode 100644 index 0000000..deaf0b4 --- /dev/null +++ b/SOURCES/0001-rtf-m_aStates-can-be-empty-in-the-inner-condition.patch @@ -0,0 +1,37 @@ +From 4ce2689bf8616463d224ebfed1d5bc80691c6b8c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 10 May 2016 09:34:58 +0100 +Subject: [PATCH] rtf: m_aStates can be empty in the inner condition + +Change-Id: Id262a3019a693f236630b798579f360c9462d12e +(cherry picked from commit 05cc87ce45fad402445c8d748817e386e56148af) +--- + writerfilter/source/rtftok/rtfdocumentimpl.cxx | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx +index 799186d..995772a 100644 +--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx ++++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx +@@ -455,11 +455,15 @@ writerfilter::Reference::Pointer_t RTFDocumentImpl::getProperties(RT + + // cloneAndDeduplicate() wants to know about only a single "style", so + // let's merge paragraph and character style properties here. +- int nCharStyle = m_aStates.top().nCurrentCharacterStyleIndex; +- RTFReferenceTable::Entries_t::iterator itChar = m_aStyleTableEntries.find(nCharStyle); ++ RTFReferenceTable::Entries_t::iterator itChar = m_aStyleTableEntries.end(); ++ if (!m_aStates.empty()) ++ { ++ int nCharStyle = m_aStates.top().nCurrentCharacterStyleIndex; ++ itChar = m_aStyleTableEntries.find(nCharStyle); ++ } ++ + RTFSprms aStyleSprms; + RTFSprms aStyleAttributes; +- + // Ensure the paragraph style is a flat list. + lcl_copyFlatten(rProps, aStyleAttributes, aStyleSprms); + +-- +2.7.4 + diff --git a/SOURCES/0001-sysui-g-ir-scanner-is-not-available-in-when-introspe.patch b/SOURCES/0001-sysui-g-ir-scanner-is-not-available-in-when-introspe.patch new file mode 100644 index 0000000..e2d07ef --- /dev/null +++ b/SOURCES/0001-sysui-g-ir-scanner-is-not-available-in-when-introspe.patch @@ -0,0 +1,79 @@ +From 7901933672c1d2dcd0148f0c8e9c8ee625d009b8 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Sep 2015 14:12:29 +0200 +Subject: [PATCH 1/2] sysui: g-ir-scanner is not available in when + introspection is disabled + +Should fix the RHEL6 build. + +Change-Id: I3d6e6a2b43c2d6a43ea0686600cf2f893c518cc8 +Reviewed-on: https://gerrit.libreoffice.org/18566 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit d8026ad65c8d50868f0f2fc0d2bd95820cddea83) +--- + config_host.mk.in | 1 + + sysui/CustomTarget_share.mk | 1 + + sysui/desktop/share/create_tree.sh | 24 +++++++++++++----------- + 3 files changed, 15 insertions(+), 11 deletions(-) + +diff --git a/config_host.mk.in b/config_host.mk.in +index 4ce14b085201..263f5323b7e5 100644 +--- a/config_host.mk.in ++++ b/config_host.mk.in +@@ -281,6 +281,7 @@ export ICU_RECLASSIFIED_CLOSE_PARENTHESIS=@ICU_RECLASSIFIED_CLOSE_PARENTHESIS@ + export ICU_RECLASSIFIED_CONDITIONAL_JAPANESE_STARTER=@ICU_RECLASSIFIED_CONDITIONAL_JAPANESE_STARTER@ + export ICU_RECLASSIFIED_HEBREW_LETTER=@ICU_RECLASSIFIED_HEBREW_LETTER@ + export ICU_RECLASSIFIED_PREPEND_SET_EMPTY=@ICU_RECLASSIFIED_PREPEND_SET_EMPTY@ ++export INTROSPECTION_SCANNER=@INTROSPECTION_SCANNER@ + export ILIB=@ILIB@ + export INSTALLDIR=@INSTALLDIR@ + export INSTALLDIRNAME=@INSTALLDIRNAME@ +diff --git a/sysui/CustomTarget_share.mk b/sysui/CustomTarget_share.mk +index 84907d1003c4..79bafd7f66ad 100644 +--- a/sysui/CustomTarget_share.mk ++++ b/sysui/CustomTarget_share.mk +@@ -184,6 +184,7 @@ $(share_WORKDIR)/%/create_tree.sh: $(share_SRCDIR)/share/create_tree.sh $(share_ + echo "ICON_SOURCE_DIR=$(SRCDIR)/sysui/desktop/icons" >> $@ + echo "APPDATA_SOURCE_DIR=$(SRCDIR)/sysui/desktop/appstream-appdata" >> $@ + echo "PRODUCTVERSION=$(PRODUCTVERSION)" >> $@ ++ echo "INTROSPECTION_SCANNER=$(INTROSPECTION_SCANNER)" >> $@ + cat $< >> $@ + chmod 774 $@ + +diff --git a/sysui/desktop/share/create_tree.sh b/sysui/desktop/share/create_tree.sh +index 45b7c6cb09db..c73b89af3ab5 100755 +--- a/sysui/desktop/share/create_tree.sh ++++ b/sysui/desktop/share/create_tree.sh +@@ -88,15 +88,17 @@ for i in base calc draw impress writer; do + done + + # Generate gobject-introspection files +-mkdir -p "${DESTDIR}/${PREFIXDIR}/share/gir-1.0" +-g-ir-scanner "${SRCDIR}/include/LibreOfficeKit/LibreOfficeKitGtk.h" "${SRCDIR}/libreofficekit/source/gtk/lokdocview.cxx" \ +- `${PKG_CONFIG} --cflags gobject-introspection-1.0 gtk+-3.0` -I"${SRCDIR}/include/" \ +- --include=GLib-2.0 --include=GObject-2.0 --include=Gio-2.0 \ +- --library=libreofficekitgtk --library-path="${DESTDIR}/${INSTALLDIR}/program" \ +- --include=Gdk-3.0 --include=GdkPixbuf-2.0 --include=Gtk-3.0 \ +- --namespace=LOKDocView --nsversion=0.1 --identifier-prefix=LOKDoc --symbol-prefix=lok_doc \ +- --output="${DESTDIR}/${PREFIXDIR}/share/gir-1.0/LOKDocView-0.1.gir" --warn-all --no-libtool ++if [ -n "$INTROSPECTION_SCANNER" ]; then ++ mkdir -p "${DESTDIR}/${PREFIXDIR}/share/gir-1.0" ++ g-ir-scanner "${SRCDIR}/include/LibreOfficeKit/LibreOfficeKitGtk.h" "${SRCDIR}/libreofficekit/source/gtk/lokdocview.cxx" \ ++ `${PKG_CONFIG} --cflags gobject-introspection-1.0 gtk+-3.0` -I"${SRCDIR}/include/" \ ++ --include=GLib-2.0 --include=GObject-2.0 --include=Gio-2.0 \ ++ --library=libreofficekitgtk --library-path="${DESTDIR}/${INSTALLDIR}/program" \ ++ --include=Gdk-3.0 --include=GdkPixbuf-2.0 --include=Gtk-3.0 \ ++ --namespace=LOKDocView --nsversion=0.1 --identifier-prefix=LOKDoc --symbol-prefix=lok_doc \ ++ --output="${DESTDIR}/${PREFIXDIR}/share/gir-1.0/LOKDocView-0.1.gir" --warn-all --no-libtool + +-mkdir -p "${DESTDIR}/${LIBDIR}/girepository-1.0" +-g-ir-compiler "${DESTDIR}/${PREFIXDIR}/share/gir-1.0/LOKDocView-0.1.gir" \ +- --output="${DESTDIR}/${LIBDIR}/girepository-1.0/LOKDocView-0.1.typelib" ++ mkdir -p "${DESTDIR}/${LIBDIR}/girepository-1.0" ++ g-ir-compiler "${DESTDIR}/${PREFIXDIR}/share/gir-1.0/LOKDocView-0.1.gir" \ ++ --output="${DESTDIR}/${LIBDIR}/girepository-1.0/LOKDocView-0.1.typelib" ++fi +-- +2.12.0 + diff --git a/SOURCES/0001-tdf-39271-allow-to-export-only-notes-pages.patch b/SOURCES/0001-tdf-39271-allow-to-export-only-notes-pages.patch new file mode 100644 index 0000000..54aa224 --- /dev/null +++ b/SOURCES/0001-tdf-39271-allow-to-export-only-notes-pages.patch @@ -0,0 +1,346 @@ +From 770a1752cda8ba629ce11bd514869a2c800f0817 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 24 Mar 2016 14:52:35 +0100 +Subject: [PATCH] tdf#39271 allow to export only notes pages + +Change-Id: Ia03062cf31b6bab8196dc317a7e8fbcfc86fadf0 +--- + filter/source/pdf/impdialog.cxx | 23 +++++++++++++ + filter/source/pdf/impdialog.hxx | 3 ++ + filter/source/pdf/pdfexport.cxx | 18 ++++++---- + filter/source/pdf/pdfexport.hxx | 1 + + filter/uiconfig/ui/pdfgeneralpage.ui | 38 +++++++++++++++++----- + .../schema/org/openoffice/Office/Common.xcs | 7 ++++ + 6 files changed, 75 insertions(+), 15 deletions(-) + +diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx +index 89a1351..8c9bd31 100644 +--- a/filter/source/pdf/impdialog.cxx ++++ b/filter/source/pdf/impdialog.cxx +@@ -86,6 +86,7 @@ ImpPDFTabDialog::ImpPDFTabDialog(vcl::Window* pParent, Sequence< PropertyValue > + mbExportNotes( true ), + mbViewPDF( false ), + mbExportNotesPages( false ), ++ mbExportOnlyNotesPages( false ), + mbUseTransitionEffects( false ), + mbIsSkipEmptyPages( true ), + mbAddStream( false ), +@@ -193,7 +194,10 @@ ImpPDFTabDialog::ImpPDFTabDialog(vcl::Window* pParent, Sequence< PropertyValue > + mbUseTaggedPDF = maConfigItem.ReadBool( "UseTaggedPDF", false ); + mnPDFTypeSelection = maConfigItem.ReadInt32( "SelectPdfVersion", 0 ); + if ( mbIsPresentation ) ++ { + mbExportNotesPages = maConfigItem.ReadBool( "ExportNotesPages", false ); ++ mbExportOnlyNotesPages = maConfigItem.ReadBool( "ExportOnlyNotesPages", false ); ++ } + mbExportNotes = maConfigItem.ReadBool( "ExportNotes", false ); + mbViewPDF = maConfigItem.ReadBool( "ViewPDFAfterExport", false ); + +@@ -395,7 +399,10 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData() + maConfigItem.WriteInt32("SelectPdfVersion", mnPDFTypeSelection ); + + if ( mbIsPresentation ) ++ { + maConfigItem.WriteBool( "ExportNotesPages", mbExportNotesPages ); ++ maConfigItem.WriteBool( "ExportOnlyNotesPages", mbExportOnlyNotesPages ); ++ } + maConfigItem.WriteBool( "ExportNotes", mbExportNotes ); + maConfigItem.WriteBool( "ViewPDFAfterExport", mbViewPDF ); + +@@ -543,6 +550,7 @@ ImpPDFTabGeneralPage::ImpPDFTabGeneralPage(vcl::Window* pParent, const SfxItemSe + get(mpCbExportHiddenSlides, "hiddenpages"); + get(mpCbExportNotes, "comments"); + get(mpCbExportNotesPages, "notes"); ++ get(mpCbExportOnlyNotesPages, "onlynotes"); + get(mpCbExportEmptyPages, "emptypages"); + get(mpCbViewPDF, "viewpdf"); + +@@ -580,6 +588,7 @@ void ImpPDFTabGeneralPage::dispose() + mpCbExportNotes.clear(); + mpCbViewPDF.clear(); + mpCbExportNotesPages.clear(); ++ mpCbExportOnlyNotesPages.clear(); + mpCbExportEmptyPages.clear(); + mpCbAddStream.clear(); + mpCbWatermark.clear(); +@@ -661,6 +670,10 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem( ImpPDFTabDialog* paParent ) + mpRbRange->SetText(get("slides")->GetText()); + mpCbExportNotesPages->Show(true); + mpCbExportNotesPages->Check(paParent->mbExportNotesPages); ++ mpCbExportNotesPages->SetToggleHdl( LINK(this, ImpPDFTabGeneralPage, ToggleExportNotesPagesHdl ) ); ++ mpCbExportOnlyNotesPages->Show(); ++ mpCbExportOnlyNotesPages->Check(paParent->mbExportOnlyNotesPages); ++ mpCbExportOnlyNotesPages->Enable(paParent->mbExportNotesPages); + mpCbExportHiddenSlides->Show(true); + mpCbExportHiddenSlides->Check(paParent->mbExportHiddenSlides); + } +@@ -668,6 +681,8 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem( ImpPDFTabDialog* paParent ) + { + mpCbExportNotesPages->Show(false); + mpCbExportNotesPages->Check(false); ++ mpCbExportOnlyNotesPages->Show(false); ++ mpCbExportOnlyNotesPages->Check(false); + mpCbExportHiddenSlides->Show(false); + mpCbExportHiddenSlides->Check(false); + } +@@ -693,7 +708,10 @@ void ImpPDFTabGeneralPage::GetFilterConfigItem( ImpPDFTabDialog* paParent ) + paParent->mbExportNotes = mpCbExportNotes->IsChecked(); + paParent->mbViewPDF = mpCbViewPDF->IsChecked(); + if ( mbIsPresentation ) ++ { + paParent->mbExportNotesPages = mpCbExportNotesPages->IsChecked(); ++ paParent->mbExportOnlyNotesPages = mpCbExportOnlyNotesPages->IsChecked(); ++ } + paParent->mbExportBookmarks = mpCbExportBookmarks->IsChecked(); + if ( mbIsPresentation ) + paParent->mbExportHiddenSlides = mpCbExportHiddenSlides->IsChecked(); +@@ -758,6 +776,11 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleExportFormFieldsHdl) + return 0; + } + ++IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleExportNotesPagesHdl) ++{ ++ mpCbExportOnlyNotesPages->Enable(mpCbExportNotesPages->IsChecked()); ++ return 0; ++} + + IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleCompressionHdl) + { +diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx +index e828721..191bd48 100644 +--- a/filter/source/pdf/impdialog.hxx ++++ b/filter/source/pdf/impdialog.hxx +@@ -104,6 +104,7 @@ protected: + bool mbExportNotes; + bool mbViewPDF; + bool mbExportNotesPages; ++ bool mbExportOnlyNotesPages; + bool mbUseTransitionEffects; + bool mbIsSkipEmptyPages; + bool mbAddStream; +@@ -218,6 +219,7 @@ class ImpPDFTabGeneralPage : public SfxTabPage + VclPtr mpCbExportNotes; + VclPtr mpCbViewPDF; + VclPtr mpCbExportNotesPages; ++ VclPtr mpCbExportOnlyNotesPages; + + VclPtr mpCbExportEmptyPages; + VclPtr mpCbAddStream; +@@ -237,6 +239,7 @@ class ImpPDFTabGeneralPage : public SfxTabPage + DECL_LINK( ToggleWatermarkHdl, void* ); + DECL_LINK( ToggleAddStreamHdl, void* ); + DECL_LINK( ToggleExportFormFieldsHdl, void* ); ++ DECL_LINK( ToggleExportNotesPagesHdl, void* ); + + public: + DECL_LINK( ToggleExportPDFAHdl, void* ); +diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx +index daf4689..1856308 100644 +--- a/filter/source/pdf/pdfexport.cxx ++++ b/filter/source/pdf/pdfexport.cxx +@@ -100,6 +100,7 @@ PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, + mbExportNotes ( true ), + mbViewPDF ( true ), + mbExportNotesPages ( false ), ++ mbExportOnlyNotesPages ( false ), + mbUseTransitionEffects ( true ), + mbExportBookmarks ( true ), + mbExportHiddenSlides ( false ), +@@ -464,6 +465,8 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& + rFilterData[ nData ].Value >>= mbViewPDF; + else if ( rFilterData[ nData ].Name == "ExportNotesPages" ) + rFilterData[ nData ].Value >>= mbExportNotesPages; ++ else if ( rFilterData[ nData ].Name == "ExportOnlyNotesPages" ) ++ rFilterData[ nData ].Value >>= mbExportOnlyNotesPages; + else if ( rFilterData[ nData ].Name == "UseTransitionEffects" ) + rFilterData[ nData ].Value >>= mbUseTransitionEffects; + else if ( rFilterData[ nData ].Name == "ExportFormFields" ) +@@ -840,7 +843,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& + aSelection = Any(); + aSelection <<= mxSrcDoc; + } +- bool bSecondPassForImpressNotes = false; ++ bool bExportNotesPages = false; + bool bReChangeToNormalView = false; + OUString sShowOnlineLayout( "ShowOnlineLayout" ); + uno::Reference< beans::XPropertySet > xViewProperties; +@@ -870,8 +873,9 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& + { + uno::Reference< drawing::XShapes > xShapes; // sj: do not allow to export notes when + if ( ! ( aSelection >>= xShapes ) ) // exporting a selection -> todo: in the dialog +- bSecondPassForImpressNotes = true; // the export notes checkbox needs to be disabled ++ bExportNotesPages = true; + } ++ const bool bExportPages = bExportNotesPages ? !mbExportOnlyNotesPages : true; + + if( aPageRange.isEmpty() ) + { +@@ -885,18 +889,18 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& + if ( pResMgr ) + { + sal_Int32 nTotalPageCount = aRangeEnum.size(); +- if ( bSecondPassForImpressNotes ) ++ if ( bExportPages && bExportNotesPages ) + nTotalPageCount *= 2; + mxStatusIndicator->start( OUString( ResId( PDF_PROGRESS_BAR, *pResMgr ) ), nTotalPageCount ); + } + } + +- if( nPageCount > 0 ) ++ bRet = nPageCount > 0; ++ ++ if ( bRet && bExportPages ) + bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aRangeEnum, aRenderOptions, nPageCount ); +- else +- bRet = false; + +- if ( bRet && bSecondPassForImpressNotes ) ++ if ( bRet && bExportNotesPages ) + { + rExportNotesValue <<= sal_True; + bRet = ExportSelection( *pPDFWriter, xRenderable, aSelection, aRangeEnum, aRenderOptions, nPageCount ); +diff --git a/filter/source/pdf/pdfexport.hxx b/filter/source/pdf/pdfexport.hxx +index 499beb1..47e960a 100644 +--- a/filter/source/pdf/pdfexport.hxx ++++ b/filter/source/pdf/pdfexport.hxx +@@ -49,6 +49,7 @@ private: + bool mbExportNotes; + bool mbViewPDF; + bool mbExportNotesPages; ++ bool mbExportOnlyNotesPages; + bool mbUseTransitionEffects; + bool mbExportBookmarks; + bool mbExportHiddenSlides; +diff --git a/filter/uiconfig/ui/pdfgeneralpage.ui b/filter/uiconfig/ui/pdfgeneralpage.ui +index 7ba4a25..52314ac 100644 +--- a/filter/uiconfig/ui/pdfgeneralpage.ui ++++ b/filter/uiconfig/ui/pdfgeneralpage.ui +@@ -1,5 +1,5 @@ + +- ++ + + + +@@ -111,8 +111,8 @@ + + False + True +- 0 + Slides: ++ 0 + + + 0 +@@ -191,9 +191,9 @@ + + True + False +- 0 + _Quality: + True ++ 0 + + + +@@ -378,10 +378,10 @@ + + True + False +- 0 + Text: + True + watermarkentry ++ 0 + + + +@@ -512,10 +512,10 @@ + + True + False +- 0 + Submit _format: + True + format ++ 0 + + + 0 +@@ -604,7 +604,7 @@ + + + 0 +- 9 ++ 10 + + + +@@ -619,7 +619,7 @@ + + + 0 +- 10 ++ 11 + + + +@@ -634,7 +634,7 @@ + + + 0 +- 8 ++ 9 + + + +@@ -652,6 +652,28 @@ + 7 + + ++ ++ ++ True ++ False ++ 12 ++ ++ ++ Export onl_y notes pages ++ True ++ True ++ False ++ True ++ 0 ++ True ++ ++ ++ ++ ++ 0 ++ 8 ++ ++ + + + +diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs +index ad22cd2..782734a 100644 +--- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs ++++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs +@@ -5134,6 +5134,13 @@ + + false + ++ ++ ++ Specifies if only notes pages (i.e., not slides) are exported to PDF. (Notes pages ++ are available in Impress documents only). ++ ++ false ++ + + + Specifies slide transitions are exported to PDF. This option +-- +2.5.0 + diff --git a/SOURCES/0001-tdf-80999-Canceling-password-prompt-should-abort-det.patch b/SOURCES/0001-tdf-80999-Canceling-password-prompt-should-abort-det.patch new file mode 100644 index 0000000..b2bec4d --- /dev/null +++ b/SOURCES/0001-tdf-80999-Canceling-password-prompt-should-abort-det.patch @@ -0,0 +1,78 @@ +From 307cf8f9a19bc768d28394cc183a3d8bf634b7de Mon Sep 17 00:00:00 2001 +From: Maxim Monastirsky +Date: Wed, 27 Apr 2016 16:19:13 +0300 +Subject: [PATCH] tdf#80999 Canceling password prompt should abort detection + +... instead of continuing the detection loop and being +"detected" as plain text. The detection API will from now +return a type based on the file extension only, which is +far more useful than "plain text" anyway. Plus the media +descriptor has a flag to indicate that the detection wasn't +completed, which can be also used by the loading code to +abort the loading process. + +Change-Id: Ida37e2687bd5cd86b5780620724e9bce82e11946 +Reviewed-on: https://gerrit.libreoffice.org/24428 +Tested-by: Jenkins +Reviewed-by: Maxim Monastirsky +(cherry picked from commit 579c2de3a88483eff0664d3a303b19cbd386db47) +--- + framework/source/loadenv/loadenv.cxx | 5 +++++ + oox/source/core/filterdetect.cxx | 18 +++++++++++++----- + 2 files changed, 18 insertions(+), 5 deletions(-) + +diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx +index 4261971..05e7821 100644 +--- a/framework/source/loadenv/loadenv.cxx ++++ b/framework/source/loadenv/loadenv.cxx +@@ -789,6 +789,11 @@ void LoadEnv::impl_detectTypeAndFilter() + aWriteLock.clear(); + // <- SAFE + ++ // We do have potentially correct type, but the detection process was aborted. ++ if (m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ABORTED(), false)) ++ throw LoadEnvException( ++ LoadEnvException::ID_UNSUPPORTED_CONTENT, "type detection aborted"); ++ + // But the type isn't enough. For loading sometimes we need more information. + // E.g. for our "_default" feature, where we recycle any frame which contains + // and "Untitled" document, we must know if the new document is based on a template! +diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx +index d48d25c..94ea20e 100644 +--- a/oox/source/core/filterdetect.cxx ++++ b/oox/source/core/filterdetect.cxx +@@ -386,11 +386,7 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq + OUString aFilterName; + MediaDescriptor aMediaDescriptor( rMediaDescSeq ); + +- /* Check that the user has not chosen to abort detection, e.g. by hitting +- 'Cancel' in the password input dialog. This may happen because this +- filter detection is used by different filters. */ +- bool bAborted = aMediaDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_ABORTED(), false ); +- if( !bAborted ) try ++ try + { + aMediaDescriptor.addInputStream(); + +@@ -419,6 +415,18 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq + } + catch( const Exception& ) + { ++ if ( aMediaDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_ABORTED(), false ) ) ++ /* The user chose to abort detection, e.g. by hitting 'Cancel' in the password input dialog, ++ so we have to return non-empty type name to abort the detection loop. The loading code is ++ supposed to check whether the "Aborted" flag is present in the descriptor, and to not attempt ++ to actually load the file then. ++ ++ The returned type name is the one we got as an input, which typically was detected by the flat ++ detection (i.e. by file extension), so normally that's the correct one. Also at this point we ++ already know that the file is OLE encrypted package, so trying with other type detectors doesn't ++ make much sense anyway. ++ */ ++ aFilterName = aMediaDescriptor.getUnpackedValueOrDefault( MediaDescriptor::PROP_TYPENAME(), OUString() ); + } + + // write back changed media descriptor members +-- +2.9.3 + diff --git a/SOURCES/0001-tdf-86575-for-OOXML-write-plain-REF-if-deleted-parts.patch b/SOURCES/0001-tdf-86575-for-OOXML-write-plain-REF-if-deleted-parts.patch new file mode 100644 index 0000000..341f36d --- /dev/null +++ b/SOURCES/0001-tdf-86575-for-OOXML-write-plain-REF-if-deleted-parts.patch @@ -0,0 +1,75 @@ +From 8727412bd1619f42f0dcd9ea820c2348a9bd8af9 Mon Sep 17 00:00:00 2001 +Message-Id: <8727412bd1619f42f0dcd9ea820c2348a9bd8af9.1462798322.git.erack@redhat.com> +From: Eike Rathke +Date: Fri, 6 May 2016 16:56:29 +0200 +Subject: [PATCH] tdf#86575 for OOXML write plain #REF! if deleted parts +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="------------erAck-patch-parts" + +This is a multi-part message in MIME format. +--------------erAck-patch-parts +Content-Type: text/plain; charset=UTF-8; format=fixed +Content-Transfer-Encoding: 8bit + + +(cherry picked from commit bb0ef99fb9dce30e99a7e9f7fa295a634d07b423) + +write the [#REF!] as defined in ODFF, tdf#86575 related + +... if a part of the reference was deleted, instead of [.#REF!A1] + +Actually this is a regression that already can be tracked down to +c54616f62bc70a9d39abf8837a9d7c3031c80a41 which changed things to use +ValidAddress() only. + +(cherry picked from commit eeb203089f2ba6dffba9a2543c9a7e8bf551bbc5) + +70f68722d7af02f6da3380c2dd9d54704c20b451 + +Change-Id: Ie3233d72bdbdd0ab82386c98a46755ce64ef3e7f +Reviewed-on: https://gerrit.libreoffice.org/24705 +Tested-by: Jenkins +Reviewed-by: Markus Mohrhard +--- + sc/source/core/tool/compiler.cxx | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + + +--------------erAck-patch-parts +Content-Type: text/x-patch; name="0001-tdf-86575-for-OOXML-write-plain-REF-if-deleted-parts.patch" +Content-Transfer-Encoding: 8bit +Content-Disposition: attachment; filename="0001-tdf-86575-for-OOXML-write-plain-REF-if-deleted-parts.patch" + +diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx +index 80f37a4..091e2e3 100644 +--- a/sc/source/core/tool/compiler.cxx ++++ b/sc/source/core/tool/compiler.cxx +@@ -1011,7 +1011,8 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1 + if( !bSingleRef ) + aAbs2 = rRef.Ref2.toAbs(rPos); + +- if (FormulaGrammar::isODFF(eGram) && (!ValidAddress(aAbs1) || !ValidAddress(aAbs2))) ++ if (FormulaGrammar::isODFF(eGram) && (rRef.Ref1.IsDeleted() || !ValidAddress(aAbs1) || ++ (!bSingleRef && (rRef.Ref2.IsDeleted() || !ValidAddress(aAbs2))))) + { + rBuffer.append(rErrRef); + // For ODFF write [#REF!], but not for PODF so apps reading ODF +@@ -1408,6 +1409,14 @@ struct ConventionXL_OOX : public ConventionXL_A1 + aPos.SetRow(0); + } + ++ if (rRef.Ref1.IsDeleted() || (!bSingleRef && rRef.Ref2.IsDeleted())) ++ { ++ // For OOXML write plain "#REF!" instead of detailed sheet/col/row ++ // information. ++ rBuf.append(rErrRef); ++ return; ++ } ++ + ConventionXL_A1::makeRefStr( rBuf, eGram, aPos, rErrRef, rTabNames, rRef, bSingleRef, bFromRangeName); + } + + +--------------erAck-patch-parts-- + + diff --git a/SOURCES/0001-tdf-95210-SetHandleControllerPosition-is-busted-wrt-.patch b/SOURCES/0001-tdf-95210-SetHandleControllerPosition-is-busted-wrt-.patch new file mode 100644 index 0000000..f6dc981 --- /dev/null +++ b/SOURCES/0001-tdf-95210-SetHandleControllerPosition-is-busted-wrt-.patch @@ -0,0 +1,64 @@ +From eafd3ee3f01bceef0eb3327be3139a8eee2a2b2e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 5 Nov 2015 13:42:13 +0000 +Subject: [PATCH] tdf#95210 SetHandleControllerPosition is busted wrt + HandleFlags::REFX + +so instead of saving the initial pos and trying to restore the pos, instead use +a bigger hammer and save the entire geometry and restore that instead. + +Change-Id: Id06ea8f205f30771987089c5dc949bb52adc7a27 +--- + cui/source/tabpages/transfrm.cxx | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx +index f6b1f26..0db63db 100644 +--- a/cui/source/tabpages/transfrm.cxx ++++ b/cui/source/tabpages/transfrm.cxx +@@ -633,10 +633,15 @@ void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs) + SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier(); + if (eKind == OBJ_CUSTOMSHAPE) + { ++ //save geometry ++ SdrCustomShapeGeometryItem aInitialGeometry = ++ static_cast(pObj->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY)); ++ + EnhancedCustomShape2d aShape(pObj); +- Point aInitialPosition; ++ + for (int i = 0; i < 2; ++i) + { ++ Point aInitialPosition; + if (!aShape.GetHandlePosition(i, aInitialPosition)) + break; + m_aControlGroups[i]->Enable(); +@@ -655,14 +660,10 @@ void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs) + aShape.GetHandlePosition(i, aMinPosition); + + Rectangle aLogicRect = aShape.GetLogicRect(); ++ aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top()); + aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top()); + aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top()); + +- aPosition.X = aInitialPosition.X(); +- aPosition.Y = aInitialPosition.Y(); +- aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top()); +- aShape.SetHandleControllerPosition(i, aPosition); +- + SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit); + SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit); + +@@ -681,6 +682,9 @@ void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs) + m_aControlY[i]->SetMax(aMaxPosition.Y(), FUNIT_MM); + } + } ++ ++ //restore geometry ++ pObj->SetMergedItem(aInitialGeometry); + } + } + for (int i = 0; i < 2; ++i) +-- +2.5.0 + diff --git a/SOURCES/0001-tdf-97665-Let-s-hope-that-over-activation-isn-t-real.patch b/SOURCES/0001-tdf-97665-Let-s-hope-that-over-activation-isn-t-real.patch new file mode 100644 index 0000000..1041213 --- /dev/null +++ b/SOURCES/0001-tdf-97665-Let-s-hope-that-over-activation-isn-t-real.patch @@ -0,0 +1,328 @@ +From fcab9d2bcef3997790f3ae68521444cbaa0c5b29 Mon Sep 17 00:00:00 2001 +From: Maxim Monastirsky +Date: Sun, 7 Feb 2016 17:53:40 +0200 +Subject: [PATCH] tdf#97665 Let's hope that over activation isn't really needed + +- MenuBarManager::Activate has a check for duplicate activation, + which makes the second activation attempt fail. Removing this + check or deactivating after each activation will likely affect + performance even more, but on the other hand should solve + lp#1296715, which was the main reason of the over activation + in the first place. So let's activate only one menu at a time, + and do full activation only on the initial update. + +- Unfortunately the HUD activation callback doesn't work, so + we still have to keep active status listener for all menu + items. (Which is BTW against the recommendation in + XPopupMenuController::updatePopupMenu IDL doc. Fortunately + the performance problem hardly noticeable on modern hw.) + +Reviewed-on: https://gerrit.libreoffice.org/22369 +Tested-by: Jenkins +Reviewed-by: Maxim Monastirsky +(cherry picked from commit 2abdcfd641883f246fe78f2fbe38499c9382c059) + +Change-Id: I96affa72412f3f38160fdca4b6efd20ca68d059f +--- + framework/inc/uielement/menubarmanager.hxx | 4 +- + .../source/uielement/generictoolbarcontroller.cxx | 2 +- + framework/source/uielement/menubarmanager.cxx | 13 ++--- + include/vcl/menu.hxx | 9 +--- + vcl/inc/salmenu.hxx | 1 + + vcl/inc/unx/gtk/gtksalmenu.hxx | 4 +- + vcl/source/window/menu.cxx | 20 +++----- + vcl/unx/gtk/window/gloactiongroup.cxx | 2 +- + vcl/unx/gtk/window/gtksalmenu.cxx | 59 ++++++---------------- + 9 files changed, 38 insertions(+), 76 deletions(-) + +diff --git a/framework/inc/uielement/menubarmanager.hxx b/framework/inc/uielement/menubarmanager.hxx +index b72d515..99f0df0 100644 +--- a/framework/inc/uielement/menubarmanager.hxx ++++ b/framework/inc/uielement/menubarmanager.hxx +@@ -95,7 +95,8 @@ class MenuBarManager : public com::sun::star::frame::XStatusListener + const OUString& aModuleIdentifier, + Menu* pMenu, + bool bDelete, +- bool bDeleteChildren ); ++ bool bDeleteChildren, ++ bool bHasMenuBar = true ); + + virtual ~MenuBarManager(); + +@@ -217,6 +218,7 @@ class MenuBarManager : public com::sun::star::frame::XStatusListener + bool m_bRetrieveImages : 1, + m_bAcceleratorCfg : 1; + bool m_bModuleIdentified; ++ bool m_bHasMenuBar; + OUString m_aMenuItemCommand; + OUString m_aModuleIdentifier; + Menu* m_pVCLMenu; +diff --git a/framework/source/uielement/generictoolbarcontroller.cxx b/framework/source/uielement/generictoolbarcontroller.cxx +index 183da37..6e83c54 100644 +--- a/framework/source/uielement/generictoolbarcontroller.cxx ++++ b/framework/source/uielement/generictoolbarcontroller.cxx +@@ -348,7 +348,7 @@ MenuToolbarController::createPopupWindow() throw (::com::sun::star::uno::Runtime + Reference< XDispatchProvider > xDispatch; + Reference< XURLTransformer > xURLTransformer = URLTransformer::create( m_xContext ); + pMenu = new Toolbarmenu(); +- m_xMenuManager.set( new MenuBarManager( m_xContext, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, true, true ) ); ++ m_xMenuManager.set( new MenuBarManager( m_xContext, m_xFrame, xURLTransformer, xDispatch, m_aModuleIdentifier, pMenu, true, true, false ) ); + if (m_xMenuManager.is()) + { + MenuBarManager& rMgr = dynamic_cast(*m_xMenuManager.get()); +diff --git a/framework/source/uielement/menubarmanager.cxx b/framework/source/uielement/menubarmanager.cxx +index 13e145f..2096408 100644 +--- a/framework/source/uielement/menubarmanager.cxx ++++ b/framework/source/uielement/menubarmanager.cxx +@@ -135,12 +135,13 @@ MenuBarManager::MenuBarManager( + const Reference< XURLTransformer >& _xURLTransformer, + const Reference< XDispatchProvider >& rDispatchProvider, + const OUString& rModuleIdentifier, +- Menu* pMenu, bool bDelete, bool bDeleteChildren ): ++ Menu* pMenu, bool bDelete, bool bDeleteChildren, bool bHasMenuBar ): + OWeakObject() + , m_bDisposed( false ) + , m_bRetrieveImages( false ) + , m_bAcceleratorCfg( false ) + , m_bModuleIdentified( false ) ++ , m_bHasMenuBar( bHasMenuBar ) + , m_aListenerContainer( m_mutex ) + , m_xContext(rxContext) + , m_xURLTransformer(_xURLTransformer) +@@ -163,6 +164,7 @@ MenuBarManager::MenuBarManager( + , m_bRetrieveImages( true ) + , m_bAcceleratorCfg( false ) + , m_bModuleIdentified( false ) ++ , m_bHasMenuBar( true ) + , m_aListenerContainer( m_mutex ) + , m_xContext(rxContext) + , m_xURLTransformer(_xURLTransformer) +@@ -392,9 +394,6 @@ throw ( RuntimeException, std::exception ) + + SolarMutexGuard aSolarGuard; + { +- vcl::MenuInvalidator::Invalidated(); +- } +- { + if ( m_bDisposed ) + return; + +@@ -492,6 +491,8 @@ throw ( RuntimeException, std::exception ) + pMenuItemHandler->xMenuItemDispatch.clear(); + } + } ++ if ( m_bHasMenuBar && !m_bActive ) ++ m_pVCLMenu->UpdateNativeMenu(); + } + } + +@@ -896,8 +897,8 @@ IMPL_LINK_TYPED( MenuBarManager, Activate, Menu *, pMenu, bool ) + if ( !bPopupMenu ) + { + xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); +- xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); +- xMenuItemDispatch->addStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); ++ if ( !m_bHasMenuBar ) ++ xMenuItemDispatch->removeStatusListener( static_cast< XStatusListener* >( this ), aTargetURL ); + } + } + else if ( !bPopupMenu ) +diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx +index 2a4abcf..a44f2a8 100644 +--- a/include/vcl/menu.hxx ++++ b/include/vcl/menu.hxx +@@ -308,6 +308,8 @@ public: + void RemoveDisabledEntries( bool bCheckPopups = true, bool bRemoveEmptyPopups = false ); + bool HasValidEntries( bool bCheckPopups = true ); + ++ void UpdateNativeMenu(); ++ + void SetItemText( sal_uInt16 nItemId, const OUString& rStr ); + OUString GetItemText( sal_uInt16 nItemId ) const; + +@@ -413,13 +415,6 @@ public: + }; + + +-namespace vcl { namespace MenuInvalidator { +- +-VCL_DLLPUBLIC VclEventListeners2* GetMenuInvalidateListeners(); +-VCL_DLLPUBLIC void Invalidated(); +- +-}} +- + class VCL_DLLPUBLIC MenuBar : public Menu + { + Link<> maCloseHdl; +diff --git a/vcl/inc/salmenu.hxx b/vcl/inc/salmenu.hxx +index aaea364..182958a 100644 +--- a/vcl/inc/salmenu.hxx ++++ b/vcl/inc/salmenu.hxx +@@ -80,6 +80,7 @@ public: + virtual bool ShowNativePopupMenu(FloatingWindow * pWin, const Rectangle& rRect, FloatWinPopupFlags nFlags); + virtual bool AddMenuBarButton( const SalMenuButtonItem& ); // return false if not implemented or failure + virtual void RemoveMenuBarButton( sal_uInt16 nId ); ++ virtual void Update() {} + + // TODO: implement show/hide for the Win/Mac VCL native backends + virtual void ShowItem( unsigned nPos, bool bShow ) { EnableItem( nPos, bShow ); } +diff --git a/vcl/inc/unx/gtk/gtksalmenu.hxx b/vcl/inc/unx/gtk/gtksalmenu.hxx +index e74de22..a8f289c 100644 +--- a/vcl/inc/unx/gtk/gtksalmenu.hxx ++++ b/vcl/inc/unx/gtk/gtksalmenu.hxx +@@ -97,11 +97,11 @@ public: + void NativeSetAccelerator( unsigned nSection, unsigned nItemPos, const vcl::KeyCode& rKeyCode, const OUString& rKeyName ); + + void DispatchCommand( gint itemId, const gchar* aCommand ); +- void Activate(); ++ void Activate( const gchar* aMenuCommand = nullptr ); + void Deactivate( const gchar* aMenuCommand ); + void Display( bool bVisible ); + bool PrepUpdate(); +- void Update(); // Update this menu only. ++ virtual void Update() override; // Update this menu only. + void UpdateFull(); // Update full menu hierarchy from this menu. + }; + +diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx +index cb83637..70e5ea1 100644 +--- a/vcl/source/window/menu.cxx ++++ b/vcl/source/window/menu.cxx +@@ -2295,6 +2295,12 @@ sal_uLong Menu::DeactivateMenuBar(sal_uLong nFocusId) + return nFocusId; + } + ++void Menu::UpdateNativeMenu() ++{ ++ if ( ImplGetSalMenu() ) ++ ImplGetSalMenu()->Update(); ++} ++ + void Menu::MenuBarKeyInput(const KeyEvent&) + { + } +@@ -3200,18 +3206,4 @@ ImplMenuDelData::~ImplMenuDelData() + const_cast< Menu* >( mpMenu )->ImplRemoveDel( *this ); + } + +-namespace vcl { namespace MenuInvalidator { +- static VclEventListeners2* pMenuInvalidateListeners = NULL; +- VclEventListeners2* GetMenuInvalidateListeners() +- { +- if(!pMenuInvalidateListeners) +- pMenuInvalidateListeners = new VclEventListeners2(); +- return pMenuInvalidateListeners; +- } +- void Invalidated() +- { +- VclSimpleEvent aEvent(0); +- GetMenuInvalidateListeners()->callListeners(&aEvent); +- }; +-} } + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/unx/gtk/window/gloactiongroup.cxx b/vcl/unx/gtk/window/gloactiongroup.cxx +index 23307fd..2066abd 100644 +--- a/vcl/unx/gtk/window/gloactiongroup.cxx ++++ b/vcl/unx/gtk/window/gloactiongroup.cxx +@@ -201,7 +201,7 @@ g_lo_action_group_perform_submenu_action (GLOActionGroup *group, + SAL_INFO("vcl.unity", "g_lo_action_group_perform_submenu_action on " << group << " to " << bState); + + if (bState) +- pSalMenu->Activate(); ++ pSalMenu->Activate (action_name); + else + pSalMenu->Deactivate (action_name); + } +diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx +index 4a18999..b07b8e5 100644 +--- a/vcl/unx/gtk/window/gtksalmenu.cxx ++++ b/vcl/unx/gtk/window/gtksalmenu.cxx +@@ -371,51 +371,9 @@ void GtkSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsig + pItem->mpSubMenu = pGtkSubMenu; + } + +-static bool bInvalidMenus = false; +-static gboolean RefreshMenusUnity(gpointer) +-{ +- SolarMutexGuard g; +- +- SalDisplay* pSalDisplay = vcl_sal::getSalDisplay(GetGenericData()); +- std::list< SalFrame* >::const_iterator pSalFrame = pSalDisplay->getFrames().begin(); +- std::list< SalFrame* >::const_iterator pEndSalFrame = pSalDisplay->getFrames().end(); +- for(; pSalFrame != pEndSalFrame; ++pSalFrame) { +- const GtkSalFrame* pGtkSalFrame = static_cast< const GtkSalFrame* >( *pSalFrame ); +- GtkSalFrame* pFrameNonConst = const_cast(pGtkSalFrame); +- GtkSalMenu* pSalMenu = static_cast(pFrameNonConst->GetMenu()); +- if(pSalMenu) { +- pSalMenu->Activate(); +- pSalMenu->UpdateFull(); +- } +- } +- bInvalidMenus = false; +- return FALSE; +-} +- +-static long RefreshMenusUnity(void*, void*) +-{ +- if(!bInvalidMenus) { +- g_timeout_add(10, &RefreshMenusUnity, NULL); +- bInvalidMenus = true; +- } +- return 0; +-} +- +-static Link<>* getRefreshLinkInstance() +-{ +- static Link<>* pLink = NULL; +- if(!pLink) { +- pLink = new Link<>(NULL, &RefreshMenusUnity); +- } +- return pLink; +-} +- + void GtkSalMenu::SetFrame( const SalFrame* pFrame ) + { + SolarMutexGuard aGuard; +- { +- vcl::MenuInvalidator::GetMenuInvalidateListeners()->addListener(*getRefreshLinkInstance()); +- } + + assert(mbMenuBar); + SAL_INFO("vcl.unity", "GtkSalMenu set to frame"); +@@ -671,6 +629,7 @@ void GtkSalMenu::DispatchCommand( gint itemId, const gchar *aCommand ) + void GtkSalMenu::ActivateAllSubmenus(MenuBar* pMenuBar) + { + pMenuBar->HandleMenuActivateEvent(mpVCLMenu); ++ pMenuBar->HandleMenuDeActivateEvent(mpVCLMenu); + for ( sal_uInt16 nPos = 0; nPos < maItems.size(); nPos++ ) + { + GtkSalMenuItem *pSalItem = maItems[ nPos ]; +@@ -682,11 +641,23 @@ void GtkSalMenu::ActivateAllSubmenus(MenuBar* pMenuBar) + } + } + +-void GtkSalMenu::Activate() ++void GtkSalMenu::Activate( const gchar* aMenuCommand ) + { + if ( !mbMenuBar ) + return; +- ActivateAllSubmenus(static_cast(mpVCLMenu)); ++ ++ if ( !aMenuCommand ) { ++ ActivateAllSubmenus( static_cast< MenuBar* >( mpVCLMenu ) ); ++ return; ++ } ++ ++ GtkSalMenu* pSalSubMenu = GetMenuForItemCommand( const_cast(aMenuCommand), TRUE ); ++ ++ if ( pSalSubMenu != nullptr ) { ++ MenuBar* pMenuBar = static_cast< MenuBar* >( mpVCLMenu ); ++ pMenuBar->HandleMenuActivateEvent( pSalSubMenu->mpVCLMenu ); ++ pSalSubMenu->Update(); ++ } + } + + void GtkSalMenu::Deactivate( const gchar* aMenuCommand ) +-- +2.7.1 + diff --git a/SOURCES/0001-tdf-99353-take-the-footgun-away-from-FilterCache.patch b/SOURCES/0001-tdf-99353-take-the-footgun-away-from-FilterCache.patch new file mode 100644 index 0000000..3fef21e --- /dev/null +++ b/SOURCES/0001-tdf-99353-take-the-footgun-away-from-FilterCache.patch @@ -0,0 +1,44 @@ +From 390ddd3bde617388e481b6747aa7bbea17d5ddf1 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 3 May 2016 14:49:34 +0200 +Subject: [PATCH] tdf#99353 take the footgun away from FilterCache + +FilterCache::impl_saveItem changes the properties of a config. item +one-by-one. But it also listens to the configuration changes and reloads +the whole item from the configuration on change... + +Change-Id: I9e4ed1c6b013925d07f0942717fe3421f924279d +--- + filter/source/config/cache/filtercache.cxx | 2 +- + filter/source/config/cache/filtercache.hxx | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/filter/source/config/cache/filtercache.cxx b/filter/source/config/cache/filtercache.cxx +index b9d15cf..6f5616d 100644 +--- a/filter/source/config/cache/filtercache.cxx ++++ b/filter/source/config/cache/filtercache.cxx +@@ -1786,7 +1786,7 @@ CacheItemList::iterator FilterCache::impl_loadItemOnDemand( EItemType + + void FilterCache::impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xItem, + EItemType eType, +- const CacheItem& aItem) ++ const CacheItem aItem) + throw(css::uno::Exception) + { + CacheItem::const_iterator pIt; +diff --git a/filter/source/config/cache/filtercache.hxx b/filter/source/config/cache/filtercache.hxx +index 93c8d78..4f8b063 100644 +--- a/filter/source/config/cache/filtercache.hxx ++++ b/filter/source/config/cache/filtercache.hxx +@@ -809,7 +809,7 @@ class FilterCache : public BaseLock + /** TODO */ + static void impl_saveItem(const css::uno::Reference< css::container::XNameReplace >& xSet , + EItemType eType , +- const CacheItem& aValue) ++ const CacheItem aValue) + throw(css::uno::Exception); + + +-- +2.7.4 + diff --git a/SOURCES/0001-tdf-99460-sw-layout-don-t-split-table-before-fly.patch b/SOURCES/0001-tdf-99460-sw-layout-don-t-split-table-before-fly.patch new file mode 100644 index 0000000..c6d4d94 --- /dev/null +++ b/SOURCES/0001-tdf-99460-sw-layout-don-t-split-table-before-fly.patch @@ -0,0 +1,107 @@ +From ac0400203d643242d5d4363590668ad5c667faba Mon Sep 17 00:00:00 2001 +From: Michael Stahl +Date: Fri, 22 Apr 2016 18:09:39 +0200 +Subject: [PATCH] tdf#99460 sw: layout: don't split table before fly + +First the table is formatted properly and then the following paragraph +is formatted, along with its anchored objects. +The Fly frame is aligned to the bottom of the page by +SwAnchoredObjectPosition::_AdjustVerRelPos() without checking for any +overlap, and thus overlaps the table. +Then SwFlyNotify and Notify_Background() invalidate the table's PrtArea, +and the table responds by splitting numerous times, until finally there +is a page where the table does not overlap with the fly any more. +Instead of the table splitting, the paragraph with the Fly anchored to +it should move to the next page; suppressing the table invalidation in +Notify_Background() appears to achieve that. + +Change-Id: If65879f1756856bda344e0ef8fbffbc33e80f3ec +Reviewed-on: https://gerrit.libreoffice.org/24307 +Tested-by: Jenkins +Reviewed-by: Michael Stahl +--- + sw/source/core/layout/frmtool.cxx | 51 ++++++++++++++++++++++++++++----------- + 1 file changed, 37 insertions(+), 14 deletions(-) + +diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx +index 72bfaef..f73402d 100644 +--- a/sw/source/core/layout/frmtool.cxx ++++ b/sw/source/core/layout/frmtool.cxx +@@ -2962,37 +2962,60 @@ void Notify_Background( const SdrObject* pObj, + } + SwFrm *pLastTab = 0; + ++ bool isValidTableBeforeAnchor(false); + while ( pCnt && pArea && pArea->IsAnLower( pCnt ) ) + { + ::lcl_NotifyContent( pObj, pCnt, rRect, eHint ); + if ( pCnt->IsInTab() ) + { +- SwLayoutFrm* pCell = pCnt->GetUpper(); +- // #i40606# - use +- // instead of , because a recalculation +- // of the bounding rectangle isn't intended here. +- if ( pCell->IsCellFrm() && +- ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) || +- pCell->Frm().IsOver( rRect ) ) ) +- { +- const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient(); +- if ( text::VertOrientation::NONE != rOri.GetVertOrient() ) +- pCell->InvalidatePrt(); +- } + SwTabFrm *pTab = pCnt->FindTabFrm(); + if ( pTab != pLastTab ) + { + pLastTab = pTab; ++ isValidTableBeforeAnchor = false; ++ if (PREP_FLY_ARRIVE == eHint ++ && pFlyFrm // TODO: do it for draw objects too? ++ && pTab->IsFollow() // table starts on previous page? ++ // "through" means they will actually overlap anyway ++ && SURROUND_THROUGHT != pFlyFrm->GetFormat()->GetSurround().GetSurround() ++ // if it's anchored in footer it can't move to other page ++ && !pAnchor->FindFooterOrHeader()) ++ { ++ SwFrm * pTmp(pAnchor->GetPrev()); ++ while (pTmp) ++ { ++ if (pTmp == pTab) ++ { ++ // tdf#99460 the table shouldn't be moved by the fly ++ isValidTableBeforeAnchor = true; ++ break; ++ } ++ pTmp = pTmp->GetPrev(); ++ } ++ } + // #i40606# - use + // instead of , because a recalculation + // of the bounding rectangle isn't intended here. +- if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) || +- pTab->Frm().IsOver( rRect ) ) ++ if (!isValidTableBeforeAnchor ++ && (pTab->Frm().IsOver(pObj->GetLastBoundRect()) || ++ pTab->Frm().IsOver(rRect))) + { + if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) ) + pTab->InvalidatePrt(); + } + } ++ SwLayoutFrm* pCell = pCnt->GetUpper(); ++ // #i40606# - use ++ // instead of , because a recalculation ++ // of the bounding rectangle isn't intended here. ++ if (!isValidTableBeforeAnchor && pCell->IsCellFrm() && ++ ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) || ++ pCell->Frm().IsOver( rRect ) ) ) ++ { ++ const SwFormatVertOrient &rOri = pCell->GetFormat()->GetVertOrient(); ++ if ( text::VertOrientation::NONE != rOri.GetVertOrient() ) ++ pCell->InvalidatePrt(); ++ } + } + pCnt = pCnt->GetNextContentFrm(); + } +-- +2.7.3 + diff --git a/SOURCES/0001-these-popups-should-start-invisible-and-take-default.patch b/SOURCES/0001-these-popups-should-start-invisible-and-take-default.patch new file mode 100644 index 0000000..be6a440 --- /dev/null +++ b/SOURCES/0001-these-popups-should-start-invisible-and-take-default.patch @@ -0,0 +1,49 @@ +From bd8559a4722825b4a1fdb33042b90b63295ef835 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 17 Dec 2015 16:33:41 +0000 +Subject: [PATCH 1/2] these popups should start invisible and take default + popup menu bits + +so they can position correctly under wayland + +Change-Id: Idf65c0ef27be5aa6027a516207fd34c2e03407ca +--- + svx/uiconfig/ui/floatingundoredo.ui | 1 - + svx/uiconfig/ui/paralinespacingcontrol.ui | 2 -- + 2 files changed, 3 deletions(-) + +diff --git a/svx/uiconfig/ui/floatingundoredo.ui b/svx/uiconfig/ui/floatingundoredo.ui +index 66f30a6..2c48f82 100644 +--- a/svx/uiconfig/ui/floatingundoredo.ui ++++ b/svx/uiconfig/ui/floatingundoredo.ui +@@ -11,7 +11,6 @@ + True + popup-menu + True +- False + False + + +diff --git a/svx/uiconfig/ui/paralinespacingcontrol.ui b/svx/uiconfig/ui/paralinespacingcontrol.ui +index 5d7402b..67ca9c1 100644 +--- a/svx/uiconfig/ui/paralinespacingcontrol.ui ++++ b/svx/uiconfig/ui/paralinespacingcontrol.ui +@@ -45,7 +45,6 @@ + 1 + + +- True + False + True + True +@@ -54,7 +53,6 @@ + True + popup-menu + True +- False + False + + +-- +2.5.0 + diff --git a/SOURCES/0001-time-stamp-object-selections-and-use-newest-as-ref-f.patch b/SOURCES/0001-time-stamp-object-selections-and-use-newest-as-ref-f.patch new file mode 100644 index 0000000..b801190 --- /dev/null +++ b/SOURCES/0001-time-stamp-object-selections-and-use-newest-as-ref-f.patch @@ -0,0 +1,124 @@ +From aff2d164a982917c57be5e8a18c6c1366b836c09 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 28 Aug 2015 15:13:41 +0100 +Subject: [PATCH] time stamp object selections and use newest as ref for + equalization + +Change-Id: I1bf22ddbaf263b240288f70d03d6949611f86b69 +--- + include/svx/svdmark.hxx | 8 ++++++++ + svx/source/svdraw/svdedtv2.cxx | 18 ++++++++++++++++-- + svx/source/svdraw/svdmark.cxx | 12 +++++++++--- + 3 files changed, 33 insertions(+), 5 deletions(-) + +diff --git a/include/svx/svdmark.hxx b/include/svx/svdmark.hxx +index cba0a75..aee9dd7 100644 +--- a/include/svx/svdmark.hxx ++++ b/include/svx/svdmark.hxx +@@ -42,7 +42,10 @@ typedef std::set SdrUShortCont; + // Everything a View needs to know about a selected object + class SVX_DLLPUBLIC SdrMark : public sdr::ObjectUser + { ++private: ++ void setTime(); + protected: ++ sal_Int64 mnTimeStamp; + SdrObject* mpSelectedSdrObject; // the selected object + SdrPageView* mpPageView; + SdrUShortCont* mpPoints; // Selected Points +@@ -145,6 +148,11 @@ public: + + return mpGluePoints; + } ++ ++ sal_Int64 getTimeStamp() const ++ { ++ return mnTimeStamp; ++ } + }; + + class SVX_DLLPUBLIC SdrMarkList +diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx +index 719355d..090efa7 100644 +--- a/svx/source/svdraw/svdedtv2.cxx ++++ b/svx/source/svdraw/svdedtv2.cxx +@@ -1181,7 +1181,19 @@ void SdrEditView::EqualizeMarkedObjects(bool bWidth) + if (nMarked < 2) + return; + +- SdrObject* pLastSelectedObj = rMarkList.GetMark(nMarked-1)->GetMarkedSdrObj(); ++ size_t nLastSelected = 0; ++ sal_Int64 nLastSelectedTime = rMarkList.GetMark(0)->getTimeStamp(); ++ for (size_t a = 1; a < nMarked; ++a) ++ { ++ sal_Int64 nCandidateTime = rMarkList.GetMark(a)->getTimeStamp(); ++ if (nCandidateTime > nLastSelectedTime) ++ { ++ nLastSelectedTime = nCandidateTime; ++ nLastSelected = a; ++ } ++ } ++ ++ SdrObject* pLastSelectedObj = rMarkList.GetMark(nLastSelected)->GetMarkedSdrObj(); + Size aLastRectSize(pLastSelectedObj->GetLogicRect().GetSize()); + + const bool bUndo = IsUndoEnabled(); +@@ -1189,8 +1201,10 @@ void SdrEditView::EqualizeMarkedObjects(bool bWidth) + if (bUndo) + BegUndo(); + +- for (size_t a = 0; a < nMarked-1; ++a) ++ for (size_t a = 0; a < nMarked; ++a) + { ++ if (a == nLastSelected) ++ continue; + SdrMark* pM = rMarkList.GetMark(a); + SdrObject* pObj = pM->GetMarkedSdrObj(); + Rectangle aLogicRect(pObj->GetLogicRect()); +diff --git a/svx/source/svdraw/svdmark.cxx b/svx/source/svdraw/svdmark.cxx +index 7ddde61..8b7f3e09c 100644 +--- a/svx/source/svdraw/svdmark.cxx ++++ b/svx/source/svdraw/svdmark.cxx +@@ -38,8 +38,12 @@ + #include + #include + +- +- ++void SdrMark::setTime() ++{ ++ TimeValue aNow; ++ osl_getSystemTime(&aNow); ++ mnTimeStamp = sal_Int64(aNow.Seconds) * 1000000000L + aNow.Nanosec; ++} + + SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView) + : mpSelectedSdrObject(pNewObj), +@@ -55,10 +59,12 @@ SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView) + { + mpSelectedSdrObject->AddObjectUser( *this ); + } ++ setTime(); + } + + SdrMark::SdrMark(const SdrMark& rMark) + : ObjectUser(), ++ mnTimeStamp(0), + mpSelectedSdrObject(0L), + mpPageView(0L), + mpPoints(0L), +@@ -117,10 +123,10 @@ void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj) + } + } + +- + SdrMark& SdrMark::operator=(const SdrMark& rMark) + { + SetMarkedSdrObj(rMark.mpSelectedSdrObject); ++ mnTimeStamp = rMark.mnTimeStamp; + mpPageView = rMark.mpPageView; + mbCon1 = rMark.mbCon1; + mbCon2 = rMark.mbCon2; +-- +2.4.0 + diff --git a/SOURCES/0001-use-the-users-preferred-initials-for-impress-annotat.patch b/SOURCES/0001-use-the-users-preferred-initials-for-impress-annotat.patch new file mode 100644 index 0000000..f68e972 --- /dev/null +++ b/SOURCES/0001-use-the-users-preferred-initials-for-impress-annotat.patch @@ -0,0 +1,200 @@ +From 9ba33206ca799d58fc18c0d320fa0e7c47eb00d1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 5 Feb 2016 10:44:12 +0000 +Subject: [PATCH] use the users preferred initials for impress annotations + +i.e. the ones entered in the tools->options + +and save and load those to/from odf similarly to +what we do for writer annotation initials + +Change-Id: Iadc0e994bfaf58632ce25b8f7cdc737580ee97bc +--- + offapi/com/sun/star/office/XAnnotation.idl | 3 +++ + sd/source/core/annotations/Annotation.cxx | 23 +++++++++++++++++++++++ + sd/source/ui/annotations/annotationmanager.cxx | 2 ++ + sd/source/ui/annotations/annotationtag.cxx | 8 +++++--- + xmloff/source/draw/sdxmlexp.cxx | 12 ++++++++++++ + xmloff/source/draw/ximppage.cxx | 7 +++++++ + 6 files changed, 52 insertions(+), 3 deletions(-) + +diff --git a/offapi/com/sun/star/office/XAnnotation.idl b/offapi/com/sun/star/office/XAnnotation.idl +index da3a235..d305743 100644 +--- a/offapi/com/sun/star/office/XAnnotation.idl ++++ b/offapi/com/sun/star/office/XAnnotation.idl +@@ -58,6 +58,9 @@ interface XAnnotation + /** stores the full name of the author who created this annotation. */ + [attribute] string Author; + ++ /** stores the initials of the author who created this annotation. */ ++ [attribute] string Initials; ++ + /** stores the date and time this annotation was last edited. */ + [attribute] ::com::sun::star::util::DateTime DateTime; + +diff --git a/sd/source/core/annotations/Annotation.cxx b/sd/source/core/annotations/Annotation.cxx +index 21a096b..9c2af42 100644 +--- a/sd/source/core/annotations/Annotation.cxx ++++ b/sd/source/core/annotations/Annotation.cxx +@@ -82,6 +82,9 @@ public: + virtual void SAL_CALL setSize( const ::com::sun::star::geometry::RealSize2D& _size ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; + virtual OUString SAL_CALL getAuthor() throw (RuntimeException, std::exception) SAL_OVERRIDE; + virtual void SAL_CALL setAuthor(const OUString & the_value) throw (RuntimeException, std::exception) SAL_OVERRIDE; ++ virtual OUString SAL_CALL getInitials() throw (RuntimeException, std::exception) SAL_OVERRIDE; ++ virtual void SAL_CALL setInitials(const OUString & the_value) throw (RuntimeException, std::exception) SAL_OVERRIDE; ++ + virtual util::DateTime SAL_CALL getDateTime() throw (RuntimeException, std::exception) SAL_OVERRIDE; + virtual void SAL_CALL setDateTime(const util::DateTime & the_value) throw (RuntimeException, std::exception) SAL_OVERRIDE; + virtual Reference< XText > SAL_CALL getTextRange() throw (RuntimeException, std::exception) SAL_OVERRIDE; +@@ -103,6 +106,7 @@ private: + RealPoint2D m_Position; + RealSize2D m_Size; + OUString m_Author; ++ OUString m_Initials; + util::DateTime m_DateTime; + rtl::Reference< TextApiObject > m_TextRange; + }; +@@ -126,6 +130,7 @@ struct AnnotationData + RealPoint2D m_Position; + RealSize2D m_Size; + OUString m_Author; ++ OUString m_Initials; + util::DateTime m_DateTime; + + void get( const rtl::Reference< Annotation >& xAnnotation ) +@@ -133,6 +138,7 @@ struct AnnotationData + m_Position = xAnnotation->getPosition(); + m_Size = xAnnotation->getSize(); + m_Author = xAnnotation->getAuthor(); ++ m_Initials = xAnnotation->getInitials(); + m_DateTime = xAnnotation->getDateTime(); + } + +@@ -141,6 +147,7 @@ struct AnnotationData + xAnnotation->setPosition(m_Position); + xAnnotation->setSize(m_Size); + xAnnotation->setAuthor(m_Author); ++ xAnnotation->setInitials(m_Initials); + xAnnotation->setDateTime(m_DateTime); + } + }; +@@ -290,6 +297,22 @@ void SAL_CALL Annotation::setAuthor(const OUString & the_value) throw (RuntimeEx + } + } + ++OUString SAL_CALL Annotation::getInitials() throw (RuntimeException, std::exception) ++{ ++ osl::MutexGuard g(m_aMutex); ++ return m_Initials; ++} ++ ++void SAL_CALL Annotation::setInitials(const OUString & the_value) throw (RuntimeException, std::exception) ++{ ++ prepareSet("Initials", Any(), Any(), nullptr); ++ { ++ osl::MutexGuard g(m_aMutex); ++ createChangeUndo(); ++ m_Initials = the_value; ++ } ++} ++ + util::DateTime SAL_CALL Annotation::getDateTime() throw (RuntimeException, std::exception) + { + osl::MutexGuard g(m_aMutex); +diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx +index 99451ab..ce5d487 100644 +--- a/sd/source/ui/annotations/annotationmanager.cxx ++++ b/sd/source/ui/annotations/annotationmanager.cxx +@@ -396,6 +396,7 @@ void AnnotationManagerImpl::InsertAnnotation() + // set current author to new annotation + SvtUserOptions aUserOptions; + xAnnotation->setAuthor( aUserOptions.GetFullName() ); ++ xAnnotation->setInitials( aUserOptions.GetID() ); + + // set current time to new annotation + xAnnotation->setDateTime( getCurrentDateTime() ); +@@ -467,6 +468,7 @@ void AnnotationManagerImpl::ExecuteReplyToAnnotation( SfxRequest& rReq ) + + SvtUserOptions aUserOptions; + xAnnotation->setAuthor( aUserOptions.GetFullName() ); ++ xAnnotation->setInitials( aUserOptions.GetID() ); + + // set current time to reply + xAnnotation->setDateTime( getCurrentDateTime() ); +diff --git a/sd/source/ui/annotations/annotationtag.cxx b/sd/source/ui/annotations/annotationtag.cxx +index 4faec96..86e4549 100644 +--- a/sd/source/ui/annotations/annotationtag.cxx ++++ b/sd/source/ui/annotations/annotationtag.cxx +@@ -517,9 +517,11 @@ BitmapEx AnnotationTag::CreateAnnotationBitmap( bool bSelected ) + { + ScopedVclPtrInstance< VirtualDevice > pVDev; + +- OUString sAuthor( getInitials( mxAnnotation->getAuthor() ) ); +- sAuthor += OUString( ' ' ); +- sAuthor += OUString::number( mnIndex ); ++ OUString sInitials(mxAnnotation->getInitials()); ++ if (sInitials.isEmpty()) ++ sInitials = getInitials(mxAnnotation->getAuthor()); ++ ++ OUString sAuthor(sInitials + " " + OUString::number(mnIndex)); + + pVDev->SetFont( mrFont ); + +diff --git a/xmloff/source/draw/sdxmlexp.cxx b/xmloff/source/draw/sdxmlexp.cxx +index 9371913..3698f76 100644 +--- a/xmloff/source/draw/sdxmlexp.cxx ++++ b/xmloff/source/draw/sdxmlexp.cxx +@@ -2718,6 +2718,18 @@ void SdXMLExport::exportAnnotations( const Reference& xDrawPage ) + this->Characters(aAuthor); + } + ++ if (SvtSaveOptions().GetODFDefaultVersion() > SvtSaveOptions::ODFVER_012) ++ { ++ // initials ++ OUString aInitials( xAnnotation->getInitials() ); ++ if( !aInitials.isEmpty() ) ++ { ++ SvXMLElementExport aInitialsElem( *this, XML_NAMESPACE_LO_EXT, ++ XML_SENDER_INITIALS, true, false ); ++ this->Characters(aInitials); ++ } ++ } ++ + { + // date time + com::sun::star::util::DateTime aDate( xAnnotation->getDateTime() ); +diff --git a/xmloff/source/draw/ximppage.cxx b/xmloff/source/draw/ximppage.cxx +index d60ed0f..26e3e7a 100644 +--- a/xmloff/source/draw/ximppage.cxx ++++ b/xmloff/source/draw/ximppage.cxx +@@ -67,6 +67,7 @@ private: + Reference< XTextCursor > mxCursor; + + OUStringBuffer maAuthorBuffer; ++ OUStringBuffer maInitialsBuffer; + OUStringBuffer maDateBuffer; + }; + +@@ -141,6 +142,11 @@ SvXMLImportContext * DrawAnnotationContext::CreateChildContext( sal_uInt16 nPref + else if( IsXMLToken( rLocalName, XML_DATE ) ) + pContext = new XMLStringBufferImportContext(GetImport(), nPrefix, rLocalName, maDateBuffer); + } ++ else if( (XML_NAMESPACE_TEXT == nPrefix || XML_NAMESPACE_LO_EXT == nPrefix) && ++ IsXMLToken(rLocalName, XML_SENDER_INITIALS) ) ++ { ++ pContext = new XMLStringBufferImportContext(GetImport(), nPrefix, rLocalName, maInitialsBuffer); ++ } + else + { + // create text cursor on demand +@@ -188,6 +194,7 @@ void DrawAnnotationContext::EndElement() + if( mxAnnotation.is() ) + { + mxAnnotation->setAuthor( maAuthorBuffer.makeStringAndClear() ); ++ mxAnnotation->setInitials( maInitialsBuffer.makeStringAndClear() ); + + util::DateTime aDateTime; + if (::sax::Converter::parseDateTime(aDateTime, 0, +-- +2.5.0 + diff --git a/SOURCES/0001-valgrind-scary-warning-that-the-cairo-font-options-w.patch b/SOURCES/0001-valgrind-scary-warning-that-the-cairo-font-options-w.patch new file mode 100644 index 0000000..ba3a09b --- /dev/null +++ b/SOURCES/0001-valgrind-scary-warning-that-the-cairo-font-options-w.patch @@ -0,0 +1,209 @@ +From 78c32c11b0911b905fced7519d8881262d6fb4a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 1 Dec 2015 20:35:28 +0000 +Subject: [PATCH] valgrind: scary warning that the cairo font options were + deleted before use + +(cherry picked from commit 3520b0f82aa2146958fbc1bda1cf7e9b5beb9a5d) + +Change-Id: I58427aafb30eca64a67bcf7dd9a7738d8da3e085 +--- + include/vcl/settings.hxx | 3 --- + vcl/inc/salinst.hxx | 4 ++++ + vcl/inc/unx/gtk/gtkinst.hxx | 2 ++ + vcl/source/app/settings.cxx | 16 ---------------- + vcl/unx/generic/gdi/cairotextrender.cxx | 12 ++++++------ + vcl/unx/gtk/app/gtkinst.cxx | 5 +++++ + vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx | 4 ---- + vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx | 3 --- + 8 files changed, 17 insertions(+), 32 deletions(-) + +diff --git a/include/vcl/settings.hxx b/include/vcl/settings.hxx +index 006e758..6df8b0d 100644 +--- a/include/vcl/settings.hxx ++++ b/include/vcl/settings.hxx +@@ -442,9 +442,6 @@ public: + void SetPrimaryButtonWarpsSlider( bool bPrimaryButtonWarpsSlider ); + bool GetPrimaryButtonWarpsSlider() const; + +- void SetCairoFontOptions( const void *pOptions ); +- const void* GetCairoFontOptions() const; +- + void SetAppFont( const vcl::Font& rFont ); + const vcl::Font& GetAppFont() const; + +diff --git a/vcl/inc/salinst.hxx b/vcl/inc/salinst.hxx +index f49bb4c..d89b1dd 100644 +--- a/vcl/inc/salinst.hxx ++++ b/vcl/inc/salinst.hxx +@@ -60,6 +60,8 @@ enum class VclInputFlags; + + enum SalYieldResult { EVENT, TIMEOUT }; + ++typedef struct _cairo_font_options cairo_font_options_t; ++ + class VCL_PLUGIN_PUBLIC SalInstance + { + private: +@@ -181,6 +183,8 @@ public: + virtual void updatePrinterUpdate() {} + virtual void jobStartedPrinterUpdate() {} + virtual void jobEndedPrinterUpdate() {} ++ ++ virtual const cairo_font_options_t* GetCairoFontOptions() { return nullptr; } + }; + + // called from SVMain +diff --git a/vcl/inc/unx/gtk/gtkinst.hxx b/vcl/inc/unx/gtk/gtkinst.hxx +index 189b6900..1ea6f8e 100644 +--- a/vcl/inc/unx/gtk/gtkinst.hxx ++++ b/vcl/inc/unx/gtk/gtkinst.hxx +@@ -98,6 +98,8 @@ public: + virtual css::uno::Reference< css::uno::XInterface > CreateClipboard( const css::uno::Sequence< css::uno::Any >& i_rArguments ) SAL_OVERRIDE; + #endif + ++ virtual const cairo_font_options_t* GetCairoFontOptions() override; ++ + void RemoveTimer (SalTimer *pTimer); + + // for managing a mirror of the in-flight un-dispatched gdk event queue +diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx +index 664f755..2f457c5 100644 +--- a/vcl/source/app/settings.cxx ++++ b/vcl/source/app/settings.cxx +@@ -191,7 +191,6 @@ struct ImplStyleData + bool mbPrimaryButtonWarpsSlider; + DialogStyle maDialogStyle; + FrameStyle maFrameStyle; +- const void* mpFontOptions; + + sal_uInt16 mnEdgeBlending; + Color maEdgeBlendingTopLeftColor; +@@ -546,7 +545,6 @@ ImplStyleData::ImplStyleData() : + mbAutoMnemonic = true; + mnToolbarIconSize = ToolbarIconSize::Unknown; + meUseImagesInMenus = TRISTATE_INDET; +- mpFontOptions = NULL; + mnEdgeBlending = 35; + maEdgeBlendingTopLeftColor = RGB_COLORDATA(0xC0, 0xC0, 0xC0); + maEdgeBlendingBottomRightColor = RGB_COLORDATA(0x40, 0x40, 0x40); +@@ -667,7 +665,6 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) : + mnToolbarIconSize = rData.mnToolbarIconSize; + mIconThemeScanner.reset(new vcl::IconThemeScanner(*rData.mIconThemeScanner)); + mIconThemeSelector.reset(new vcl::IconThemeSelector(*rData.mIconThemeSelector)); +- mpFontOptions = rData.mpFontOptions; + mnEdgeBlending = rData.mnEdgeBlending; + maEdgeBlendingTopLeftColor = rData.maEdgeBlendingTopLeftColor; + maEdgeBlendingBottomRightColor = rData.maEdgeBlendingBottomRightColor; +@@ -1547,19 +1544,6 @@ StyleSettings::GetPrimaryButtonWarpsSlider() const + } + + void +-StyleSettings::SetCairoFontOptions( const void *pOptions ) +-{ +- CopyData(); +- mxData->mpFontOptions = pOptions; +-} +- +-const void* +-StyleSettings::GetCairoFontOptions() const +-{ +- return mxData->mpFontOptions; +-} +- +-void + StyleSettings::SetAppFont( const vcl::Font& rFont ) + { + CopyData(); +diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx +index 2e3aa90..4ffddf3 100644 +--- a/vcl/unx/generic/gdi/cairotextrender.cxx ++++ b/vcl/unx/generic/gdi/cairotextrender.cxx +@@ -214,8 +214,9 @@ void CairoTextRender::DrawServerFontLayout( const ServerFontLayout& rLayout ) + return; + } + +- if (const void *pOptions = Application::GetSettings().GetStyleSettings().GetCairoFontOptions()) +- cairo_set_font_options(cr, static_cast(pOptions)); ++ ImplSVData* pSVData = ImplGetSVData(); ++ if (const cairo_font_options_t* pFontOptions = pSVData->mpDefInst->GetCairoFontOptions()) ++ cairo_set_font_options(cr, pFontOptions); + + double nDX, nDY; + getSurfaceOffset(nDX, nDY); +@@ -462,12 +463,11 @@ void CairoTextRender::GetDevFontList( PhysicalFontCollection* pFontCollection ) + + void cairosubcallback(void* pPattern) + { +- const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); +- const void* pFontOptions = rStyleSettings.GetCairoFontOptions(); ++ ImplSVData* pSVData = ImplGetSVData(); ++ const cairo_font_options_t* pFontOptions = pSVData->mpDefInst->GetCairoFontOptions(); + if( !pFontOptions ) + return; +- cairo_ft_font_options_substitute(static_cast(pFontOptions), +- static_cast(pPattern)); ++ cairo_ft_font_options_substitute(pFontOptions, static_cast(pPattern)); + } + + ImplFontOptions* GetFCFontOptions( const ImplFontAttributes& rFontAttributes, int nSize) +diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx +index 9242b88..7d8111c 100644 +--- a/vcl/unx/gtk/app/gtkinst.cxx ++++ b/vcl/unx/gtk/app/gtkinst.cxx +@@ -473,4 +473,9 @@ GtkInstance::getPrintWrapper() const + return m_xPrintWrapper; + } + ++const cairo_font_options_t* GtkInstance::GetCairoFontOptions() ++{ ++ return gdk_screen_get_font_options(gdk_screen_get_default()); ++} ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +index 1220596..aa53b65 100644 +--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx ++++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +@@ -3928,7 +3928,6 @@ void GtkSalGraphics::refreshFontconfig( GtkSettings *pSettings ) + + void GtkSalGraphics::updateSettings( AllSettings& rSettings ) + { +- GdkScreen* pScreen = gtk_widget_get_screen( m_pWindow ); + gtk_widget_ensure_style( m_pWindow ); + GtkStyle* pStyle = gtk_widget_get_style( m_pWindow ); + GtkSettings* pSettings = gtk_widget_get_settings( m_pWindow ); +@@ -4257,9 +4256,6 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) + + aStyleSet.SetToolbarIconSize( ToolbarIconSize::Large ); + +- const cairo_font_options_t* pNewOptions = gdk_screen_get_font_options( pScreen ); +- aStyleSet.SetCairoFontOptions( pNewOptions ); +- + // finally update the collected settings + rSettings.SetStyleSettings( aStyleSet ); + } +diff --git a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx +index 90d8734..2d639bf 100644 +--- a/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx ++++ b/vcl/unx/gtk3/gdi/gtk3salnativewidgets-gtk.cxx +@@ -1452,7 +1452,6 @@ static inline ::Color getColorFromColor( const GdkColor& rCol ) + + void GtkSalGraphics::updateSettings( AllSettings& rSettings ) + { +- GdkScreen* pScreen = gtk_widget_get_screen( mpWindow ); + GtkStyleContext* pStyle = gtk_widget_get_style_context( mpWindow ); + GtkSettings* pSettings = gtk_widget_get_settings( mpWindow ); + StyleSettings aStyleSet = rSettings.GetStyleSettings(); +@@ -1801,8 +1800,6 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) + + aStyleSet.SetToolbarIconSize( ToolbarIconSize::Large ); + +- const cairo_font_options_t* pNewOptions = gdk_screen_get_font_options(pScreen); +- aStyleSet.SetCairoFontOptions( pNewOptions ); + // finally update the collected settings + rSettings.SetStyleSettings( aStyleSet ); + gchar* pThemeName = NULL; +-- +2.5.0 + diff --git a/SOURCES/0001-vcl-assign-nullptr-after-deleting.patch b/SOURCES/0001-vcl-assign-nullptr-after-deleting.patch new file mode 100644 index 0000000..6e7cf14 --- /dev/null +++ b/SOURCES/0001-vcl-assign-nullptr-after-deleting.patch @@ -0,0 +1,74 @@ +From 2bd35de5cf811af8f8019549fcdb5ccf2af7af93 Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Mon, 7 Sep 2015 17:43:04 -0400 +Subject: [PATCH 1/6] vcl: assign nullptr after deleting + +In the preinit stage, the VCL initialization is done by the parent process +and when the lo_startmain thread de-initialize the VCL, some services are +disposed early, and it causes segmentation violation. + +So it is ensured that pointers to service objetcs is set nullptr after +deleting. + +Change-Id: I65ecfc2d2694a981ec2986988efabdfd28d0cce4 +(cherry picked from commit 4886676a5b50caf0946b91491055cbdc2696f1ca) +--- + vcl/source/app/svdata.cxx | 4 ++-- + vcl/source/app/svmain.cxx | 10 +++++++--- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx +index 71d7628..0bbba59 100644 +--- a/vcl/source/app/svdata.cxx ++++ b/vcl/source/app/svdata.cxx +@@ -102,10 +102,10 @@ void ImplDeInitSVData() + + // delete global instance data + if( pSVData->mpSettingsConfigItem ) +- delete pSVData->mpSettingsConfigItem; ++ delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = nullptr; + + if( pSVData->mpDockingManager ) +- delete pSVData->mpDockingManager; ++ delete pSVData->mpDockingManager, pSVData->mpDockingManager = nullptr; + + if( pSVData->maCtrlData.mpFieldUnitStrings ) + delete pSVData->maCtrlData.mpFieldUnitStrings, pSVData->maCtrlData.mpFieldUnitStrings = NULL; +diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx +index 23757e8..3202019 100644 +--- a/vcl/source/app/svmain.cxx ++++ b/vcl/source/app/svmain.cxx +@@ -380,7 +380,7 @@ void DeInitVCL() + delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL; + + if ( pSVData->maAppData.mpIdleMgr ) +- delete pSVData->maAppData.mpIdleMgr; ++ delete pSVData->maAppData.mpIdleMgr, pSVData->maAppData.mpIdleMgr = nullptr; + Scheduler::ImplDeInitScheduler(); + + if ( pSVData->maWinData.mpMsgBoxImgList ) +@@ -539,7 +539,11 @@ void DeInitVCL() + pSVData->mpSalTimer = NULL; + + // Deinit Sal +- DestroySalInstance( pSVData->mpDefInst ); ++ if (pSVData->mpDefInst) ++ { ++ DestroySalInstance( pSVData->mpDefInst ); ++ pSVData->mpDefInst = nullptr; ++ } + + if( pOwnSvApp ) + { +@@ -566,7 +570,7 @@ struct WorkerThreadData + static HANDLE hThreadID = 0; + static unsigned __stdcall _threadmain( void *pArgs ) + { +- OleInitialize( NULL ); ++ OleInitialize( nullptr ); + ((WorkerThreadData*)pArgs)->pWorker( ((WorkerThreadData*)pArgs)->pThreadData ); + delete (WorkerThreadData*)pArgs; + OleUninitialize(); +-- +2.9.3 + diff --git a/SOURCES/0002-Fix-memleak-of-strings-allocated-in-VclGtkClipboard-.patch b/SOURCES/0002-Fix-memleak-of-strings-allocated-in-VclGtkClipboard-.patch new file mode 100644 index 0000000..a39d1a3 --- /dev/null +++ b/SOURCES/0002-Fix-memleak-of-strings-allocated-in-VclGtkClipboard-.patch @@ -0,0 +1,71 @@ +From b88646fc68cfc1c3840024fe3a59727c9eb9f95d Mon Sep 17 00:00:00 2001 +From: Dennis Francis +Date: Fri, 11 Dec 2015 09:19:22 +0530 +Subject: [PATCH 2/3] Fix memleak of strings allocated in + VclGtkClipboard::makeGtkTargetEntry + +This leak is produced when copy and paste of text/numbers +is done in Calc/Writer. + +Following is the trace produced by valgrind (trimmed) + + malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) + g_malloc (in /usr/lib64/libglib-2.0.so.0.4600.2) + g_strdup (in /usr/lib64/libglib-2.0.so.0.4600.2) + VclGtkClipboard::makeGtkTargetEntry(...) (gtk3gtkinst.cxx:467) + VclGtkClipboard::setContents(...) (gtk3gtkinst.cxx:557) + TransferableHelper::CopyToSelection(vcl::Window*) const (transfer.cxx:1019) + ScTabView::CheckSelectionTransfer() (tabview3.cxx:319) + ScTabView::UpdateAutoFillMark() (tabview3.cxx:144) + ScTabView::SelectionChanged() (tabview3.cxx:365) + ScViewFunc::PostPasteFromClip(ScRangeList const&, ScMarkData const&) (viewfun3.cxx:1753) + ScViewFunc::PasteFromClip(...) (viewfun3.cxx:1415) + ScClipUtil::PasteFromClipboard(ScViewData*, ScTabViewShell*, bool) (cliputil.cxx:69) + ScCellShell::ExecuteEdit(SfxRequest&) (cellsh1.cxx:1285) + SfxStubScCellShellExecuteEdit(SfxShell*, SfxRequest&) (scslots.hxx:7135) + SfxShell::CallExec(void (*)(SfxShell*, SfxRequest&), SfxRequest&) (shell.hxx:206) + SfxDispatcher::Call_Impl(SfxShell&, SfxSlot const&, SfxRequest&, bool) (dispatch.cxx:258)... + ... + +Change-Id: I12468e746f33a64e2b5f05e9ac1c6814c702ffd7 +Reviewed-on: https://gerrit.libreoffice.org/20646 +Reviewed-by: jan iversen +Tested-by: jan iversen +(cherry picked from commit 97df0e601a0d76664b4207d075fa6e2a5a51625c) +--- + vcl/unx/gtk3/gtk3gtkinst.cxx | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx +index e9210d0..f1a9ddc 100644 +--- a/vcl/unx/gtk3/gtk3gtkinst.cxx ++++ b/vcl/unx/gtk3/gtk3gtkinst.cxx +@@ -456,7 +456,7 @@ void VclGtkClipboard::OwnerChanged(GtkClipboard* clipboard, GdkEvent* /*event*/) + void VclGtkClipboard::ClipboardClear(GtkClipboard * /*clipboard*/) + { + for (auto &a : m_aGtkTargets) +- free(a.target); ++ g_free(a.target); + m_aGtkTargets.clear(); + } + +@@ -518,6 +518,7 @@ VclGtkClipboard::~VclGtkClipboard() + GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); + g_signal_handler_disconnect(clipboard, m_nOwnerChangedSignalId); + g_object_unref(m_pOwner); ++ ClipboardClear(nullptr); + } + + void VclGtkClipboard::setContents( +@@ -577,6 +578,8 @@ void VclGtkClipboard::setContents( + //if there was a previous gtk_clipboard_set_with_data call then + //ClipboardClearFunc will be called now + GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ if(G_OBJECT(m_pOwner) == gtk_clipboard_get_owner(clipboard)) ++ gtk_clipboard_clear(clipboard); + //use with_owner with m_pOwner so we can distinguish in handle_owner_change + //if we have gained or lost ownership of the clipboard + gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(), +-- +2.5.0 + diff --git a/SOURCES/0002-LOK-remove-unused-LOK_PARTMODE_EMBEDDEDOBJ.patch b/SOURCES/0002-LOK-remove-unused-LOK_PARTMODE_EMBEDDEDOBJ.patch new file mode 100644 index 0000000..2dca803 --- /dev/null +++ b/SOURCES/0002-LOK-remove-unused-LOK_PARTMODE_EMBEDDEDOBJ.patch @@ -0,0 +1,90 @@ +From f8c6d3406005aa7a6e408ca25f61a0db35acd6be Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 22 May 2015 12:14:36 +0100 +Subject: [PATCH 002/398] LOK: remove unused LOK_PARTMODE_EMBEDDEDOBJ + +Change-Id: I8cbb5b7a134fb84bd2c363b06f06f7f40964521f +(cherry picked from commit 39321c5ffa9b4196308575be6dd19f2b2924214f) +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 7 ++----- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 9 +-------- + sd/source/ui/unoidl/unomodel.cxx | 15 +-------------- + 3 files changed, 4 insertions(+), 27 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 5293aa9be4c0..66237e4512cf 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -28,11 +28,8 @@ LibreOfficeKitDocumentType; + + typedef enum + { +- LOK_PARTMODE_DEFAULT, +- LOK_PARTMODE_SLIDE, +- LOK_PARTMODE_NOTES, +- LOK_PARTMODE_SLIDENOTES, +- LOK_PARTMODE_EMBEDDEDOBJ ++ LOK_PARTMODE_SLIDES, ++ LOK_PARTMODE_NOTES + } + LibreOfficeKitPartMode; + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 83ec9d23c113..d20f43d90627 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -312,11 +312,8 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + + static void populatePartModeSelector( GtkComboBoxText* pSelector ) + { +- gtk_combo_box_text_append_text( pSelector, "Default" ); +- gtk_combo_box_text_append_text( pSelector, "Slide" ); ++ gtk_combo_box_text_append_text( pSelector, "Standard" ); + gtk_combo_box_text_append_text( pSelector, "Notes" ); +- gtk_combo_box_text_append_text( pSelector, "Combined (SlideNotes)" ); +- gtk_combo_box_text_append_text( pSelector, "Embedded Objects" ); + gtk_combo_box_set_active( GTK_COMBO_BOX(pSelector), 0 ); + } + +@@ -331,10 +328,6 @@ static void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ ) + { + lok_docview_set_partmode( LOK_DOCVIEW(pDocView), ePartMode ); + } +- +- // The number of items could change e.g. if we change from slide +- // to embeddede obj mode -- hence we should update the part list. +- populatePartSelector(); + } + #endif + +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 7a9bf2af2671..4148035c899a 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2346,22 +2346,9 @@ void SdXImpressDocument::setPartMode( int nPartMode ) + PageKind aPageKind( PK_STANDARD ); + switch ( nPartMode ) + { +- case LOK_PARTMODE_EMBEDDEDOBJ: +- // This will probably be handled higher up, i.e. +- // we probably shouldn't be handling this here. +- // (However we don't offer embedded object-only +- // rendering anywhere yet, so this may be a +- // completely incorrect comment.) +- assert( false ); +- // And let's fall through in a normal build. +- case LOK_PARTMODE_DEFAULT: +- case LOK_PARTMODE_SLIDE: +- break; +- case LOK_PARTMODE_SLIDENOTES: +- aPageKind = PK_NOTES; ++ case LOK_PARTMODE_SLIDES: + break; + case LOK_PARTMODE_NOTES: +- // TODO: this shows combined slides + notes + aPageKind = PK_NOTES; + break; + } +-- +2.12.0 + diff --git a/SOURCES/0002-Related-tdf-93676-msword-wraps-slightly-differently-.patch b/SOURCES/0002-Related-tdf-93676-msword-wraps-slightly-differently-.patch new file mode 100644 index 0000000..90ddc6b --- /dev/null +++ b/SOURCES/0002-Related-tdf-93676-msword-wraps-slightly-differently-.patch @@ -0,0 +1,61 @@ +From d9aed0bc2e741fa02a6ffdf90193aae7ce471e52 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 8 Sep 2015 09:45:12 +0100 +Subject: [PATCH] Related: tdf#93676 msword wraps slightly differently than us + +Change-Id: I688d4d193709d9c9829065c87f0d656a94fd9f16 +--- + sw/source/filter/ww8/docxsdrexport.cxx | 16 +++++++++++++++- + sw/source/filter/ww8/wrtw8esh.cxx | 2 +- + 2 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx +index 02b134a..71a357e 100644 +--- a/sw/source/filter/ww8/docxsdrexport.cxx ++++ b/sw/source/filter/ww8/docxsdrexport.cxx +@@ -516,6 +516,21 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons + } + m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionH); + m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_positionV, XML_relativeFrom, relativeFromV, FSEND); ++ ++ sal_Int64 nTwipstoEMU = TwipsToEMU(aPos.Y); ++ ++ // tdf#93675, 0 below line/paragraph and/or top line/paragraph with ++ // wrap top+bottom or other wraps is affecting the line directly ++ // above the anchor line, which seems odd, but a tiny adjustment ++ // here to bring the top down convinces msoffice to wrap like us ++ if (nTwipstoEMU == 0 && ++ (strcmp(relativeFromV, "line") == 0 || strcmp(relativeFromV, "paragraph") == 0) && ++ (!alignV || strcmp(alignV, "top") == 0)) ++ { ++ alignV = NULL; ++ nTwipstoEMU = 635; ++ } ++ + if (alignV != NULL) + { + m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_align, FSEND); +@@ -525,7 +540,6 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons + else + { + m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND); +- sal_Int64 nTwipstoEMU = TwipsToEMU(aPos.Y); + if (nTwipstoEMU > MAX_INTEGER_VALUE) + { + nTwipstoEMU = MAX_INTEGER_VALUE; +diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx +index fd6dfbc..2b7cebe 100644 +--- a/sw/source/filter/ww8/wrtw8esh.cxx ++++ b/sw/source/filter/ww8/wrtw8esh.cxx +@@ -810,7 +810,7 @@ void PlcDrawObj::WritePlc( WW8Export& rWrt ) const + // wrap top+bottom or other wraps is affecting the line directly + // above the anchor line, which seems odd, but a tiny adjustment + // here to bring the top down convinces msoffice to wrap like us +- if (nTop < 8 && !rFrameFormat.IsInline() && ++ if (nTop == 0 && !rFrameFormat.IsInline() && + rVOr.GetVertOrient() == text::VertOrientation::NONE && + rVOr.GetRelationOrient() == text::RelOrientation::FRAME) + { +-- +2.1.0 + diff --git a/SOURCES/0002-disable-tearability-of-color-window.patch b/SOURCES/0002-disable-tearability-of-color-window.patch new file mode 100644 index 0000000..8dc0268 --- /dev/null +++ b/SOURCES/0002-disable-tearability-of-color-window.patch @@ -0,0 +1,46 @@ +From 011f42c0c6104228f5c15daae58e432ccf2be69d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 17 Dec 2015 17:04:52 +0000 +Subject: [PATCH 2/2] disable tearability of color window + +the new popup controllers take care to destroy the popup +and recreate a non-popup and move the contents into it + +so we should re-implement the color popup as one of those +in the meantime, turn it into a non-tearable thing + +Change-Id: I6ba26bf19badcbf910b7200b7e1b8b2a64ce4eec +--- + svx/source/tbxctrls/tbcontrl.cxx | 3 +-- + svx/uiconfig/ui/colorwindow.ui | 1 - + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/svx/source/tbxctrls/tbcontrl.cxx b/svx/source/tbxctrls/tbcontrl.cxx +index ae696ae..28691dc 100644 +--- a/svx/source/tbxctrls/tbcontrl.cxx ++++ b/svx/source/tbxctrls/tbcontrl.cxx +@@ -2659,8 +2659,7 @@ VclPtr SvxColorToolBoxControl::CreatePopupWindow() + break; + } + +- pColorWin->StartPopupMode( &GetToolBox(), +- FloatWinPopupFlags::AllowTearOff|FloatWinPopupFlags::NoAppFocusClose ); ++ pColorWin->StartPopupMode( &GetToolBox(), FloatWinPopupFlags::NoAppFocusClose ); + pColorWin->StartSelection(); + SetPopupWindow( pColorWin ); + if ( !bSidebarType ) +diff --git a/svx/uiconfig/ui/colorwindow.ui b/svx/uiconfig/ui/colorwindow.ui +index 9482562..702bee3 100644 +--- a/svx/uiconfig/ui/colorwindow.ui ++++ b/svx/uiconfig/ui/colorwindow.ui +@@ -25,7 +25,6 @@ + True + popup-menu + True +- False + False + + +-- +2.5.0 + diff --git a/SOURCES/0002-remove-newly-unused-WB_NEEDSFOCUS-and-fragile-FLOAT_.patch b/SOURCES/0002-remove-newly-unused-WB_NEEDSFOCUS-and-fragile-FLOAT_.patch new file mode 100644 index 0000000..3341e46 --- /dev/null +++ b/SOURCES/0002-remove-newly-unused-WB_NEEDSFOCUS-and-fragile-FLOAT_.patch @@ -0,0 +1,178 @@ +From b9431532ba696a39e7d35597f4083ea356b63eb3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 16 Dec 2015 21:30:22 +0000 +Subject: [PATCH] remove newly unused WB_NEEDSFOCUS and fragile FLOAT_FOCUSABLE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change-Id: Idce03318fbc01039a6c0638879785607970993c0 +Reviewed-on: https://gerrit.libreoffice.org/20746 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +--- + include/tools/wintypes.hxx | 1 - + vcl/inc/salframe.hxx | 2 - + vcl/inc/unx/gtk/gtkframe.hxx | 3 +- + vcl/osx/salframeview.mm | 1807 ----------------------------------------- + vcl/source/window/brdwin.cxx | 2 +- + vcl/source/window/window.cxx | 4 +- + vcl/unx/gtk/gtksalframe.cxx | 11 +- + vcl/unx/gtk3/gtk3gtkframe.cxx | 9 +- + 8 files changed, 8 insertions(+), 1831 deletions(-) + delete mode 100644 vcl/osx/salframeview.mm + +diff --git a/include/tools/wintypes.hxx b/include/tools/wintypes.hxx +index 897e635..3943cc4 100644 +--- a/include/tools/wintypes.hxx ++++ b/include/tools/wintypes.hxx +@@ -180,7 +180,6 @@ WinBits const WB_NOSHADOW = SAL_CONST_INT64(0x400000000); + WinBits const WB_TOOLTIPWIN = SAL_CONST_INT64(0x800000000); + WinBits const WB_OWNERDRAWDECORATION = SAL_CONST_INT64(0x2000000000); + WinBits const WB_DEFAULTWIN = SAL_CONST_INT64(0x4000000000); +-WinBits const WB_NEEDSFOCUS = SAL_CONST_INT64(0x1000000000); + WinBits const WB_POPUP = SAL_CONST_INT64(0x20000000); + + WinBits const WB_HSCROLL = WB_HORZ; +diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx +index 9b3d52e..1016d3c 100644 +--- a/vcl/inc/salframe.hxx ++++ b/vcl/inc/salframe.hxx +@@ -76,8 +76,6 @@ struct SystemEnvData; + #define SAL_FRAME_STYLE_SYSTEMCHILD ((sal_uLong)0x08000000) + // floating window + #define SAL_FRAME_STYLE_FLOAT ((sal_uLong)0x20000000) +-// floating window that needs to be focusable +-#define SAL_FRAME_STYLE_FLOAT_FOCUSABLE ((sal_uLong)0x04000000) + // toolwindows should be painted with a smaller decoration + #define SAL_FRAME_STYLE_TOOLWINDOW ((sal_uLong)0x40000000) + // the window containing the intro bitmap, aka splashscreen +diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx +index a55ff2c..479a41b 100644 +--- a/vcl/inc/unx/gtk/gtkframe.hxx ++++ b/vcl/inc/unx/gtk/gtkframe.hxx +@@ -292,8 +292,7 @@ class GtkSalFrame : public SalFrame, public X11WindowProvider + return + (m_nStyle & SAL_FRAME_STYLE_FLOAT) && // only a float can be floatgrab + !(m_nStyle & SAL_FRAME_STYLE_TOOLTIP) && // tool tips are not +- !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) && // toolbars are also not +- !(m_nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE); // focusable floats are not ++ !(m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION); // toolbars are also not + } + + bool isChild( bool bPlug = true, bool bSysChild = true ) +diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx +index f57ab37..0e354bd 100644 +--- a/vcl/source/window/brdwin.cxx ++++ b/vcl/source/window/brdwin.cxx +@@ -1750,7 +1750,7 @@ void ImplBorderWindow::ImplInit( vcl::Window* pParent, + { + // remove all unwanted WindowBits + WinBits nOrgStyle = nStyle; +- WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_PINABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW | WB_NEEDSFOCUS | WB_POPUP); ++ WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_PINABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW | WB_POPUP); + if ( nTypeStyle & BORDERWINDOW_STYLE_APP ) + nTestStyle |= WB_APP; + nStyle &= nTestStyle; +diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx +index 808d683..87b8e93 100644 +--- a/vcl/source/window/window.cxx ++++ b/vcl/source/window/window.cxx +@@ -911,7 +911,7 @@ void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* p + nBorderTypeStyle |= BORDERWINDOW_STYLE_FRAME; + nStyle |= WB_BORDER; + } +- VclPtrInstance pBorderWin( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_NEEDSFOCUS), nBorderTypeStyle ); ++ VclPtrInstance pBorderWin( pParent, nStyle & (WB_BORDER | WB_DIALOGCONTROL | WB_NODIALOGCONTROL), nBorderTypeStyle ); + ((vcl::Window*)pBorderWin)->mpWindowImpl->mpClientWindow = this; + pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder ); + mpWindowImpl->mpBorderWindow = pBorderWin; +@@ -966,8 +966,6 @@ void Window::ImplInit( vcl::Window* pParent, WinBits nStyle, SystemParentData* p + nFrameStyle = SAL_FRAME_STYLE_FLOAT; + if( nStyle & WB_OWNERDRAWDECORATION ) + nFrameStyle |= (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_NOSHADOW); +- if( nStyle & WB_NEEDSFOCUS ) +- nFrameStyle |= SAL_FRAME_STYLE_FLOAT_FOCUSABLE; + } + else if( mpWindowImpl->mbFloatWin ) + nFrameStyle |= SAL_FRAME_STYLE_TOOLWINDOW; +diff --git a/vcl/unx/gtk/gtksalframe.cxx b/vcl/unx/gtk/gtksalframe.cxx +index 03f25dd..bd9662c 100644 +--- a/vcl/unx/gtk/gtksalframe.cxx ++++ b/vcl/unx/gtk/gtksalframe.cxx +@@ -1373,8 +1373,7 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + m_nStyle = nStyle; + + GtkWindowType eWinType = ( (nStyle & SAL_FRAME_STYLE_FLOAT) && +- ! (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION| +- SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ++ ! (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) + ) + ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL; + +@@ -1419,7 +1418,7 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + bool bDecoHandling = + ! isChild() && + ( ! (nStyle & SAL_FRAME_STYLE_FLOAT) || +- (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ); ++ (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) ); + + if( bDecoHandling ) + { +@@ -1441,10 +1440,6 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; + lcl_set_accept_focus( GTK_WINDOW(m_pWindow), false, true ); + } +- else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) +- { +- eType = GDK_WINDOW_TYPE_HINT_UTILITY; +- } + #if !GTK_CHECK_VERSION(3,0,0) + if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) + && getDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() ) +@@ -2770,7 +2765,7 @@ void GtkSalFrame::ToTop( sal_uInt16 nFlags ) + * to our window - which it of course won't since our input hint + * is set to false. + */ +- if( (m_nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ) ++ if (m_nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) + { + // sad but true: this can cause an XError, we need to catch that + // to do this we need to synchronize with the XServer +diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx +index d41be9d..4ac3da7 100644 +--- a/vcl/unx/gtk3/gtk3gtkframe.cxx ++++ b/vcl/unx/gtk3/gtk3gtkframe.cxx +@@ -1121,8 +1121,7 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + m_nStyle = nStyle; + + GtkWindowType eWinType = ( (nStyle & SAL_FRAME_STYLE_FLOAT) && +- ! (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION| +- SAL_FRAME_STYLE_FLOAT_FOCUSABLE)) ++ ! (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) + ) + ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL; + +@@ -1167,7 +1166,7 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + bool bDecoHandling = + ! isChild() && + ( ! (nStyle & SAL_FRAME_STYLE_FLOAT) || +- (nStyle & (SAL_FRAME_STYLE_OWNERDRAWDECORATION|SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) ); ++ (nStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION ) ); + + if( bDecoHandling ) + { +@@ -1190,10 +1189,6 @@ void GtkSalFrame::Init( SalFrame* pParent, sal_uLong nStyle ) + gtk_window_set_accept_focus(GTK_WINDOW(m_pWindow), false); + gtk_window_set_decorated(GTK_WINDOW(m_pWindow), false); + } +- else if( (nStyle & SAL_FRAME_STYLE_FLOAT_FOCUSABLE) ) +- { +- eType = GDK_WINDOW_TYPE_HINT_UTILITY; +- } + gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType ); + gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC ); + } +-- +2.5.0 + diff --git a/SOURCES/0002-sysui-introspection-wants-INSTDIR-not-DESTDIR-INSTAL.patch b/SOURCES/0002-sysui-introspection-wants-INSTDIR-not-DESTDIR-INSTAL.patch new file mode 100644 index 0000000..7237d2f --- /dev/null +++ b/SOURCES/0002-sysui-introspection-wants-INSTDIR-not-DESTDIR-INSTAL.patch @@ -0,0 +1,50 @@ +From 132994c95901d1b5876c6eb468aae294ff00655b Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 18 Sep 2015 09:10:30 +0200 +Subject: [PATCH 2/2] sysui: introspection wants ${INSTDIR}, not + ${DESTDIR}/${INSTALLDIR} + +The later can be empty for the generic rpm case. + +Change-Id: I69c62dcd2a16004c7927c9cf67837463e6411a8d +Reviewed-on: https://gerrit.libreoffice.org/18675 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit c722e9e728ec6c9df0285f5dd2041aa58f66f686) +--- + configure.ac | 5 ++++- + sysui/desktop/share/create_tree.sh | 2 +- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index f3fe04da124b..c5183b7cc448 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -9917,7 +9917,10 @@ if test "x$enable_gtk3" = "xyes"; then + PKG_CHECK_MODULES(GTK3, gtk+-3.0 >= 3.8 gtk+-unix-print-3.0 gmodule-no-export-2.0 glib-2.0 >= 2.38 cairo, ENABLE_GTK3="TRUE", ENABLE_GTK3="") + if test "x$ENABLE_GTK3" = "xTRUE"; then + R="gtk3" +- GOBJECT_INTROSPECTION_CHECK(INTROSPECTION_REQUIRED_VERSION) ++ dnl Avoid installed by unpackaged files for now. ++ if test -z "$PKGFORMAT"; then ++ GOBJECT_INTROSPECTION_CHECK(INTROSPECTION_REQUIRED_VERSION) ++ fi + else + AC_MSG_ERROR([gtk3 or dependent libraries of the correct versions, not found]) + fi +diff --git a/sysui/desktop/share/create_tree.sh b/sysui/desktop/share/create_tree.sh +index c73b89af3ab5..86d2837fed0f 100755 +--- a/sysui/desktop/share/create_tree.sh ++++ b/sysui/desktop/share/create_tree.sh +@@ -93,7 +93,7 @@ if [ -n "$INTROSPECTION_SCANNER" ]; then + g-ir-scanner "${SRCDIR}/include/LibreOfficeKit/LibreOfficeKitGtk.h" "${SRCDIR}/libreofficekit/source/gtk/lokdocview.cxx" \ + `${PKG_CONFIG} --cflags gobject-introspection-1.0 gtk+-3.0` -I"${SRCDIR}/include/" \ + --include=GLib-2.0 --include=GObject-2.0 --include=Gio-2.0 \ +- --library=libreofficekitgtk --library-path="${DESTDIR}/${INSTALLDIR}/program" \ ++ --library=libreofficekitgtk --library-path="${INSTDIR}/program" \ + --include=Gdk-3.0 --include=GdkPixbuf-2.0 --include=Gtk-3.0 \ + --namespace=LOKDocView --nsversion=0.1 --identifier-prefix=LOKDoc --symbol-prefix=lok_doc \ + --output="${DESTDIR}/${PREFIXDIR}/share/gir-1.0/LOKDocView-0.1.gir" --warn-all --no-libtool +-- +2.12.0 + diff --git a/SOURCES/0002-vcl-add-isInitVCL-to-not-initialize-twice.patch b/SOURCES/0002-vcl-add-isInitVCL-to-not-initialize-twice.patch new file mode 100644 index 0000000..52c453c --- /dev/null +++ b/SOURCES/0002-vcl-add-isInitVCL-to-not-initialize-twice.patch @@ -0,0 +1,57 @@ +From ae536d948c00a5561f7d08f2f7459516d8bf9807 Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Mon, 7 Sep 2015 17:33:09 -0400 +Subject: [PATCH 2/6] vcl: add isInitVCL, to not initialize twice + +In the preinit stage, the VCL is initialized in the parent process +and when the lo_startmain thread is started, the thread initialize +VCL again. + +It is not necessary to initialize twice. + +Change-Id: I819cf0125afe7760c3f4d91c420d36a3a383902c +(cherry picked from commit bc8dfe47596f28ff43ec01af4487a2abe349caee) +--- + vcl/source/app/svmain.cxx | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx +index 3202019..f6d4e25 100644 +--- a/vcl/source/app/svmain.cxx ++++ b/vcl/source/app/svmain.cxx +@@ -91,6 +91,8 @@ + + using namespace ::com::sun::star; + ++static bool isInitVCL(); ++ + oslSignalAction SAL_CALL VCLExceptionSignal_impl( void* /*pData*/, oslSignalInfo* pInfo) + { + static bool bIn = false; +@@ -160,7 +162,7 @@ int ImplSVMain() + + int nReturn = EXIT_FAILURE; + +- bool bInit = InitVCL(); ++ bool bInit = (!isInitVCL() ? InitVCL() : true); + + if( bInit ) + { +@@ -243,6 +245,14 @@ uno::Any SAL_CALL DesktopEnvironmentContext::getValueByName( const OUString& Nam + return retVal; + } + ++static bool isInitVCL() ++{ ++ ImplSVData* pSVData = ImplGetSVData(); ++ return pExceptionHandler != NULL && ++ pSVData->mpApp != NULL && ++ pSVData->mpDefInst != NULL; ++} ++ + bool InitVCL() + { + if( pExceptionHandler != NULL ) +-- +2.9.3 + diff --git a/SOURCES/0003-Look-for-libsofficeapp.dylib-in-the-right-place-on-O.patch b/SOURCES/0003-Look-for-libsofficeapp.dylib-in-the-right-place-on-O.patch new file mode 100644 index 0000000..1f890d1 --- /dev/null +++ b/SOURCES/0003-Look-for-libsofficeapp.dylib-in-the-right-place-on-O.patch @@ -0,0 +1,28 @@ +From 9eb31913cc9f35fb792bf8c8051f44ba11e16a5c Mon Sep 17 00:00:00 2001 +From: Tor Lillqvist +Date: Sat, 23 May 2015 10:09:18 +0100 +Subject: [PATCH 003/398] Look for libsofficeapp.dylib in the right place on OS + X + +Change-Id: Icef6b70081b15d4b8d99eb4ba7103f059e8d00e4 +(cherry picked from commit a1aa2cdaa7c467376c1f7824e2b6a83cb252a39a) +--- + desktop/source/lib/init.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index b2076c622bf1..88cbcbd8d285 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -899,6 +899,8 @@ static bool initialize_uno(const OUString& aAppProgramURL) + #ifdef IOS + // For iOS we already hardocde the inifile as "rc" in the .app directory. + (void) aAppProgramURL; ++#elif defined MACOSX ++ rtl::Bootstrap::setIniFilename(aAppProgramURL + "/../Resources/" SAL_CONFIGFILE("soffice")); + #else + rtl::Bootstrap::setIniFilename(aAppProgramURL + "/" SAL_CONFIGFILE("soffice")); + #endif +-- +2.12.0 + diff --git a/SOURCES/0003-Resolves-rhbz-1240591-gtk3-store-clipboard-when-Libr.patch b/SOURCES/0003-Resolves-rhbz-1240591-gtk3-store-clipboard-when-Libr.patch new file mode 100644 index 0000000..9bedd4c --- /dev/null +++ b/SOURCES/0003-Resolves-rhbz-1240591-gtk3-store-clipboard-when-Libr.patch @@ -0,0 +1,100 @@ +From 3f20d5f3b46160c2a5e425bfd50b2e0319cda021 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Thu, 21 Jan 2016 11:28:50 +0000 +Subject: [PATCH] Resolves: rhbz#1240591 gtk3: store clipboard when LibreOffice + is closed + +now contents copied to clipboard persist after LibreOffice exits + +Change-Id: I4433543944fb9664f87ade43da1198dcdd4e2a7c +(cherry picked from commit f1358edf469e70df1fb044bb58cd888fea15173c) +--- + vcl/unx/gtk3/gtk3gtkinst.cxx | 25 ++++++++++++++++++++++--- + 1 file changed, 22 insertions(+), 3 deletions(-) + +diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx +index f727462..8654b45 100644 +--- a/vcl/unx/gtk3/gtk3gtkinst.cxx ++++ b/vcl/unx/gtk3/gtk3gtkinst.cxx +@@ -13,12 +13,12 @@ + #include "com/sun/star/lang/XServiceInfo.hpp" + #include "com/sun/star/lang/XSingleServiceFactory.hpp" + #include "com/sun/star/lang/XInitialization.hpp" +-#include "com/sun/star/lang/DisposedException.hpp" + #include "com/sun/star/datatransfer/XTransferable.hpp" + #include "com/sun/star/datatransfer/clipboard/XClipboard.hpp" + #include "com/sun/star/datatransfer/clipboard/XClipboardEx.hpp" + #include "com/sun/star/datatransfer/clipboard/XClipboardNotifier.hpp" + #include "com/sun/star/datatransfer/clipboard/XClipboardListener.hpp" ++#include "com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp" + #include "com/sun/star/datatransfer/clipboard/XSystemClipboard.hpp" + #include "com/sun/star/datatransfer/dnd/XDragSource.hpp" + #include "com/sun/star/datatransfer/dnd/XDropTarget.hpp" +@@ -275,6 +275,7 @@ static void clipboard_owner_init(ClipboardOwner *) + class VclGtkClipboard : + public cppu::WeakComponentImplHelper< + datatransfer::clipboard::XSystemClipboard, ++ datatransfer::clipboard::XFlushableClipboard, + XServiceInfo> + { + GdkAtom m_nSelection; +@@ -326,6 +327,12 @@ public: + throw(RuntimeException, std::exception) SAL_OVERRIDE; + + /* ++ * XFlushableClipboard ++ */ ++ virtual void SAL_CALL flushClipboard() ++ throw(RuntimeException, std::exception) override; ++ ++ /* + * XClipboardNotifier + */ + virtual void SAL_CALL addClipboardListener( +@@ -503,7 +510,8 @@ namespace + } + + VclGtkClipboard::VclGtkClipboard(GdkAtom nSelection) +- : cppu::WeakComponentImplHelper ++ : cppu::WeakComponentImplHelper + (m_aMutex) + , m_nSelection(nSelection) + { +@@ -514,6 +522,16 @@ VclGtkClipboard::VclGtkClipboard(GdkAtom nSelection) + m_pOwner->m_pThis = this; + } + ++void VclGtkClipboard::flushClipboard() ++ throw (RuntimeException, std::exception) ++{ ++ if (GDK_SELECTION_CLIPBOARD != m_nSelection) ++ return; ++ ++ GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); ++ gtk_clipboard_store(clipboard); ++} ++ + VclGtkClipboard::~VclGtkClipboard() + { + GtkClipboard* clipboard = gtk_clipboard_get(m_nSelection); +@@ -525,7 +543,7 @@ VclGtkClipboard::~VclGtkClipboard() + void VclGtkClipboard::setContents( + const Reference< css::datatransfer::XTransferable >& xTrans, + const Reference< css::datatransfer::clipboard::XClipboardOwner >& xClipboardOwner ) +- throw( RuntimeException, std::exception ) ++ throw(RuntimeException, std::exception) + { + osl::ClearableMutexGuard aGuard( m_aMutex ); + Reference< datatransfer::clipboard::XClipboardOwner > xOldOwner( m_aOwner ); +@@ -585,6 +603,7 @@ void VclGtkClipboard::setContents( + //if we have gained or lost ownership of the clipboard + gtk_clipboard_set_with_owner(clipboard, aGtkTargets.data(), aGtkTargets.size(), + ClipboardGetFunc, ClipboardClearFunc, G_OBJECT(m_pOwner)); ++ gtk_clipboard_set_can_store(clipboard, aGtkTargets.data(), aGtkTargets.size()); + } + m_aGtkTargets = aGtkTargets; + } +-- +2.5.0 + diff --git a/SOURCES/0003-gnome-documents-rework-SfxPickList-as-pimpl.patch b/SOURCES/0003-gnome-documents-rework-SfxPickList-as-pimpl.patch new file mode 100644 index 0000000..d1b363e --- /dev/null +++ b/SOURCES/0003-gnome-documents-rework-SfxPickList-as-pimpl.patch @@ -0,0 +1,284 @@ +From f0efe28ec775c3205d3591750cd5159119128d20 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 8 May 2017 15:27:49 +0100 +Subject: [PATCH 3/6] gnome-documents: rework SfxPickList as pimpl +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +and call impl dtor with SolarMutex held + +Reviewed-on: https://gerrit.libreoffice.org/37395 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 53082fcd1b1cccf7ef0c3cb1bef8e747c4e88a61) + +Change-Id: I06931ca9ab4384a5e3c255847cf3533ed03b77dc +--- + sfx2/source/appl/sfxpicklist.cxx | 101 ++++++++++++++++++++++++++++++--------- + sfx2/source/inc/sfxpicklist.hxx | 53 +++++--------------- + sfx2/source/menu/virtmenu.cxx | 2 +- + 3 files changed, 92 insertions(+), 64 deletions(-) + +diff --git a/sfx2/source/appl/sfxpicklist.cxx b/sfx2/source/appl/sfxpicklist.cxx +index 24754ca..478c537 100644 +--- a/sfx2/source/appl/sfxpicklist.cxx ++++ b/sfx2/source/appl/sfxpicklist.cxx +@@ -78,7 +78,54 @@ class StringLength : public ::cppu::WeakImplHelper1< XStringWidth > + } + }; + +-void SfxPickList::CreatePicklistMenuTitle( Menu* pMenu, sal_uInt16 nItemId, const OUString& aURLString, sal_uInt32 nNo ) ++namespace ++{ ++ class thePickListMutex ++ : public rtl::Static {}; ++} ++ ++class SfxPickListImpl : public SfxListener ++{ ++ struct PickListEntry ++ { ++ PickListEntry( const OUString& _aName, const OUString& _aFilter, const OUString& _aTitle ) : ++ aName( _aName ), aFilter( _aFilter ), aTitle( _aTitle ) {} ++ ++ OUString aName; ++ OUString aFilter; ++ OUString aTitle; ++ OUString aOptions; ++ }; ++ ++ std::vector< PickListEntry* > m_aPicklistVector; ++ sal_uInt32 m_nAllowedMenuSize; ++ css::uno::Reference< css::util::XStringWidth > m_xStringLength; ++ ++ void CreatePicklistMenuTitle( Menu* pMenu, sal_uInt16 nItemId, const OUString& aURL, sal_uInt32 nNo ); ++ PickListEntry* GetPickListEntry( sal_uInt32 nIndex ); ++ void CreatePickListEntries(); ++ void RemovePickListEntries(); ++ /** ++ * Adds the given document to the pick list (recent documents) if it satisfies ++ certain requirements, e.g. being writable. Check implementation for requirement ++ details. ++ */ ++ static void AddDocumentToPickList( SfxObjectShell* pDocShell ); ++ ++public: ++ void CreateMenuEntries( Menu* pMenu ); ++ void ExecuteMenuEntry( sal_uInt16 nId ); ++ void ExecuteEntry( sal_uInt32 nIndex ); ++ ++ SfxPickListImpl(sal_uInt32 nMenuSize); ++ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; ++ ~SfxPickListImpl() ++ { ++ RemovePickListEntries(); ++ } ++}; ++ ++void SfxPickListImpl::CreatePicklistMenuTitle( Menu* pMenu, sal_uInt16 nItemId, const OUString& aURLString, sal_uInt32 nNo ) + { + OUStringBuffer aPickEntry; + +@@ -136,13 +183,7 @@ void SfxPickList::CreatePicklistMenuTitle( Menu* pMenu, sal_uInt16 nItemId, cons + pMenu->SetAccessibleName( nItemId, aAccessibleName ); + } + +-namespace +-{ +- class thePickListMutex +- : public rtl::Static {}; +-} +- +-void SfxPickList::RemovePickListEntries() ++void SfxPickListImpl::RemovePickListEntries() + { + ::osl::MutexGuard aGuard( thePickListMutex::get() ); + for ( sal_uInt32 i = 0; i < m_aPicklistVector.size(); i++ ) +@@ -150,7 +191,7 @@ void SfxPickList::RemovePickListEntries() + m_aPicklistVector.clear(); + } + +-SfxPickList::PickListEntry* SfxPickList::GetPickListEntry( sal_uInt32 nIndex ) ++SfxPickListImpl::PickListEntry* SfxPickListImpl::GetPickListEntry( sal_uInt32 nIndex ) + { + OSL_ASSERT( m_aPicklistVector.size() > nIndex ); + +@@ -160,7 +201,7 @@ SfxPickList::PickListEntry* SfxPickList::GetPickListEntry( sal_uInt32 nIndex ) + return 0; + } + +-void SfxPickList::AddDocumentToPickList( SfxObjectShell* pDocSh ) ++void SfxPickListImpl::AddDocumentToPickList( SfxObjectShell* pDocSh ) + { + if (comphelper::LibreOfficeKit::isActive()) + return; +@@ -242,13 +283,34 @@ void SfxPickList::AddDocumentToPickList( SfxObjectShell* pDocSh ) + (pFilter) ? pFilter->GetServiceName() : OUString() ); + } + ++SfxPickList::SfxPickList(sal_uInt32 nAllowedMenuSize) ++ : mxImpl(new SfxPickListImpl(nAllowedMenuSize)) ++{ ++} ++ ++SfxPickList::~SfxPickList() ++{ ++ std::unique_ptr xGuard(comphelper::SolarMutex::get() ? new SolarMutexGuard : nullptr); ++ mxImpl.reset(); ++} ++ + SfxPickList& SfxPickList::Get() + { + static SfxPickList aUniqueInstance(SvtHistoryOptions().GetSize(ePICKLIST)); + return aUniqueInstance; + } + +-SfxPickList::SfxPickList( sal_uInt32 nAllowedMenuSize ) : ++void SfxPickList::CreateMenuEntries(Menu* pMenu) ++{ ++ mxImpl->CreateMenuEntries(pMenu); ++} ++ ++void SfxPickList::ExecuteMenuEntry(sal_uInt16 nId) ++{ ++ mxImpl->ExecuteMenuEntry(nId); ++} ++ ++SfxPickListImpl::SfxPickListImpl( sal_uInt32 nAllowedMenuSize ) : + m_nAllowedMenuSize( nAllowedMenuSize ) + { + m_xStringLength = new StringLength; +@@ -256,12 +318,7 @@ SfxPickList::SfxPickList( sal_uInt32 nAllowedMenuSize ) : + StartListening( *SfxGetpApp() ); + } + +-SfxPickList::~SfxPickList() +-{ +- RemovePickListEntries(); +-} +- +-void SfxPickList::CreatePickListEntries() ++void SfxPickListImpl::CreatePickListEntries() + { + RemovePickListEntries(); + +@@ -305,7 +362,7 @@ void SfxPickList::CreatePickListEntries() + } + } + +-void SfxPickList::CreateMenuEntries( Menu* pMenu ) ++void SfxPickListImpl::CreateMenuEntries( Menu* pMenu ) + { + ::osl::MutexGuard aGuard( thePickListMutex::get() ); + +@@ -340,11 +397,11 @@ void SfxPickList::CreateMenuEntries( Menu* pMenu ) + bPickListMenuInitializing = false; + } + +-void SfxPickList::ExecuteEntry( sal_uInt32 nIndex ) ++void SfxPickListImpl::ExecuteEntry( sal_uInt32 nIndex ) + { + ::osl::ClearableMutexGuard aGuard( thePickListMutex::get() ); + +- PickListEntry *pPick = SfxPickList::Get().GetPickListEntry( nIndex ); ++ PickListEntry *pPick = GetPickListEntry(nIndex); + + if ( pPick ) + { +@@ -369,12 +426,12 @@ void SfxPickList::ExecuteEntry( sal_uInt32 nIndex ) + } + } + +-void SfxPickList::ExecuteMenuEntry( sal_uInt16 nId ) ++void SfxPickListImpl::ExecuteMenuEntry( sal_uInt16 nId ) + { + ExecuteEntry( (sal_uInt32)( nId - START_ITEMID_PICKLIST ) ); + } + +-void SfxPickList::Notify( SfxBroadcaster&, const SfxHint& rHint ) ++void SfxPickListImpl::Notify( SfxBroadcaster&, const SfxHint& rHint ) + { + const SfxStringHint* pStringHint = dynamic_cast(&rHint); + if ( pStringHint ) +diff --git a/sfx2/source/inc/sfxpicklist.hxx b/sfx2/source/inc/sfxpicklist.hxx +index 502492c..56da5d4 100644 +--- a/sfx2/source/inc/sfxpicklist.hxx ++++ b/sfx2/source/inc/sfxpicklist.hxx +@@ -29,48 +29,19 @@ + + #define PICKLIST_MAXSIZE 100 + +-class SfxPickList : public SfxListener +-{ +- struct PickListEntry +- { +- PickListEntry( const OUString& _aName, const OUString& _aFilter, const OUString& _aTitle ) : +- aName( _aName ), aFilter( _aFilter ), aTitle( _aTitle ) {} +- +- OUString aName; +- OUString aFilter; +- OUString aTitle; +- OUString aOptions; +- }; +- +- std::vector< PickListEntry* > m_aPicklistVector; +- sal_uInt32 m_nAllowedMenuSize; +- ::com::sun::star::uno::Reference< ::com::sun::star::util::XStringWidth > m_xStringLength; +- +- SfxPickList( sal_uInt32 nMenuSize ); +- virtual ~SfxPickList(); ++class SfxPickListImpl; + +- void CreatePicklistMenuTitle( Menu* pMenu, sal_uInt16 nItemId, const OUString& aURL, sal_uInt32 nNo ); +- PickListEntry* GetPickListEntry( sal_uInt32 nIndex ); +- void CreatePickListEntries(); +- void RemovePickListEntries(); +- /** +- * Adds the given document to the pick list (recent documents) if it satisfies +- certain requirements, e.g. being writable. Check implementation for requirement +- details. +- */ +- static void AddDocumentToPickList( SfxObjectShell* pDocShell ); +- +- public: +- static SfxPickList& Get(); +- static void ensure() { Get(); } +- +- sal_uInt32 GetAllowedMenuSize() { return m_nAllowedMenuSize; } +- sal_uInt32 GetNumOfEntries() const { return m_aPicklistVector.size(); } +- void CreateMenuEntries( Menu* pMenu ); +- static void ExecuteMenuEntry( sal_uInt16 nId ); +- static void ExecuteEntry( sal_uInt32 nIndex ); +- +- virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) SAL_OVERRIDE; ++class SfxPickList ++{ ++private: ++ std::unique_ptr mxImpl; ++public: ++ SfxPickList(sal_uInt32 nAllowedMenuSize); ++ static SfxPickList& Get(); ++ void CreateMenuEntries(Menu* pMenu); ++ void ExecuteMenuEntry(sal_uInt16 nId); ++ static void ensure() { Get(); } ++ ~SfxPickList(); + }; + + #endif // INCLUDED_SFX2_SOURCE_INC_SFXPICKLIST_HXX +diff --git a/sfx2/source/menu/virtmenu.cxx b/sfx2/source/menu/virtmenu.cxx +index e14bb24..eab7bb7 100644 +--- a/sfx2/source/menu/virtmenu.cxx ++++ b/sfx2/source/menu/virtmenu.cxx +@@ -964,7 +964,7 @@ IMPL_LINK( SfxVirtualMenu, Select, Menu *, pMenu ) + } + else if ( nSlotId >= START_ITEMID_PICKLIST && nSlotId <= END_ITEMID_PICKLIST ) + { +- SfxPickList::ExecuteMenuEntry( nSlotId ); ++ SfxPickList::Get().ExecuteMenuEntry(nSlotId); + return sal_IntPtr(true); + } + +-- +2.9.3 + diff --git a/SOURCES/0003-gtk3-wayland-start-floating-windows-hidden.patch b/SOURCES/0003-gtk3-wayland-start-floating-windows-hidden.patch new file mode 100644 index 0000000..94af791 --- /dev/null +++ b/SOURCES/0003-gtk3-wayland-start-floating-windows-hidden.patch @@ -0,0 +1,56 @@ +From dab2582f05979cd99a5937cb95a387cfed70bb8d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 16 Dec 2015 14:18:11 +0000 +Subject: [PATCH 3/3] gtk3+wayland: start floating windows hidden + +once they are visible we can't move them under wayland, so +start then hidden, move them and then show + +these floating windows are very delicate. + +Change-Id: Ia233c23f25cec453df79ef70cab6210dbdd280a0 +--- + sfx2/uiconfig/ui/floatingrecord.ui | 1 - + svx/uiconfig/ui/colorwindow.ui | 1 - + svx/uiconfig/ui/floatingundoredo.ui | 1 - + 3 files changed, 3 deletions(-) + +diff --git a/sfx2/uiconfig/ui/floatingrecord.ui b/sfx2/uiconfig/ui/floatingrecord.ui +index 653867a..9136b38 100644 +--- a/sfx2/uiconfig/ui/floatingrecord.ui ++++ b/sfx2/uiconfig/ui/floatingrecord.ui +@@ -3,7 +3,6 @@ + + + +- True + False + True + 6 +diff --git a/svx/uiconfig/ui/colorwindow.ui b/svx/uiconfig/ui/colorwindow.ui +index 71cda63..9482562 100644 +--- a/svx/uiconfig/ui/colorwindow.ui ++++ b/svx/uiconfig/ui/colorwindow.ui +@@ -17,7 +17,6 @@ + 1 + + +- True + False + True + True +diff --git a/svx/uiconfig/ui/floatingundoredo.ui b/svx/uiconfig/ui/floatingundoredo.ui +index 10491f8..66f30a6 100644 +--- a/svx/uiconfig/ui/floatingundoredo.ui ++++ b/svx/uiconfig/ui/floatingundoredo.ui +@@ -3,7 +3,6 @@ + + + +- True + False + True + True +-- +2.5.0 + diff --git a/SOURCES/0004-Don-t-do-any-magic-LO-OS-X-application-stuff-in-a-LO.patch b/SOURCES/0004-Don-t-do-any-magic-LO-OS-X-application-stuff-in-a-LO.patch new file mode 100644 index 0000000..e694c41 --- /dev/null +++ b/SOURCES/0004-Don-t-do-any-magic-LO-OS-X-application-stuff-in-a-LO.patch @@ -0,0 +1,38 @@ +From afd423f49c86a0360510433302b545cfc97f3cbc Mon Sep 17 00:00:00 2001 +From: Tor Lillqvist +Date: Sat, 23 May 2015 10:56:30 +0100 +Subject: [PATCH 004/398] Don't do any magic LO OS X application stuff in a + LOKit client + +Change-Id: If6b6c3e48c7d0681958ff0e2afe0b0be5f6ee1ab +(cherry picked from commit 20c9ceb708e4720205a303bf2d41274b1311e36b) +--- + vcl/osx/salinst.cxx | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx +index 58a52d58accf..f57f8f4b45c5 100644 +--- a/vcl/osx/salinst.cxx ++++ b/vcl/osx/salinst.cxx +@@ -23,6 +23,8 @@ + + #include + ++#include "comphelper/lok.hxx" ++ + #include "osl/process.h" + + #include "rtl/ustrbuf.hxx" +@@ -182,6 +184,9 @@ static void initNSApp() + + bool ImplSVMainHook( int * pnInit ) + { ++ if (comphelper::LibreOfficeKit::isActive()) ++ return false; ++ + unlink([[NSString stringWithFormat:@"%@/Library/Saved Application State/%s.savedState/restorecount.plist", NSHomeDirectory(), MACOSX_BUNDLE_IDENTIFIER] UTF8String]); + unlink([[NSString stringWithFormat:@"%@/Library/Saved Application State/%s.savedState/restorecount.txt", NSHomeDirectory(), MACOSX_BUNDLE_IDENTIFIER] UTF8String]); + +-- +2.12.0 + diff --git a/SOURCES/0004-rhbz-1444437-gnome-documents-finalize-may-not-occur-.patch b/SOURCES/0004-rhbz-1444437-gnome-documents-finalize-may-not-occur-.patch new file mode 100644 index 0000000..853f098 --- /dev/null +++ b/SOURCES/0004-rhbz-1444437-gnome-documents-finalize-may-not-occur-.patch @@ -0,0 +1,68 @@ +From 4910cb9a1be7040142cedc0ccfb1bec2d74b3dca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 5 May 2017 14:34:51 +0100 +Subject: [PATCH 4/6] rhbz#1444437 gnome-documents finalize may not occur + immediately +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +when LOK Widget is destroyed, it may instead happen during GC of javascript, +like in the in gnome-documents case, but "destroy" will be called promptly. So +close documents and office in destroy, not finalize + +Reviewed-on: https://gerrit.libreoffice.org/37398 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit c45660df336a640f0f9d4290b881548d25c9db9d) + +Change-Id: I1dd7b828839894cb2d87f5c087194fe458ca22f0 +--- + libreofficekit/source/gtk/lokdocview.cxx | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 13ae6ea..7d1ec01 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2042,15 +2042,27 @@ static gboolean lok_doc_view_draw (GtkWidget* pWidget, cairo_t* pCairo) + return FALSE; + } + +-static void lok_doc_view_finalize (GObject* object) ++//rhbz#1444437 finalize may not occur immediately when this widget is destroyed ++//it may happen during GC of javascript, e.g. in gnome-documents but "destroy" ++//will be called promptly, so close documents in destroy, not finalize ++static void lok_doc_view_destroy (GtkWidget* widget) + { +- LOKDocView* pDocView = LOK_DOC_VIEW (object); ++ LOKDocView* pDocView = LOK_DOC_VIEW (widget); + LOKDocViewPrivate& priv = getPrivate(pDocView); + + if (priv->m_pDocument) + priv->m_pDocument->pClass->destroy (priv->m_pDocument); + if (priv->m_pOffice) + priv->m_pOffice->pClass->destroy (priv->m_pOffice); ++ ++ GTK_WIDGET_CLASS (lok_doc_view_parent_class)->destroy (widget); ++} ++ ++static void lok_doc_view_finalize (GObject* object) ++{ ++ LOKDocView* pDocView = LOK_DOC_VIEW (object); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ + delete priv.m_pImpl; + priv.m_pImpl = nullptr; + +@@ -2099,6 +2111,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + pWidgetClass->key_press_event = signalKey; + pWidgetClass->key_release_event = signalKey; + pWidgetClass->motion_notify_event = lok_doc_view_signal_motion; ++ pWidgetClass->destroy = lok_doc_view_destroy; + + /** + * LOKDocView:lopath: +-- +2.9.3 + diff --git a/SOURCES/0005-gnome-documents-hold-solarmutex-on-dtor-patch-as-wel.patch b/SOURCES/0005-gnome-documents-hold-solarmutex-on-dtor-patch-as-wel.patch new file mode 100644 index 0000000..adae3f4 --- /dev/null +++ b/SOURCES/0005-gnome-documents-hold-solarmutex-on-dtor-patch-as-wel.patch @@ -0,0 +1,38 @@ +From eb64ed49b102cf90bba65c23c81c852a32754671 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 8 May 2017 15:51:46 +0100 +Subject: [PATCH 5/6] gnome-documents: hold solarmutex on dtor patch as well +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Change-Id: I75fe71612116d435606c37185bf55b450425fc25 +Reviewed-on: https://gerrit.libreoffice.org/37396 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 899ffa4c4c66702e2a65f4065cbb7970d0e9c0e2) +--- + include/comphelper/unique_disposing_ptr.hxx | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/include/comphelper/unique_disposing_ptr.hxx b/include/comphelper/unique_disposing_ptr.hxx +index 1848639..7c0f600 100644 +--- a/include/comphelper/unique_disposing_ptr.hxx ++++ b/include/comphelper/unique_disposing_ptr.hxx +@@ -151,6 +151,12 @@ public: + SolarMutexGuard aGuard; + unique_disposing_ptr::reset(p); + } ++ ++ virtual ~unique_disposing_solar_mutex_reset_ptr() override ++ { ++ if (unique_disposing_ptr::get() && comphelper::SolarMutex::get()) ++ reset(); ++ } + }; + + } +-- +2.9.3 + diff --git a/SOURCES/0005-loplugin-staticmethods.patch b/SOURCES/0005-loplugin-staticmethods.patch new file mode 100644 index 0000000..e88835b --- /dev/null +++ b/SOURCES/0005-loplugin-staticmethods.patch @@ -0,0 +1,85 @@ +From 17e3b1763321f5f338e415bb0d0d86f5e7f7d2c6 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Wed, 27 May 2015 20:51:09 +0200 +Subject: [PATCH 005/398] loplugin:staticmethods + +Change-Id: Idb1072ecedd9ab0315d67e296da6d306c098b183 +(cherry picked from commit 5af7ca55a3d06ab23df715346c9b24d1333907be) +--- + libreofficekit/source/gtk/lokdocview.cxx | 39 +++++++++++++++++--------------- + 1 file changed, 21 insertions(+), 18 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 79cc649fa369..24f9d04a9024 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -38,6 +38,26 @@ + // We know that VirtualDevices use a DPI of 96. + static const int DPI = 96; + ++namespace { ++ ++/// Sets rWidth and rHeight from a "width, height" string. ++void payloadToSize(const char* pPayload, long& rWidth, long& rHeight) ++{ ++ rWidth = rHeight = 0; ++ gchar** ppCoordinates = g_strsplit(pPayload, ", ", 2); ++ gchar** ppCoordinate = ppCoordinates; ++ if (!*ppCoordinate) ++ return; ++ rWidth = atoi(*ppCoordinate); ++ ++ppCoordinate; ++ if (!*ppCoordinate) ++ return; ++ rHeight = atoi(*ppCoordinate); ++ g_strfreev(ppCoordinates); ++} ++ ++} ++ + /// Holds data used by LOKDocView only. + struct LOKDocView_Impl + { +@@ -170,8 +190,6 @@ struct LOKDocView_Impl + * the tiles that intersect with pPartial. + */ + void renderDocument(GdkRectangle* pPartial); +- /// Sets rWidth and rHeight from a "width, height" string. +- static void payloadToSize(const char* pPayload, long& rWidth, long& rHeight); + /// Returns the GdkRectangle of a width,height,x,y string. + static GdkRectangle payloadToRectangle(const char* pPayload); + /// Returns the GdkRectangles of a w,h,x,y;w2,h2,x2,y2;... string. +@@ -846,21 +864,6 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + } + } + +-void LOKDocView_Impl::payloadToSize(const char* pPayload, long& rWidth, long& rHeight) +-{ +- rWidth = rHeight = 0; +- gchar** ppCoordinates = g_strsplit(pPayload, ", ", 2); +- gchar** ppCoordinate = ppCoordinates; +- if (!*ppCoordinate) +- return; +- rWidth = atoi(*ppCoordinate); +- ++ppCoordinate; +- if (!*ppCoordinate) +- return; +- rHeight = atoi(*ppCoordinate); +- g_strfreev(ppCoordinates); +-} +- + GdkRectangle LOKDocView_Impl::payloadToRectangle(const char* pPayload) + { + GdkRectangle aRet; +@@ -1033,7 +1036,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + break; + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + { +- LOKDocView_Impl::payloadToSize(pCallback->m_aPayload.c_str(), m_nDocumentWidthTwips, m_nDocumentHeightTwips); ++ payloadToSize(pCallback->m_aPayload.c_str(), m_nDocumentWidthTwips, m_nDocumentHeightTwips); + } + break; + case LOK_CALLBACK_SET_PART: +-- +2.12.0 + diff --git a/SOURCES/0006-Resolves-rhbz-144437-make-gnome-documents-not-crash-.patch b/SOURCES/0006-Resolves-rhbz-144437-make-gnome-documents-not-crash-.patch new file mode 100644 index 0000000..2e6dc90 --- /dev/null +++ b/SOURCES/0006-Resolves-rhbz-144437-make-gnome-documents-not-crash-.patch @@ -0,0 +1,206 @@ +From baa91265d38ac44294b93f8ce47162454fbeb6d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 8 May 2017 15:26:22 +0100 +Subject: [PATCH] Resolves: rhbz#144437 make gnome-documents not crash the + whole time + +accept that once initted that LibreOffice cannot be deinitted and reinited +(without lots of work), but allow the main loop to quit and restart so LOKs +thread can run and exit successfully, new LOK connections will restart the main +loop. + +The buckets of global state continues to be valid the whole time this way + +Change-Id: Ide54c0df2ce4065f7c192ae8c2cedfaaa2b58d72 +--- + desktop/source/app/app.cxx | 2 +- + desktop/source/app/officeipcthread.cxx | 11 ++++++++--- + desktop/source/app/officeipcthread.hxx | 2 +- + desktop/source/lib/init.cxx | 6 ++++++ + framework/source/services/desktop.cxx | 10 ++++++++-- + libreofficekit/source/gtk/lokdocview.cxx | 6 ++++++ + vcl/source/app/svapp.cxx | 1 + + vcl/source/app/svmain.cxx | 8 ++++++++ + 8 files changed, 39 insertions(+), 7 deletions(-) + +diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx +index 5042752..372f605 100644 +--- a/desktop/source/app/app.cxx ++++ b/desktop/source/app/app.cxx +@@ -1890,7 +1890,7 @@ IMPL_LINK_NOARG(Desktop, OpenClients_Impl) + try { + OpenClients(); + +- OfficeIPCThread::SetReady(); ++ OfficeIPCThread::SetReady(true); + + CloseSplashScreen(); + CheckFirstRun( ); +diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx +index cb6ad0b..e65e935 100644 +--- a/desktop/source/app/officeipcthread.cxx ++++ b/desktop/source/app/officeipcthread.cxx +@@ -646,13 +646,15 @@ void OfficeIPCThread::DisableOfficeIPCThread(bool join) + // release mutex to avoid deadlocks + aMutex.clear(); + +- OfficeIPCThread::SetReady(pOfficeIPCThread); ++ OfficeIPCThread::SetReady(true, pOfficeIPCThread); + + // exit gracefully and join + if (join) + { + pOfficeIPCThread->join(); + } ++ ++ OfficeIPCThread::SetReady(false, pOfficeIPCThread); + } + } + +@@ -675,14 +677,17 @@ OfficeIPCThread::~OfficeIPCThread() + pGlobalOfficeIPCThread.clear(); + } + +-void OfficeIPCThread::SetReady( ++void OfficeIPCThread::SetReady(bool bIsReady, + rtl::Reference< OfficeIPCThread > const & pThread) + { + rtl::Reference< OfficeIPCThread > const & t( + pThread.is() ? pThread : pGlobalOfficeIPCThread); + if (t.is()) + { +- t->cReady.set(); ++ if (bIsReady) ++ t->cReady.set(); ++ else ++ t->cReady.reset(); + } + } + +diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx +index e81f57a..f23eff2 100644 +--- a/desktop/source/app/officeipcthread.hxx ++++ b/desktop/source/app/officeipcthread.hxx +@@ -115,7 +115,7 @@ class OfficeIPCThread : public salhelper::Thread + static Status EnableOfficeIPCThread(); + static void DisableOfficeIPCThread(bool join = true); + // start dispatching events... +- static void SetReady( ++ static void SetReady(bool bIsReady, + rtl::Reference< OfficeIPCThread > const & pThread = + rtl::Reference< OfficeIPCThread >()); + static void WaitForReady( +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 184d777..2619539 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1697,7 +1697,12 @@ static void lo_startmain(void*) + { + osl_setThreadName("lo_startmain"); + ++ if (comphelper::SolarMutex::get()) ++ Application::GetSolarMutex().tryToAcquire(); ++ + soffice_main(); ++ ++ Application::ReleaseSolarMutex(); + } + + static bool bInitialized = false; +@@ -1799,6 +1804,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char + SAL_INFO("lok", "Enabling OfficeIPCThread"); + OfficeIPCThread::EnableOfficeIPCThread(); + SAL_INFO("lok", "Starting soffice_main"); ++ OfficeIPCThread::SetReady(false); + pLib->maThread = osl_createThread(lo_startmain, NULL); + SAL_INFO("lok", "Waiting for OfficeIPCThread"); + OfficeIPCThread::WaitForReady(); +diff --git a/framework/source/services/desktop.cxx b/framework/source/services/desktop.cxx +index 24b9761..c7dbaca 100644 +--- a/framework/source/services/desktop.cxx ++++ b/framework/source/services/desktop.cxx +@@ -59,6 +59,7 @@ + #include + + #include ++#include + #include + #include + +@@ -231,8 +232,13 @@ sal_Bool SAL_CALL Desktop::terminate() + + // try to close all open frames. + // Allow using of any UI ... because Desktop.terminate() was designed as UI functionality in the past. +- bool bAllowUI = true; +- bool bFramesClosed = impl_closeFrames(bAllowUI); ++ bool bRestartableMainLoop = comphelper::LibreOfficeKit::isActive(); ++ bool bFramesClosed = impl_closeFrames(!bRestartableMainLoop); ++ if (bRestartableMainLoop) ++ { ++ Application::Quit(); ++ return true; ++ } + if ( ! bFramesClosed ) + { + impl_sendCancelTerminationEvent(lCalledTerminationListener); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 7d1ec01..92cf6b3 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2051,9 +2051,15 @@ static void lok_doc_view_destroy (GtkWidget* widget) + LOKDocViewPrivate& priv = getPrivate(pDocView); + + if (priv->m_pDocument) ++ { + priv->m_pDocument->pClass->destroy (priv->m_pDocument); ++ priv->m_pDocument = nullptr; ++ } + if (priv->m_pOffice) ++ { + priv->m_pOffice->pClass->destroy (priv->m_pOffice); ++ priv->m_pOffice = nullptr; ++ } + + GTK_WIDGET_CLASS (lok_doc_view_parent_class)->destroy (widget); + } +diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx +index 302c4a7..2104243 100644 +--- a/vcl/source/app/svapp.cxx ++++ b/vcl/source/app/svapp.cxx +@@ -331,6 +331,7 @@ void Application::Execute() + { + ImplSVData* pSVData = ImplGetSVData(); + pSVData->maAppData.mbInAppExecute = true; ++ pSVData->maAppData.mbAppQuit = false; + + while ( !pSVData->maAppData.mbAppQuit ) + Application::Yield(); +diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx +index f6d4e25..16977d3 100644 +--- a/vcl/source/app/svmain.cxx ++++ b/vcl/source/app/svmain.cxx +@@ -28,6 +28,7 @@ + #include "tools/resmgr.hxx" + + #include "comphelper/processfactory.hxx" ++#include "comphelper/lok.hxx" + + #include "unotools/syslocaleoptions.hxx" + #include "vcl/svapp.hxx" +@@ -343,6 +344,13 @@ VCLUnoWrapperDeleter::disposing(lang::EventObject const& /* rSource */) + + void DeInitVCL() + { ++ //rhbz#1444437, when using LibreOffice like a library you can't realistically ++ //tear everything down and recreate them on the next call, there's too many ++ //(c++) singletons that point to stuff that gets deleted during shutdown ++ //which won't be recreated on restart. ++ if (comphelper::LibreOfficeKit::isActive()) ++ return; ++ + ImplSVData* pSVData = ImplGetSVData(); + pSVData->mbDeInit = true; + +-- +1.8.3.1 + diff --git a/SOURCES/0006-loplugin-cstylecast-deal-with-those-that-are-technic.patch b/SOURCES/0006-loplugin-cstylecast-deal-with-those-that-are-technic.patch new file mode 100644 index 0000000..db93032 --- /dev/null +++ b/SOURCES/0006-loplugin-cstylecast-deal-with-those-that-are-technic.patch @@ -0,0 +1,40 @@ +From e9e2deeffc6fba956f829e1f2676d48c3e870bcc Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 2 Jun 2015 11:26:10 +0200 +Subject: [PATCH 006/398] loplugin:cstylecast: deal with those that are + (technically) const_cast + +Change-Id: Id57c9599a454e1156a6a248ebb143a88f6d78425 +(cherry picked from commit a9ae0c394b7b763e2c0090defc6d21cc76b1ab87) +--- + desktop/source/lib/init.cxx | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 88cbcbd8d285..39a1fbffc533 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -440,16 +440,16 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha + switch (doc_getDocumentType(pThis)) + { + case LOK_DOCTYPE_SPREADSHEET: +- pMap = (const ExtensionMap*) aCalcExtensionMap; ++ pMap = aCalcExtensionMap; + break; + case LOK_DOCTYPE_PRESENTATION: +- pMap = (const ExtensionMap*) aImpressExtensionMap; ++ pMap = aImpressExtensionMap; + break; + case LOK_DOCTYPE_DRAWING: +- pMap = (const ExtensionMap*) aDrawExtensionMap; ++ pMap = aDrawExtensionMap; + break; + case LOK_DOCTYPE_TEXT: +- pMap = (const ExtensionMap*) aWriterExtensionMap; ++ pMap = aWriterExtensionMap; + break; + case LOK_DOCTYPE_OTHER: + default: +-- +2.12.0 + diff --git a/SOURCES/0007-fsanitize-float-divide-by-zero.patch b/SOURCES/0007-fsanitize-float-divide-by-zero.patch new file mode 100644 index 0000000..022367d --- /dev/null +++ b/SOURCES/0007-fsanitize-float-divide-by-zero.patch @@ -0,0 +1,65 @@ +From 17c7e35232d04b5b32c29b995459e83a4b3a2319 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Wed, 3 Jun 2015 08:11:06 +0200 +Subject: [PATCH 007/398] -fsanitize=float-divide-by-zero + +...happens at least during CppunitTest_sd_tiledrendering that +aCurrTextSize.Height() is zero: + + SdrTextObj::ImpAutoFitText(SdrOutliner&, Size const&, bool) svx/source/svdraw/svdotext.cxx:1312:49 + SdrTextObj::ImpAutoFitText(SdrOutliner&) const svx/source/svdraw/svdotext.cxx:1290:5 + SdrTextObj::BegTextEdit(SdrOutliner&) svx/source/svdraw/svdotxed.cxx:103:9 + SdrObjEditView::SdrBeginTextEdit(SdrObject*, SdrPageView*, vcl::Window*, bool, SdrOutliner*, OutlinerView*, bool, bool, bool) svx/source/svdraw/svdedxv.cxx:635:12 + sd::View::SdrBeginTextEdit(SdrObject*, SdrPageView*, vcl::Window*, bool, SdrOutliner*, OutlinerView*, bool, bool, bool) sd/source/ui/view/sdview.cxx:704:20 + sd::Outliner::EnterEditMode(bool) sd/source/ui/view/Outliner.cxx:1299:9 + sd::Outliner::PrepareSearchAndReplace() sd/source/ui/view/Outliner.cxx:1181:9 + sd::Outliner::ProvideNextTextObject() sd/source/ui/view/Outliner.cxx:973:29 + sd::Outliner::SearchAndReplaceOnce() sd/source/ui/view/Outliner.cxx:674:17 + sd::Outliner::StartSearchAndReplace(SvxSearchItem const*) sd/source/ui/view/Outliner.cxx:496:28 + sd::FuSearch::SearchAndReplace(SvxSearchItem const*) sd/source/ui/func/fusearch.cxx:132:33 + sd::DrawDocShell::Execute(SfxRequest&) sd/source/ui/docshell/docshel3.cxx:222:21 + SfxStubDrawDocShellExecute(SfxShell*, SfxRequest&) workdir/SdiTarget/sd/sdi/sdslots.hxx:17034:1 + SfxShell::CallExec(void (*)(SfxShell*, SfxRequest&), SfxRequest&) include/sfx2/shell.hxx:210:35 + SfxDispatcher::Call_Impl(SfxShell&, SfxSlot const&, SfxRequest&, bool) sfx2/source/control/dispatch.cxx:257:13 + SfxDispatcher::_Execute(SfxShell&, SfxSlot const&, SfxRequest&, SfxCallMode) sfx2/source/control/dispatch.cxx:847:9 + SfxDispatcher::Execute(unsigned short, SfxCallMode, SfxItemSet*, SfxItemSet*, unsigned short) sfx2/source/control/dispatch.cxx:916:9 + SfxDispatchController_Impl::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence const&, com::sun::star::uno::Reference const&) sfx2/source/control/unoctitm.cxx:823:37 + SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence const&) sfx2/source/control/unoctitm.cxx:359:9 + non-virtual thunk to SfxOfficeDispatch::dispatch(com::sun::star::util::URL const&, com::sun::star::uno::Sequence const&) sfx2/source/control/unoctitm.cxx:343:34 + comphelper::dispatchCommand(rtl::OUString const&, com::sun::star::uno::Sequence const&) comphelper/source/misc/dispatchcommand.cxx:57:5 + lcl_search(rtl::OUString const&) sd/qa/unit/tiledrendering/tiledrendering.cxx:338:5 + SdTiledRenderingTest::testSearch() sd/qa/unit/tiledrendering/tiledrendering.cxx:361:5 + ... + +Change-Id: I38ab71c5f4024b2d7270a4f6c2aeb4ef502d08f5 +(cherry picked from commit bf93b3d1a4b624c3b58e6429899c47fa7cad6ede) +--- + svx/source/svdraw/svdotext.cxx | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx +index 47696fd28204..104f48bee47d 100644 +--- a/svx/source/svdraw/svdotext.cxx ++++ b/svx/source/svdraw/svdotext.cxx +@@ -1307,9 +1307,16 @@ void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner, const Size& rTextSize, + const Size aCurrTextSize = rOutliner.CalcTextSizeNTP(); + double fFactor(1.0); + if( bIsVerticalWriting ) +- fFactor = double(rTextSize.Width())/aCurrTextSize.Width(); +- else ++ { ++ if (aCurrTextSize.Width() != 0) ++ { ++ fFactor = double(rTextSize.Width())/aCurrTextSize.Width(); ++ } ++ } ++ else if (aCurrTextSize.Height() != 0) ++ { + fFactor = double(rTextSize.Height())/aCurrTextSize.Height(); ++ } + // fFactor scales in both x and y directions + // - this is fine for bulleted words + // - but it scales too much for a long paragraph +-- +2.12.0 + diff --git a/SOURCES/0008-LOK-fix-the-rectangle-format-mentioned-in-documentat.patch b/SOURCES/0008-LOK-fix-the-rectangle-format-mentioned-in-documentat.patch new file mode 100644 index 0000000..a6c3f33 --- /dev/null +++ b/SOURCES/0008-LOK-fix-the-rectangle-format-mentioned-in-documentat.patch @@ -0,0 +1,28 @@ +From 59ba6f6da9314d57d7c91a20c9ca6e7fc061780b Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 5 Jun 2015 16:36:14 +0530 +Subject: [PATCH 008/398] LOK: fix the rectangle format mentioned in + documentation/comment + +Change-Id: I41bf3a21b5da9fc8155bbe6eb0f86078f90f6647 +(cherry picked from commit 107d31165479d602fbc644aaf41d213e58e00389) +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 66237e4512cf..bdcc2f0c256f 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -39,7 +39,7 @@ typedef enum + * Any tiles which are over the rectangle described in the payload are no + * longer valid. + * +- * Rectangle format: "width, height, x, y", where all numbers are document ++ * Rectangle format: "x, y, width, height", where all numbers are document + * coordinates, in twips. When all tiles are supposed to be dropped, the + * format is the "EMPTY" string. + */ +-- +2.12.0 + diff --git a/SOURCES/0009-loplugin-cstylecast-deal-with-remaining-pointer-cast.patch b/SOURCES/0009-loplugin-cstylecast-deal-with-remaining-pointer-cast.patch new file mode 100644 index 0000000..b167588 --- /dev/null +++ b/SOURCES/0009-loplugin-cstylecast-deal-with-remaining-pointer-cast.patch @@ -0,0 +1,28 @@ +From 9eb895e01e53a2f240067b8a85b4b51dcd48d529 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Mon, 8 Jun 2015 16:26:12 +0200 +Subject: [PATCH 009/398] loplugin:cstylecast: deal with remaining pointer + casts + +Change-Id: I6fcd79094bb09f9068a4182eaace794b19633f4c +(cherry picked from commit b2f490e8627fd31d8f5e48708a898c9f997a4676) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 24f9d04a9024..d18c3c27a70e 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1196,7 +1196,7 @@ SAL_DLLPUBLIC_EXPORT guint lok_docview_get_type() + lok_docview_init, + NULL, + NULL, +- (GtkClassInitFunc) NULL ++ nullptr + }; + + lok_docview_type = gtk_type_unique( gtk_scrolled_window_get_type(), &lok_docview_info ); +-- +2.12.0 + diff --git a/SOURCES/0010-lokdocview-add-width-and-height-to-the-visible-recta.patch b/SOURCES/0010-lokdocview-add-width-and-height-to-the-visible-recta.patch new file mode 100644 index 0000000..10ba9b5 --- /dev/null +++ b/SOURCES/0010-lokdocview-add-width-and-height-to-the-visible-recta.patch @@ -0,0 +1,30 @@ +From 61e6551def6ed87458164aebba5f4401575d9372 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 2 Jun 2015 18:26:12 +0530 +Subject: [PATCH 010/398] lokdocview: add width and height to the visible + rectangle + +Change-Id: I64212113750893f33f8a859ba52ecd8815a820f4 +(cherry picked from commit d2ea6d817d116f4fe4a31e76fe64d88c8121b1c2) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d18c3c27a70e..8fa351add6a9 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1323,8 +1323,10 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_get_visarea(LOKDocView* pThis, GdkRectangl + { + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pThis)); + pArea->x = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_value(pHAdjustment)); ++ pArea->width = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_page_size(pHAdjustment)); + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pThis)); + pArea->y = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_value(pVAdjustment)); ++ pArea->height = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_page_size(pVAdjustment)); + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0011-lokdocview-use-GtkDrawingArea-for-drawing-tiles.patch b/SOURCES/0011-lokdocview-use-GtkDrawingArea-for-drawing-tiles.patch new file mode 100644 index 0000000..559f1c1 --- /dev/null +++ b/SOURCES/0011-lokdocview-use-GtkDrawingArea-for-drawing-tiles.patch @@ -0,0 +1,165 @@ +From 0750e69cc4483cbcf22789d25d4518396e13fc13 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 3 Jun 2015 20:52:49 +0530 +Subject: [PATCH 011/398] lokdocview: use GtkDrawingArea for drawing tiles + +Change-Id: I1a3d8a9229f416418f0f3e9c720b78af09b35978 +(cherry picked from commit a13d4671bf1f557b3104e745277554ed11b3e6da) +--- + libreofficekit/source/gtk/lokdocview.cxx | 77 +++++++++++++------------------- + 1 file changed, 30 insertions(+), 47 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 8fa351add6a9..c487ac8dd906 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -65,6 +65,9 @@ struct LOKDocView_Impl + GtkWidget* m_pEventBox; + GtkWidget* m_pTable; + GtkWidget** m_pCanvas; ++ GtkWidget *darea; ++ ++ TileBuffer *mTileBuffer; + + float m_fZoom; + +@@ -140,6 +143,8 @@ struct LOKDocView_Impl + ~LOKDocView_Impl(); + /// Connected to the destroy signal of LOKDocView, deletes its LOKDocView_Impl. + static void destroy(LOKDocView* pDocView, gpointer pData); ++ /// Connected to the expose-event of the GtkDrawingArea ++ static void on_exposed(GtkWidget *widget, GdkEvent *event, gpointer user_data); + /// Converts from screen pixels to document coordinates. + float pixelToTwip(float fInput); + /// Converts from document coordinates to screen pixels. +@@ -258,6 +263,7 @@ LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPaylo + LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView) + : m_pDocView(pDocView), + m_pEventBox(gtk_event_box_new()), ++ darea(gtk_drawing_area_new()), + m_pTable(0), + m_pCanvas(0), + m_fZoom(1), +@@ -307,6 +313,12 @@ void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/) + delete pDocView->m_pImpl; + } + ++void LOKDocView_Impl::on_exposed(GtkWidget *widget, GdkEvent *event, gpointer userdata) ++{ ++ LOKDocView *pDocView = LOK_DOCVIEW (userdata); ++ pDocView->m_pImpl->renderDocument(0); ++} ++ + float LOKDocView_Impl::pixelToTwip(float fInput) + { + return (fInput / DPI / m_fZoom) * 1440.0f; +@@ -771,40 +783,17 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + { + const int nTileSizePixels = 256; + ++ GdkRectangle visibleArea; ++ lok_docview_get_visarea (m_pDocView, &visibleArea); ++ + long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips); + long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips); + // Total number of rows / columns in this document. + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- // Set up our table and the tile pointers. +- if (!m_pTable) +- pPartial = 0; +- if (pPartial) +- { +- // Same as nRows / nColumns, but from the previous renderDocument() call. +- guint nOldRows, nOldColumns; +- +-#if GTK_CHECK_VERSION(2,22,0) +- gtk_table_get_size(GTK_TABLE(m_pTable), &nOldRows, &nOldColumns); +- if (nOldRows != nRows || nOldColumns != nColumns) +- // Can't do partial rendering, document size changed. +- pPartial = 0; +-#else +- pPartial = 0; +-#endif +- } +- if (!pPartial) +- { +- if (m_pTable) +- gtk_container_remove(GTK_CONTAINER(m_pEventBox), m_pTable); +- m_pTable = gtk_table_new(nRows, nColumns, FALSE); +- gtk_container_add(GTK_CONTAINER(m_pEventBox), m_pTable); +- gtk_widget_show(m_pTable); +- if (m_pCanvas) +- g_free(m_pCanvas); +- m_pCanvas = static_cast(g_malloc0(sizeof(GtkWidget*) * nRows * nColumns)); +- } ++ gtk_widget_set_size_request(darea, nDocumentWidthPixels, nDocumentHeightPixels); ++ cairo_t *pcairo = gdk_cairo_create(darea->window); + + // Render the tiles. + for (guint nRow = 0; nRow < nRows; ++nRow) +@@ -830,7 +819,10 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width); + aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height); + if (pPartial && !gdk_rectangle_intersect(pPartial, &aTileRectangleTwips, 0)) +- bPaint = false; ++ bPaint = false; ++ ++ if (!gdk_rectangle_intersect(&visibleArea, &aTileRectangleTwips, 0)) ++ bPaint = false; + + if (bPaint) + { +@@ -849,21 +841,16 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + // Size of the tile, depends on the zoom factor and the tile position only. + aTileRectangleTwips.width, aTileRectangleTwips.height); + +- if (m_pCanvas[nTile]) +- gtk_widget_destroy(GTK_WIDGET(m_pCanvas[nTile])); +- m_pCanvas[nTile] = gtk_image_new(); +- gtk_image_set_from_pixbuf(GTK_IMAGE(m_pCanvas[nTile]), pPixBuf); +- g_object_unref(G_OBJECT(pPixBuf)); +- gtk_widget_show(m_pCanvas[nTile]); +- gtk_table_attach(GTK_TABLE(m_pTable), +- m_pCanvas[nTile], +- nColumn, nColumn + 1, nRow, nRow + 1, +- GTK_SHRINK, GTK_SHRINK, 0, 0); ++ gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, twipToPixel(aTileRectangleTwips.x), twipToPixel(aTileRectangleTwips.y)); ++ cairo_paint(pcairo); + } + } + } ++ ++ cairo_destroy(pcairo); + } + ++ + GdkRectangle LOKDocView_Impl::payloadToRectangle(const char* pPayload) + { + GdkRectangle aRet; +@@ -1167,17 +1154,13 @@ static void lok_docview_init( GTypeInstance* pInstance, gpointer ) + + pDocView->m_pImpl = new LOKDocView_Impl(pDocView); + gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView), +- pDocView->m_pImpl->m_pEventBox ); +- +- gtk_widget_set_events(pDocView->m_pImpl->m_pEventBox, GDK_BUTTON_PRESS_MASK); // So that drag doesn't try to move the whole window. +- gtk_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pEventBox), "button-press-event", GTK_SIGNAL_FUNC(LOKDocView_Impl::signalButton), pDocView); +- gtk_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pEventBox), "button-release-event", GTK_SIGNAL_FUNC(LOKDocView_Impl::signalButton), pDocView); +- gtk_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pEventBox), "motion-notify-event", GTK_SIGNAL_FUNC(LOKDocView_Impl::signalMotion), pDocView); ++ pDocView->m_pImpl->darea ); + +- gtk_widget_show( pDocView->m_pImpl->m_pEventBox ); ++ g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->darea), ++ "expose-event", ++ GTK_SIGNAL_FUNC(LOKDocView_Impl::on_exposed), pDocView); + + gtk_signal_connect(GTK_OBJECT(pDocView), "destroy", GTK_SIGNAL_FUNC(LOKDocView_Impl::destroy), 0); +- g_signal_connect_after(pDocView->m_pImpl->m_pEventBox, "expose-event", G_CALLBACK(LOKDocView_Impl::renderOverlay), pDocView); + } + + SAL_DLLPUBLIC_EXPORT guint lok_docview_get_type() +-- +2.12.0 + diff --git a/SOURCES/0012-Add-tile-buffering-support.patch b/SOURCES/0012-Add-tile-buffering-support.patch new file mode 100644 index 0000000..57023ed --- /dev/null +++ b/SOURCES/0012-Add-tile-buffering-support.patch @@ -0,0 +1,407 @@ +From 2b35ac76de22c9aa23c2245e49fc9e0c823b739c Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 4 Jun 2015 00:06:46 +0530 +Subject: [PATCH 012/398] Add tile buffering support + +The TileBuffer class now manages all the tiles. The tile rendering calls +to LO core is also managed by this class. + +Change-Id: Ic667a93dcf1c097e0601c0496e8a083c4742e8cb +(cherry picked from commit 42dc4f3ed8b7b41597dd9851c31dee4d0e352f46) +--- + libreofficekit/Library_libreofficekitgtk.mk | 1 + + libreofficekit/source/gtk/lokdocview.cxx | 76 ++++++++++++------------ + libreofficekit/source/gtk/tilebuffer.cxx | 90 +++++++++++++++++++++++++++++ + libreofficekit/source/gtk/tilebuffer.hxx | 78 +++++++++++++++++++++++++ + 4 files changed, 209 insertions(+), 36 deletions(-) + create mode 100644 libreofficekit/source/gtk/tilebuffer.cxx + create mode 100644 libreofficekit/source/gtk/tilebuffer.hxx + +diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk +index ff800d0f1d96..92409537f4e8 100644 +--- a/libreofficekit/Library_libreofficekitgtk.mk ++++ b/libreofficekit/Library_libreofficekitgtk.mk +@@ -17,6 +17,7 @@ $(eval $(call gb_Library_use_externals,libreofficekitgtk,\ + + $(eval $(call gb_Library_add_exception_objects,libreofficekitgtk,\ + libreofficekit/source/gtk/lokdocview \ ++ libreofficekit/source/gtk/tilebuffer \ + )) + + ifeq ($(OS),LINUX) +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index c487ac8dd906..413054cf873c 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -22,6 +22,8 @@ + #include + #include + ++#include "tilebuffer.hxx" ++ + #if !GLIB_CHECK_VERSION(2,32,0) + #define G_SOURCE_REMOVE FALSE + #define G_SOURCE_CONTINUE TRUE +@@ -37,6 +39,8 @@ + + // We know that VirtualDevices use a DPI of 96. + static const int DPI = 96; ++// Lets use a square of side 256 pixels. ++static const int nTileSizePixels = 256; + + namespace { + +@@ -62,12 +66,8 @@ void payloadToSize(const char* pPayload, long& rWidth, long& rHeight) + struct LOKDocView_Impl + { + LOKDocView* m_pDocView; +- GtkWidget* m_pEventBox; +- GtkWidget* m_pTable; +- GtkWidget** m_pCanvas; +- GtkWidget *darea; +- +- TileBuffer *mTileBuffer; ++ GtkWidget *m_pDrawingArea; ++ TileBuffer *m_pTileBuffer; + + float m_fZoom; + +@@ -262,10 +262,7 @@ LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPaylo + + LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView) + : m_pDocView(pDocView), +- m_pEventBox(gtk_event_box_new()), +- darea(gtk_drawing_area_new()), +- m_pTable(0), +- m_pCanvas(0), ++ m_pDrawingArea(gtk_drawing_area_new()), + m_fZoom(1), + m_pOffice(0), + m_pDocument(0), +@@ -313,7 +310,7 @@ void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/) + delete pDocView->m_pImpl; + } + +-void LOKDocView_Impl::on_exposed(GtkWidget *widget, GdkEvent *event, gpointer userdata) ++void LOKDocView_Impl::on_exposed(GtkWidget* /*widget*/, GdkEvent* /*event*/, gpointer userdata) + { + LOKDocView *pDocView = LOK_DOCVIEW (userdata); + pDocView->m_pImpl->renderDocument(0); +@@ -773,7 +770,7 @@ gboolean LOKDocView_Impl::handleTimeoutImpl() + m_bCursorOverlayVisible = false; + else + m_bCursorOverlayVisible = true; +- gtk_widget_queue_draw(GTK_WIDGET(m_pEventBox)); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); + } + + return G_SOURCE_CONTINUE; +@@ -781,8 +778,6 @@ gboolean LOKDocView_Impl::handleTimeoutImpl() + + void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + { +- const int nTileSizePixels = 256; +- + GdkRectangle visibleArea; + lok_docview_get_visarea (m_pDocView, &visibleArea); + +@@ -792,8 +787,8 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- gtk_widget_set_size_request(darea, nDocumentWidthPixels, nDocumentHeightPixels); +- cairo_t *pcairo = gdk_cairo_create(darea->window); ++ gtk_widget_set_size_request(m_pDrawingArea, nDocumentWidthPixels, nDocumentHeightPixels); ++ cairo_t *pcairo = gdk_cairo_create(m_pDrawingArea->window); + + // Render the tiles. + for (guint nRow = 0; nRow < nRows; ++nRow) +@@ -826,20 +821,10 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + + if (bPaint) + { +- // Index of the current tile. +- guint nTile = nRow * nColumns + nColumn; +- +- GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, aTileRectanglePixels.width, aTileRectanglePixels.height); +- unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); +- g_info("renderDocument: paintTile(%d, %d)", nRow, nColumn); +- m_pDocument->pClass->paintTile(m_pDocument, +- // Buffer and its size, depends on the position only. +- pBuffer, +- aTileRectanglePixels.width, aTileRectanglePixels.height, +- // Position of the tile. +- aTileRectangleTwips.x, aTileRectangleTwips.y, +- // Size of the tile, depends on the zoom factor and the tile position only. +- aTileRectangleTwips.width, aTileRectangleTwips.height); ++ g_info("gettile: (%d %d)", nRow, nColumn); ++ ++ Tile& currentTile = m_pTileBuffer->tile_buffer_get_tile(nRow, nColumn); ++ GdkPixbuf* pPixBuf = currentTile.tile_get_buffer(); + + gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, twipToPixel(aTileRectangleTwips.x), twipToPixel(aTileRectangleTwips.y)); + cairo_paint(pcairo); +@@ -959,7 +944,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + { + m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + m_bCursorOverlayVisible = true; +- gtk_widget_queue_draw(GTK_WIDGET(m_pEventBox)); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); + } + break; + case LOK_CALLBACK_TEXT_SELECTION: +@@ -976,7 +961,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + } + else + memset(&m_aHandleMiddleRect, 0, sizeof(m_aHandleMiddleRect)); +- gtk_widget_queue_draw(GTK_WIDGET(m_pEventBox)); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); + } + break; + case LOK_CALLBACK_TEXT_SELECTION_START: +@@ -1000,7 +985,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + m_aGraphicSelection = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + else + memset(&m_aGraphicSelection, 0, sizeof(m_aGraphicSelection)); +- gtk_widget_queue_draw(GTK_WIDGET(m_pEventBox)); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); + } + break; + case LOK_CALLBACK_HYPERLINK_CLICKED: +@@ -1154,9 +1139,9 @@ static void lok_docview_init( GTypeInstance* pInstance, gpointer ) + + pDocView->m_pImpl = new LOKDocView_Impl(pDocView); + gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView), +- pDocView->m_pImpl->darea ); ++ pDocView->m_pImpl->m_pDrawingArea ); + +- g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->darea), ++ g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + "expose-event", + GTK_SIGNAL_FUNC(LOKDocView_Impl::on_exposed), pDocView); + +@@ -1218,6 +1203,18 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, c + pDocView->m_pImpl->m_pDocument->pClass->registerCallback(pDocView->m_pImpl->m_pDocument, &LOKDocView_Impl::callbackWorker, pDocView); + pDocView->m_pImpl->m_pDocument->pClass->getDocumentSize(pDocView->m_pImpl->m_pDocument, &pDocView->m_pImpl->m_nDocumentWidthTwips, &pDocView->m_pImpl->m_nDocumentHeightTwips); + g_timeout_add(600, &LOKDocView_Impl::handleTimeout, pDocView); ++ ++ long nDocumentWidthTwips = pDocView->m_pImpl->m_nDocumentWidthTwips; ++ long nDocumentHeightTwips = pDocView->m_pImpl->m_nDocumentHeightTwips; ++ long nDocumentWidthPixels = pDocView->m_pImpl->twipToPixel(nDocumentWidthTwips); ++ long nDocumentHeightPixels = pDocView->m_pImpl->twipToPixel(nDocumentHeightTwips); ++ // Total number of rows / columns in this document. ++ guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); ++ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); ++ pDocView->m_pImpl->m_pTileBuffer = new TileBuffer(pDocView->m_pImpl->m_pDocument, ++ nTileSizePixels, ++ nRows, ++ nColumns); + pDocView->m_pImpl->renderDocument(0); + } + +@@ -1232,6 +1229,13 @@ SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_docview_get_document(LOKDocView + SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZoom ) + { + pDocView->m_pImpl->m_fZoom = fZoom; ++ long nDocumentWidthPixels = pDocView->m_pImpl->twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips); ++ long nDocumentHeightPixels = pDocView->m_pImpl->twipToPixel(pDocView->m_pImpl->m_nDocumentHeightTwips); ++ // Total number of rows / columns in this document. ++ guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); ++ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); ++ ++ pDocView->m_pImpl->m_pTileBuffer->tile_buffer_set_zoom(fZoom, nRows, nColumns); + + if ( pDocView->m_pImpl->m_pDocument ) + pDocView->m_pImpl->renderDocument(0); +@@ -1283,7 +1287,7 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_set_edit( LOKDocView* pDocView, + } + pDocView->m_pImpl->m_bEdit = bEdit; + g_signal_emit(pDocView, docview_signals[EDIT_CHANGED], 0, bWasEdit); +- gtk_widget_queue_draw(GTK_WIDGET(pDocView->m_pImpl->m_pEventBox)); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView->m_pImpl->m_pDrawingArea)); + } + + SAL_DLLPUBLIC_EXPORT gboolean lok_docview_get_edit(LOKDocView* pDocView) +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +new file mode 100644 +index 000000000000..ca66ae904f71 +--- /dev/null ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -0,0 +1,90 @@ ++/* -*- 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 "tilebuffer.hxx" ++ ++static const int DPI = 96; ++ ++static float pixelToTwip(float fInput, float zoom) ++{ ++ return (fInput / DPI / zoom) * 1440.0f; ++} ++ ++static float twipToPixel(float fInput, float zoom) ++{ ++ return fInput / 1440.0f * DPI * zoom; ++} ++ ++GdkPixbuf* Tile::tile_get_buffer() ++{ ++ return m_pBuffer; ++} ++ ++void Tile::tile_release() ++{ ++ gdk_pixbuf_unref(m_pBuffer); ++ m_pBuffer = NULL; ++} ++ ++void TileBuffer::tile_buffer_set_zoom(float newZoomFactor, int rows, int columns) ++{ ++ m_fZoomFactor = newZoomFactor; ++ ++ tile_buffer_reset_all_tiles(); ++ ++ // set new buffer width and height ++ m_nWidth = columns; ++ m_nHeight = rows; ++ m_aTiles.resize(m_nWidth * m_nHeight); ++} ++ ++void TileBuffer::tile_buffer_reset_all_tiles() ++{ ++ for (size_t i = 0; i < m_aTiles.size(); i++) ++ { ++ m_aTiles[i].tile_release(); ++ } ++ m_aTiles.clear(); ++} ++ ++Tile& TileBuffer::tile_buffer_get_tile(int x, int y) ++{ ++ int index = x * m_nWidth + y; ++ if(!m_aTiles[index].valid) ++ { ++ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); ++ if (!pPixBuf){ ++ g_info ("error allocating memory to pixbuf"); ++ } ++ unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); ++ GdkRectangle aTileRectangle; ++ aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y; ++ aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x; ++ ++ g_info ("rendering (%d %d)", x, y); ++ m_pLOKDocument->pClass->paintTile(m_pLOKDocument, ++ // Buffer and its size, depends on the position only. ++ pBuffer, ++ m_nTileSize, m_nTileSize, ++ // Position of the tile. ++ aTileRectangle.x, aTileRectangle.y, ++ // Size of the tile, depends on the zoom factor and the tile position only. ++ pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor)); ++ ++ m_aTiles[index].tile_set_pixbuf(pPixBuf); ++ m_aTiles[index].valid = 1; ++ } ++ ++ return m_aTiles[index]; ++} ++ ++void Tile::tile_set_pixbuf(GdkPixbuf *buffer) ++{ ++ m_pBuffer = buffer; ++} +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +new file mode 100644 +index 000000000000..a5ed0dc8ec61 +--- /dev/null ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -0,0 +1,78 @@ ++/* -*- 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/. ++ */ ++ ++#ifndef INCLUDED_TILEBUFFER_HXX ++#define INCLUDED_TILEBUFFER_HXX ++ ++#include ++#include ++#include ++ ++#define LOK_USE_UNSTABLE_API ++#include ++#include ++#include ++ ++/* ++ This class represents a single tile in the tile buffer. ++ TODO: Extend it to support features like double buffering ++*/ ++class Tile ++{ ++public: ++ Tile() : valid(0) {} ++ ~Tile() { ++ tile_release(); ++ } ++ ++ GdkPixbuf* tile_get_buffer(); ++ void tile_release(); ++ void tile_set_pixbuf(GdkPixbuf*); ++ bool valid; ++private: ++ GdkPixbuf *m_pBuffer; ++}; ++ ++/* ++ TileBuffer is the buffer caching all the recently rendered tiles. ++ The buffer is set to invalid when zoom factor changes. ++*/ ++class TileBuffer ++{ ++public: ++ TileBuffer(LibreOfficeKitDocument *document, ++ int tileSize, ++ int rows, ++ int columns) ++ : m_pLOKDocument(document) ++ , m_nTileSize(tileSize) ++ , m_fZoomFactor(1) ++ , m_nWidth(columns) ++ , m_nHeight(rows) ++ { ++ m_aTiles.resize(rows * columns); ++ } ++ ++ ~TileBuffer() {} ++ ++ void tile_buffer_set_zoom(float zoomFactor, int rows, int columns); ++ Tile& tile_buffer_get_tile(int x, int y); ++ void tile_buffer_update(); ++ void tile_buffer_reset_all_tiles(); ++private: ++ LibreOfficeKitDocument *m_pLOKDocument; ++ int m_nTileSize; ++ float m_fZoomFactor; ++ std::vector m_aTiles; ++ //TODO: Also set width and height when document size changes ++ int m_nWidth; ++ int m_nHeight; ++}; ++ ++#endif // INCLUDED_TILEBUFFER_HXX +-- +2.12.0 + diff --git a/SOURCES/0013-lokdocview-Use-maps-instead-of-vector.patch b/SOURCES/0013-lokdocview-Use-maps-instead-of-vector.patch new file mode 100644 index 0000000..ee34179 --- /dev/null +++ b/SOURCES/0013-lokdocview-Use-maps-instead-of-vector.patch @@ -0,0 +1,102 @@ +From a8675df04f316dce72483c62f578467dfb446493 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 4 Jun 2015 01:44:47 +0530 +Subject: [PATCH 013/398] lokdocview: Use maps instead of vector + +Using vector each tile needs to be allocated memory irrespective of +whether tile is required or not. This approach fails when we zoom in to +a very high level to have thousands of tiles due to lot of memory +required. Using maps instead of vector takes care of this, and only +allocates Tiles when required. + +Change-Id: I523f815618451a7f014e28258e0de7b1c0693370 +(cherry picked from commit cc78267f274a42d268b1d56d0a83888dc69a4c91) +--- + libreofficekit/source/gtk/tilebuffer.cxx | 17 +++++++++-------- + libreofficekit/source/gtk/tilebuffer.hxx | 8 +++----- + 2 files changed, 12 insertions(+), 13 deletions(-) + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index ca66ae904f71..e1b5b3294cc5 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -41,22 +41,22 @@ void TileBuffer::tile_buffer_set_zoom(float newZoomFactor, int rows, int columns + // set new buffer width and height + m_nWidth = columns; + m_nHeight = rows; +- m_aTiles.resize(m_nWidth * m_nHeight); + } + + void TileBuffer::tile_buffer_reset_all_tiles() + { +- for (size_t i = 0; i < m_aTiles.size(); i++) ++ std::map::iterator it = m_mTiles.begin(); ++ for (; it != m_mTiles.end(); it++) + { +- m_aTiles[i].tile_release(); ++ it->second.tile_release(); + } +- m_aTiles.clear(); ++ m_mTiles.clear(); + } + + Tile& TileBuffer::tile_buffer_get_tile(int x, int y) + { + int index = x * m_nWidth + y; +- if(!m_aTiles[index].valid) ++ if(m_mTiles.find(index) == m_mTiles.end()) + { + GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); + if (!pPixBuf){ +@@ -77,11 +77,12 @@ Tile& TileBuffer::tile_buffer_get_tile(int x, int y) + // Size of the tile, depends on the zoom factor and the tile position only. + pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor)); + +- m_aTiles[index].tile_set_pixbuf(pPixBuf); +- m_aTiles[index].valid = 1; ++ //create a mapping for it ++ m_mTiles[index].tile_set_pixbuf(pPixBuf); ++ m_mTiles[index].valid = 1; + } + +- return m_aTiles[index]; ++ return m_mTiles[index]; + } + + void Tile::tile_set_pixbuf(GdkPixbuf *buffer) +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index a5ed0dc8ec61..0bc2d38dd641 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -12,7 +12,7 @@ + + #include + #include +-#include ++#include + + #define LOK_USE_UNSTABLE_API + #include +@@ -55,9 +55,7 @@ public: + , m_fZoomFactor(1) + , m_nWidth(columns) + , m_nHeight(rows) +- { +- m_aTiles.resize(rows * columns); +- } ++ { } + + ~TileBuffer() {} + +@@ -69,7 +67,7 @@ private: + LibreOfficeKitDocument *m_pLOKDocument; + int m_nTileSize; + float m_fZoomFactor; +- std::vector m_aTiles; ++ std::map m_mTiles; + //TODO: Also set width and height when document size changes + int m_nWidth; + int m_nHeight; +-- +2.12.0 + diff --git a/SOURCES/0014-lokdocview-Add-support-for-editing-documents.patch b/SOURCES/0014-lokdocview-Add-support-for-editing-documents.patch new file mode 100644 index 0000000..aa6a372 --- /dev/null +++ b/SOURCES/0014-lokdocview-Add-support-for-editing-documents.patch @@ -0,0 +1,327 @@ +From 34a8ad7556a7a69f70a87d4d4e3dab328cff33de Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 4 Jun 2015 03:32:18 +0530 +Subject: [PATCH 014/398] lokdocview: Add support for editing documents + +Change-Id: I8637d99e6fa59129af207e667bcdf03dc212efeb +(cherry picked from commit 82a208a08fdfa8b6dab4f1577931f5e4f037276c) +--- + libreofficekit/source/gtk/lokdocview.cxx | 50 ++++++++++++++-- + libreofficekit/source/gtk/tilebuffer.cxx | 99 ++++++++++++++++++-------------- + libreofficekit/source/gtk/tilebuffer.hxx | 68 +++++++++++----------- + 3 files changed, 136 insertions(+), 81 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 413054cf873c..3b894f765faa 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -821,7 +821,7 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + + if (bPaint) + { +- g_info("gettile: (%d %d)", nRow, nColumn); ++ // g_info("gettile: (%d %d)", nRow, nColumn); + + Tile& currentTile = m_pTileBuffer->tile_buffer_get_tile(nRow, nColumn); + GdkPixbuf* pPixBuf = currentTile.tile_get_buffer(); +@@ -934,17 +934,50 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + if (pCallback->m_aPayload != "EMPTY") + { + GdkRectangle aRectangle = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); +- renderDocument(&aRectangle); ++ GdkRectangle aRectanglePixels; ++ aRectanglePixels.x = twipToPixel(aRectangle.x); ++ aRectanglePixels.y = twipToPixel(aRectangle.y); ++ aRectanglePixels.width = twipToPixel(aRectangle.width); ++ aRectanglePixels.height = twipToPixel(aRectangle.height); ++ int rowStart = aRectanglePixels.y / nTileSizePixels; ++ int colStart = aRectanglePixels.x / nTileSizePixels; ++ int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; ++ int colEnd = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; ++ int i,j; ++ for (i = rowStart; i < rowEnd; i++) { ++ for (j = colStart; j < colEnd; j++) { ++ m_pTileBuffer->tile_buffer_set_invalid(i, j); ++ } ++ } ++ renderDocument(0); + } + else ++ { ++ m_pTileBuffer->tile_buffer_reset_all_tiles(); + renderDocument(0); ++ } + } + break; + case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: + { + m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + m_bCursorOverlayVisible = true; +- gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); ++ GdkRectangle aRectanglePixels; ++ aRectanglePixels.x = twipToPixel(m_aVisibleCursor.x); ++ aRectanglePixels.y = twipToPixel(m_aVisibleCursor.y); ++ aRectanglePixels.width = twipToPixel(m_aVisibleCursor.width); ++ aRectanglePixels.height = twipToPixel(m_aVisibleCursor.height); ++ int rowStart = aRectanglePixels.y / nTileSizePixels; ++ int colStart = aRectanglePixels.x / nTileSizePixels; ++ int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; ++ int colEnd = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; ++ int i,j; ++ for (i = rowStart; i < rowEnd; i++) { ++ for (j = colStart; j < colEnd; j++) { ++ m_pTileBuffer->tile_buffer_set_invalid(i, j); ++ } ++ } ++ renderDocument(0); + } + break; + case LOK_CALLBACK_TEXT_SELECTION: +@@ -961,7 +994,6 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + } + else + memset(&m_aHandleMiddleRect, 0, sizeof(m_aHandleMiddleRect)); +- gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); + } + break; + case LOK_CALLBACK_TEXT_SELECTION_START: +@@ -1144,6 +1176,16 @@ static void lok_docview_init( GTypeInstance* pInstance, gpointer ) + g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + "expose-event", + GTK_SIGNAL_FUNC(LOKDocView_Impl::on_exposed), pDocView); ++ g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ "expose-event", ++ GTK_SIGNAL_FUNC(LOKDocView_Impl::renderOverlay), pDocView); ++ gtk_widget_add_events(pDocView->m_pImpl->m_pDrawingArea, ++ GDK_BUTTON_PRESS_MASK ++ | GDK_BUTTON_RELEASE_MASK ++ | GDK_BUTTON_MOTION_MASK); ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-press-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-release-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "motion-notify-event", G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView); + + gtk_signal_connect(GTK_OBJECT(pDocView), "destroy", GTK_SIGNAL_FUNC(LOKDocView_Impl::destroy), 0); + } +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index e1b5b3294cc5..e13f5b034c1d 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -23,69 +23,82 @@ static float twipToPixel(float fInput, float zoom) + + GdkPixbuf* Tile::tile_get_buffer() + { +- return m_pBuffer; ++ return m_pBuffer; + } + + void Tile::tile_release() + { +- gdk_pixbuf_unref(m_pBuffer); +- m_pBuffer = NULL; ++ g_object_unref (m_pBuffer); ++ m_pBuffer = NULL; + } + + void TileBuffer::tile_buffer_set_zoom(float newZoomFactor, int rows, int columns) + { +- m_fZoomFactor = newZoomFactor; ++ m_fZoomFactor = newZoomFactor; + +- tile_buffer_reset_all_tiles(); ++ tile_buffer_reset_all_tiles(); + +- // set new buffer width and height +- m_nWidth = columns; +- m_nHeight = rows; ++ // set new buffer width and height ++ m_nWidth = columns; ++ m_nHeight = rows; + } + + void TileBuffer::tile_buffer_reset_all_tiles() + { +- std::map::iterator it = m_mTiles.begin(); +- for (; it != m_mTiles.end(); it++) +- { +- it->second.tile_release(); +- } +- m_mTiles.clear(); ++ std::map::iterator it = m_mTiles.begin(); ++ for (; it != m_mTiles.end(); it++) ++ { ++ it->second.tile_release(); ++ } ++ m_mTiles.clear(); ++} ++ ++void TileBuffer::tile_buffer_set_invalid(int x, int y) ++{ ++ int index = x * m_nWidth + y; ++ g_info("setting invalid : %d %d",x, y); ++ if (m_mTiles.find(index) != m_mTiles.end()) ++ { ++ m_mTiles[index].valid = 0; ++ m_mTiles[index].tile_release(); ++ m_mTiles.erase(index); ++ } + } + + Tile& TileBuffer::tile_buffer_get_tile(int x, int y) + { +- int index = x * m_nWidth + y; +- if(m_mTiles.find(index) == m_mTiles.end()) +- { +- GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); +- if (!pPixBuf){ +- g_info ("error allocating memory to pixbuf"); +- } +- unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); +- GdkRectangle aTileRectangle; +- aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y; +- aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x; +- +- g_info ("rendering (%d %d)", x, y); +- m_pLOKDocument->pClass->paintTile(m_pLOKDocument, +- // Buffer and its size, depends on the position only. +- pBuffer, +- m_nTileSize, m_nTileSize, +- // Position of the tile. +- aTileRectangle.x, aTileRectangle.y, +- // Size of the tile, depends on the zoom factor and the tile position only. +- pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor)); +- +- //create a mapping for it +- m_mTiles[index].tile_set_pixbuf(pPixBuf); +- m_mTiles[index].valid = 1; +- } +- +- return m_mTiles[index]; ++ int index = x * m_nWidth + y; ++ if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[index].valid) ++ { ++ ++ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); ++ if (!pPixBuf){ ++ g_info ("error allocating memory to pixbuf"); ++ } ++ unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); ++ GdkRectangle aTileRectangle; ++ aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y; ++ aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x; ++ ++ g_info ("rendering (%d %d)", x, y); ++ m_pLOKDocument->pClass->paintTile(m_pLOKDocument, ++ // Buffer and its size, depends on the position only. ++ pBuffer, ++ m_nTileSize, m_nTileSize, ++ // Position of the tile. ++ aTileRectangle.x, aTileRectangle.y, ++ // Size of the tile, depends on the zoom factor and the tile position only. ++ pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor)); ++ ++ //create a mapping for it ++ m_mTiles[index].tile_set_pixbuf(pPixBuf); ++ m_mTiles[index].valid = 1; ++ } ++ ++ return m_mTiles[index]; + } + + void Tile::tile_set_pixbuf(GdkPixbuf *buffer) + { +- m_pBuffer = buffer; ++ m_pBuffer = buffer; + } +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 0bc2d38dd641..088df93ca6b6 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -25,18 +25,17 @@ + */ + class Tile + { +-public: +- Tile() : valid(0) {} +- ~Tile() { +- tile_release(); +- } ++ public: ++ Tile() : valid(0) {} ++ ~Tile() { ++ } + +- GdkPixbuf* tile_get_buffer(); +- void tile_release(); +- void tile_set_pixbuf(GdkPixbuf*); +- bool valid; +-private: +- GdkPixbuf *m_pBuffer; ++ GdkPixbuf* tile_get_buffer(); ++ void tile_release(); ++ void tile_set_pixbuf(GdkPixbuf*); ++ bool valid; ++ private: ++ GdkPixbuf *m_pBuffer; + }; + + /* +@@ -45,32 +44,33 @@ private: + */ + class TileBuffer + { +-public: +- TileBuffer(LibreOfficeKitDocument *document, +- int tileSize, +- int rows, +- int columns) +- : m_pLOKDocument(document) +- , m_nTileSize(tileSize) +- , m_fZoomFactor(1) +- , m_nWidth(columns) +- , m_nHeight(rows) ++ public: ++ TileBuffer(LibreOfficeKitDocument *document, ++ int tileSize, ++ int rows, ++ int columns) ++ : m_pLOKDocument(document) ++ , m_nTileSize(tileSize) ++ , m_fZoomFactor(1) ++ , m_nWidth(columns) ++ , m_nHeight(rows) + { } + +- ~TileBuffer() {} ++ ~TileBuffer() {} + +- void tile_buffer_set_zoom(float zoomFactor, int rows, int columns); +- Tile& tile_buffer_get_tile(int x, int y); +- void tile_buffer_update(); +- void tile_buffer_reset_all_tiles(); +-private: +- LibreOfficeKitDocument *m_pLOKDocument; +- int m_nTileSize; +- float m_fZoomFactor; +- std::map m_mTiles; +- //TODO: Also set width and height when document size changes +- int m_nWidth; +- int m_nHeight; ++ void tile_buffer_set_zoom(float zoomFactor, int rows, int columns); ++ Tile& tile_buffer_get_tile(int x, int y); ++ void tile_buffer_update(); ++ void tile_buffer_reset_all_tiles(); ++ void tile_buffer_set_invalid(int x, int y); ++ private: ++ LibreOfficeKitDocument *m_pLOKDocument; ++ int m_nTileSize; ++ float m_fZoomFactor; ++ std::map m_mTiles; ++ //TODO: Also set width and height when document size changes ++ int m_nWidth; ++ int m_nHeight; + }; + + #endif // INCLUDED_TILEBUFFER_HXX +-- +2.12.0 + diff --git a/SOURCES/0015-lokdocview-move-commonly-used-functions-and-variable.patch b/SOURCES/0015-lokdocview-move-commonly-used-functions-and-variable.patch new file mode 100644 index 0000000..f0214b4 --- /dev/null +++ b/SOURCES/0015-lokdocview-move-commonly-used-functions-and-variable.patch @@ -0,0 +1,381 @@ +From b4886f6f3f809212c97fb93cb7e7e7375b5f188a Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 4 Jun 2015 13:56:46 +0530 +Subject: [PATCH 015/398] lokdocview: move commonly used functions and + variables to common header + +twipToPixel and pixelToTwip are also being used by the new TileBuffer +clsas. Lets move these utility functions to a common header, +tilebuffer.hxx + +The variables for DPI and tileSize are also moved to tilebuffer.hxx + +Change-Id: I9d0bec7f2aefe412df232040a7a9abc6db3e4ccb +(cherry picked from commit a5d3efa4a02bed357d43960913a7c946c8b12aff) +--- + libreofficekit/source/gtk/lokdocview.cxx | 125 +++++++++++++------------------ + libreofficekit/source/gtk/tilebuffer.cxx | 6 +- + libreofficekit/source/gtk/tilebuffer.hxx | 9 +++ + 3 files changed, 65 insertions(+), 75 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 3b894f765faa..bfb414f0909c 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -37,11 +37,6 @@ + // Number of handles around a graphic selection. + #define GRAPHIC_HANDLE_COUNT 8 + +-// We know that VirtualDevices use a DPI of 96. +-static const int DPI = 96; +-// Lets use a square of side 256 pixels. +-static const int nTileSizePixels = 256; +- + namespace { + + /// Sets rWidth and rHeight from a "width, height" string. +@@ -145,10 +140,6 @@ struct LOKDocView_Impl + static void destroy(LOKDocView* pDocView, gpointer pData); + /// Connected to the expose-event of the GtkDrawingArea + static void on_exposed(GtkWidget *widget, GdkEvent *event, gpointer user_data); +- /// Converts from screen pixels to document coordinates. +- float pixelToTwip(float fInput); +- /// Converts from document coordinates to screen pixels. +- float twipToPixel(float fInput); + /// Receives a key press or release event. + void signalKey(GdkEventKey* pEvent); + /** +@@ -316,16 +307,6 @@ void LOKDocView_Impl::on_exposed(GtkWidget* /*widget*/, GdkEvent* /*event*/, gpo + pDocView->m_pImpl->renderDocument(0); + } + +-float LOKDocView_Impl::pixelToTwip(float fInput) +-{ +- return (fInput / DPI / m_fZoom) * 1440.0f; +-} +- +-float LOKDocView_Impl::twipToPixel(float fInput) +-{ +- return fInput / 1440.0f * DPI * m_fZoom; +-} +- + void LOKDocView_Impl::signalKey(GdkEventKey* pEvent) + { + int nCharCode = 0; +@@ -390,7 +371,7 @@ gboolean LOKDocView_Impl::signalButton(GtkWidget* /*pEventBox*/, GdkEventButton* + /// Receives a button press event. + gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) + { +- g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", (int)pEvent->x, (int)pEvent->y, (int)pixelToTwip(pEvent->x), (int)pixelToTwip(pEvent->y)); ++ g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", (int)pEvent->x, (int)pEvent->y, (int)pixelToTwip(pEvent->x, m_fZoom), (int)pixelToTwip(pEvent->y, m_fZoom)); + + if (pEvent->type == GDK_BUTTON_RELEASE) + { +@@ -419,7 +400,7 @@ gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) + { + g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i); + m_bInDragGraphicHandles[i] = false; +- m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y)); ++ m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom)); + return FALSE; + } + } +@@ -428,7 +409,7 @@ gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) + { + g_info("LOKDocView_Impl::signalButton: end of drag graphic selection"); + m_bInDragGraphicSelection = false; +- m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y)); ++ m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom)); + return FALSE; + } + } +@@ -469,8 +450,8 @@ gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) + m_bInDragGraphicHandles[i] = true; + m_pDocument->pClass->setGraphicSelection(m_pDocument, + LOK_SETGRAPHICSELECTION_START, +- pixelToTwip(m_aGraphicHandleRects[i].x + m_aGraphicHandleRects[i].width / 2), +- pixelToTwip(m_aGraphicHandleRects[i].y + m_aGraphicHandleRects[i].height / 2)); ++ pixelToTwip(m_aGraphicHandleRects[i].x + m_aGraphicHandleRects[i].width / 2, m_fZoom), ++ pixelToTwip(m_aGraphicHandleRects[i].y + m_aGraphicHandleRects[i].height / 2, m_fZoom)); + return FALSE; + } + } +@@ -488,7 +469,7 @@ gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) + if ((pEvent->time - m_nLastButtonPressTime) < 250) + nCount++; + m_nLastButtonPressTime = pEvent->time; +- m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y), nCount); ++ m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), nCount); + break; + } + case GDK_BUTTON_RELEASE: +@@ -497,7 +478,7 @@ gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) + if ((pEvent->time - m_nLastButtonReleaseTime) < 250) + nCount++; + m_nLastButtonReleaseTime = pEvent->time; +- m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y), nCount); ++ m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), nCount); + break; + } + default: +@@ -534,21 +515,21 @@ gboolean LOKDocView_Impl::signalMotionImpl(GdkEventButton* pEvent) + { + g_info("lcl_signalMotion: dragging the middle handle"); + LOKDocView_Impl::getDragPoint(&m_aHandleMiddleRect, pEvent, &aPoint); +- m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_RESET, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y)); ++ m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_RESET, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom)); + return FALSE; + } + if (m_bInDragStartHandle) + { + g_info("lcl_signalMotion: dragging the start handle"); + LOKDocView_Impl::getDragPoint(&m_aHandleStartRect, pEvent, &aPoint); +- m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y)); ++ m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom)); + return FALSE; + } + if (m_bInDragEndHandle) + { + g_info("lcl_signalMotion: dragging the end handle"); + LOKDocView_Impl::getDragPoint(&m_aHandleEndRect, pEvent, &aPoint); +- m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y)); ++ m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom)); + return FALSE; + } + for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) +@@ -566,20 +547,20 @@ gboolean LOKDocView_Impl::signalMotionImpl(GdkEventButton* pEvent) + } + + GdkRectangle aMotionInTwipsInTwips; +- aMotionInTwipsInTwips.x = pixelToTwip(pEvent->x); +- aMotionInTwipsInTwips.y = pixelToTwip(pEvent->y); ++ aMotionInTwipsInTwips.x = pixelToTwip(pEvent->x, m_fZoom); ++ aMotionInTwipsInTwips.y = pixelToTwip(pEvent->y, m_fZoom); + aMotionInTwipsInTwips.width = 1; + aMotionInTwipsInTwips.height = 1; + if (gdk_rectangle_intersect(&aMotionInTwipsInTwips, &m_aGraphicSelection, 0)) + { + g_info("lcl_signalMotion: start of drag graphic selection"); + m_bInDragGraphicSelection = true; +- m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y)); ++ m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom)); + return FALSE; + } + + // Otherwise a mouse move, as on the desktop. +- m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x), pixelToTwip(pEvent->y), 1); ++ m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), 1); + + return FALSE; + } +@@ -602,10 +583,10 @@ gboolean LOKDocView_Impl::renderOverlayImpl(GtkWidget* pWidget) + + cairo_set_source_rgb(pCairo, 0, 0, 0); + cairo_rectangle(pCairo, +- twipToPixel(m_aVisibleCursor.x), +- twipToPixel(m_aVisibleCursor.y), +- twipToPixel(m_aVisibleCursor.width), +- twipToPixel(m_aVisibleCursor.height)); ++ twipToPixel(m_aVisibleCursor.x, m_fZoom), ++ twipToPixel(m_aVisibleCursor.y, m_fZoom), ++ twipToPixel(m_aVisibleCursor.width, m_fZoom), ++ twipToPixel(m_aVisibleCursor.height, m_fZoom)); + cairo_fill(pCairo); + } + +@@ -624,10 +605,10 @@ gboolean LOKDocView_Impl::renderOverlayImpl(GtkWidget* pWidget) + // Blue with 75% transparency. + cairo_set_source_rgba(pCairo, ((double)0x43)/255, ((double)0xac)/255, ((double)0xe8)/255, 0.25); + cairo_rectangle(pCairo, +- twipToPixel(rRectangle.x), +- twipToPixel(rRectangle.y), +- twipToPixel(rRectangle.width), +- twipToPixel(rRectangle.height)); ++ twipToPixel(rRectangle.x, m_fZoom), ++ twipToPixel(rRectangle.y, m_fZoom), ++ twipToPixel(rRectangle.width, m_fZoom), ++ twipToPixel(rRectangle.height, m_fZoom)); + cairo_fill(pCairo); + } + +@@ -674,10 +655,10 @@ void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, + nHandleWidth = cairo_image_surface_get_width(pHandle); + nHandleHeight = cairo_image_surface_get_height(pHandle); + // We want to scale down the handle, so that its height is the same as the cursor caret. +- fHandleScale = twipToPixel(rCursor.height) / nHandleHeight; ++ fHandleScale = twipToPixel(rCursor.height, m_fZoom) / nHandleHeight; + // We want the top center of the handle bitmap to be at the bottom center of the cursor rectangle. +- aCursorBottom.x = twipToPixel(rCursor.x) + twipToPixel(rCursor.width) / 2 - (nHandleWidth * fHandleScale) / 2; +- aCursorBottom.y = twipToPixel(rCursor.y) + twipToPixel(rCursor.height); ++ aCursorBottom.x = twipToPixel(rCursor.x, m_fZoom) + twipToPixel(rCursor.width, m_fZoom) / 2 - (nHandleWidth * fHandleScale) / 2; ++ aCursorBottom.y = twipToPixel(rCursor.y, m_fZoom) + twipToPixel(rCursor.height, m_fZoom); + cairo_save(pCairo); + cairo_translate(pCairo, aCursorBottom.x, aCursorBottom.y); + cairo_scale(pCairo, fHandleScale, fHandleScale); +@@ -700,10 +681,10 @@ void LOKDocView_Impl::renderGraphicHandle(cairo_t* pCairo, const GdkRectangle& r + nHandleWidth = cairo_image_surface_get_width(pHandle); + nHandleHeight = cairo_image_surface_get_height(pHandle); + +- aSelection.x = twipToPixel(rSelection.x); +- aSelection.y = twipToPixel(rSelection.y); +- aSelection.width = twipToPixel(rSelection.width); +- aSelection.height = twipToPixel(rSelection.height); ++ aSelection.x = twipToPixel(rSelection.x, m_fZoom); ++ aSelection.y = twipToPixel(rSelection.y, m_fZoom); ++ aSelection.width = twipToPixel(rSelection.width, m_fZoom); ++ aSelection.height = twipToPixel(rSelection.height, m_fZoom); + + for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) + { +@@ -781,8 +762,8 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + GdkRectangle visibleArea; + lok_docview_get_visarea (m_pDocView, &visibleArea); + +- long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips); +- long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips); ++ long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips, m_fZoom); ++ long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips, m_fZoom); + // Total number of rows / columns in this document. + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +@@ -809,10 +790,10 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + aTileRectanglePixels.height = nTileSizePixels; + + // Determine size and position of the tile in document coordinates, so we can decide if we can skip painting for partial rendering. +- aTileRectangleTwips.x = pixelToTwip(nTileSizePixels) * nColumn; +- aTileRectangleTwips.y = pixelToTwip(nTileSizePixels) * nRow; +- aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width); +- aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height); ++ aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, m_fZoom) * nColumn; ++ aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, m_fZoom) * nRow; ++ aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, m_fZoom); ++ aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, m_fZoom); + if (pPartial && !gdk_rectangle_intersect(pPartial, &aTileRectangleTwips, 0)) + bPaint = false; + +@@ -826,7 +807,7 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + Tile& currentTile = m_pTileBuffer->tile_buffer_get_tile(nRow, nColumn); + GdkPixbuf* pPixBuf = currentTile.tile_get_buffer(); + +- gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, twipToPixel(aTileRectangleTwips.x), twipToPixel(aTileRectangleTwips.y)); ++ gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, twipToPixel(aTileRectangleTwips.x, m_fZoom), twipToPixel(aTileRectangleTwips.y, m_fZoom)); + cairo_paint(pcairo); + } + } +@@ -935,10 +916,10 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + { + GdkRectangle aRectangle = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + GdkRectangle aRectanglePixels; +- aRectanglePixels.x = twipToPixel(aRectangle.x); +- aRectanglePixels.y = twipToPixel(aRectangle.y); +- aRectanglePixels.width = twipToPixel(aRectangle.width); +- aRectanglePixels.height = twipToPixel(aRectangle.height); ++ aRectanglePixels.x = twipToPixel(aRectangle.x, m_fZoom); ++ aRectanglePixels.y = twipToPixel(aRectangle.y, m_fZoom); ++ aRectanglePixels.width = twipToPixel(aRectangle.width, m_fZoom); ++ aRectanglePixels.height = twipToPixel(aRectangle.height, m_fZoom); + int rowStart = aRectanglePixels.y / nTileSizePixels; + int colStart = aRectanglePixels.x / nTileSizePixels; + int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; +@@ -963,10 +944,10 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + m_bCursorOverlayVisible = true; + GdkRectangle aRectanglePixels; +- aRectanglePixels.x = twipToPixel(m_aVisibleCursor.x); +- aRectanglePixels.y = twipToPixel(m_aVisibleCursor.y); +- aRectanglePixels.width = twipToPixel(m_aVisibleCursor.width); +- aRectanglePixels.height = twipToPixel(m_aVisibleCursor.height); ++ aRectanglePixels.x = twipToPixel(m_aVisibleCursor.x, m_fZoom); ++ aRectanglePixels.y = twipToPixel(m_aVisibleCursor.y, m_fZoom); ++ aRectanglePixels.width = twipToPixel(m_aVisibleCursor.width, m_fZoom); ++ aRectanglePixels.height = twipToPixel(m_aVisibleCursor.height, m_fZoom); + int rowStart = aRectanglePixels.y / nTileSizePixels; + int colStart = aRectanglePixels.x / nTileSizePixels; + int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; +@@ -1246,10 +1227,11 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, c + pDocView->m_pImpl->m_pDocument->pClass->getDocumentSize(pDocView->m_pImpl->m_pDocument, &pDocView->m_pImpl->m_nDocumentWidthTwips, &pDocView->m_pImpl->m_nDocumentHeightTwips); + g_timeout_add(600, &LOKDocView_Impl::handleTimeout, pDocView); + ++ float zoom = pDocView->m_pImpl->m_fZoom; + long nDocumentWidthTwips = pDocView->m_pImpl->m_nDocumentWidthTwips; + long nDocumentHeightTwips = pDocView->m_pImpl->m_nDocumentHeightTwips; +- long nDocumentWidthPixels = pDocView->m_pImpl->twipToPixel(nDocumentWidthTwips); +- long nDocumentHeightPixels = pDocView->m_pImpl->twipToPixel(nDocumentHeightTwips); ++ long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); ++ long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); + // Total number of rows / columns in this document. + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +@@ -1271,8 +1253,8 @@ SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_docview_get_document(LOKDocView + SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZoom ) + { + pDocView->m_pImpl->m_fZoom = fZoom; +- long nDocumentWidthPixels = pDocView->m_pImpl->twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips); +- long nDocumentHeightPixels = pDocView->m_pImpl->twipToPixel(pDocView->m_pImpl->m_nDocumentHeightTwips); ++ long nDocumentWidthPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips, fZoom); ++ long nDocumentHeightPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentHeightTwips, fZoom); + // Total number of rows / columns in this document. + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +@@ -1350,12 +1332,13 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_post_key(GtkWidget* /*pWidget*/, GdkEventK + + SAL_DLLPUBLIC_EXPORT void lok_docview_get_visarea(LOKDocView* pThis, GdkRectangle* pArea) + { ++ float zoom = pThis->m_pImpl->m_fZoom; + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pThis)); +- pArea->x = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_value(pHAdjustment)); +- pArea->width = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_page_size(pHAdjustment)); ++ pArea->x = pixelToTwip(gtk_adjustment_get_value(pHAdjustment),zoom); ++ pArea->width = pixelToTwip(gtk_adjustment_get_page_size(pHAdjustment), zoom); + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pThis)); +- pArea->y = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_value(pVAdjustment)); +- pArea->height = pThis->m_pImpl->pixelToTwip(gtk_adjustment_get_page_size(pVAdjustment)); ++ pArea->y = pixelToTwip(gtk_adjustment_get_value(pVAdjustment), zoom); ++ pArea->height = pixelToTwip(gtk_adjustment_get_page_size(pVAdjustment), zoom); + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index e13f5b034c1d..3e5e01f8d686 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -9,14 +9,12 @@ + + #include "tilebuffer.hxx" + +-static const int DPI = 96; +- +-static float pixelToTwip(float fInput, float zoom) ++float pixelToTwip(float fInput, float zoom) + { + return (fInput / DPI / zoom) * 1440.0f; + } + +-static float twipToPixel(float fInput, float zoom) ++float twipToPixel(float fInput, float zoom) + { + return fInput / 1440.0f * DPI * zoom; + } +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 088df93ca6b6..15b276f238aa 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -19,6 +19,15 @@ + #include + #include + ++// We know that VirtualDevices use a DPI of 96. ++const int DPI = 96; ++// Lets use a square of side 256 pixels for each tile. ++const int nTileSizePixels = 256; ++ ++float pixelToTwip(float fInput, float zoom); ++ ++float twipToPixel(float fInput, float zoom); ++ + /* + This class represents a single tile in the tile buffer. + TODO: Extend it to support features like double buffering +-- +2.12.0 + diff --git a/SOURCES/0016-lokdocview-wrap-a-functionality-inside-a-member-func.patch b/SOURCES/0016-lokdocview-wrap-a-functionality-inside-a-member-func.patch new file mode 100644 index 0000000..1d3202b --- /dev/null +++ b/SOURCES/0016-lokdocview-wrap-a-functionality-inside-a-member-func.patch @@ -0,0 +1,104 @@ +From d7f30799b250c8ffd3d25307e9efb5e7f13ce8b0 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 4 Jun 2015 14:15:58 +0530 +Subject: [PATCH 016/398] lokdocview: wrap a functionality inside a member + function + +Lets use a member function to set invalid tiles that come under the +given GdkRectangle. + +Change-Id: I440336ddf3c5fd9094f35bb89479aa76a42477fa +(cherry picked from commit ad0a404ef3097d92cf9a0e861e076a72074a5258) +--- + libreofficekit/source/gtk/lokdocview.cxx | 54 ++++++++++++++------------------ + 1 file changed, 24 insertions(+), 30 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index bfb414f0909c..cfa71a357f22 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -212,6 +212,8 @@ struct LOKDocView_Impl + void searchNotFound(const std::string& rPayload); + /// LOK decided to change parts, need to update UI. + void setPart(const std::string& rPayload); ++ /// Sets the tiles enclosed by rRectangle as invalid in m_pTileBuffer ++ void setTilesInvalid(const GdkRectangle& rRectangle); + }; + + namespace { +@@ -646,6 +648,26 @@ bool LOKDocView_Impl::isEmptyRectangle(const GdkRectangle& rRectangle) + return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0; + } + ++void LOKDocView_Impl::setTilesInvalid(const GdkRectangle& rRectangle) ++{ ++ GdkRectangle aRectanglePixels; ++ GdkPoint aStart, aEnd; ++ ++ aRectanglePixels.x = twipToPixel(rRectangle.x, m_fZoom); ++ aRectanglePixels.y = twipToPixel(rRectangle.y, m_fZoom); ++ aRectanglePixels.width = twipToPixel(rRectangle.width, m_fZoom); ++ aRectanglePixels.height = twipToPixel(rRectangle.height, m_fZoom); ++ ++ aStart.x = aRectanglePixels.y / nTileSizePixels; ++ aStart.y = aRectanglePixels.x / nTileSizePixels; ++ aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; ++ aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; ++ ++ for (int i = aStart.x; i < aEnd.x; i++) ++ for (int j = aStart.y; j < aEnd.y; j++) ++ m_pTileBuffer->tile_buffer_set_invalid(i, j); ++} ++ + void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle) + { + GdkPoint aCursorBottom; +@@ -915,21 +937,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + if (pCallback->m_aPayload != "EMPTY") + { + GdkRectangle aRectangle = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); +- GdkRectangle aRectanglePixels; +- aRectanglePixels.x = twipToPixel(aRectangle.x, m_fZoom); +- aRectanglePixels.y = twipToPixel(aRectangle.y, m_fZoom); +- aRectanglePixels.width = twipToPixel(aRectangle.width, m_fZoom); +- aRectanglePixels.height = twipToPixel(aRectangle.height, m_fZoom); +- int rowStart = aRectanglePixels.y / nTileSizePixels; +- int colStart = aRectanglePixels.x / nTileSizePixels; +- int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; +- int colEnd = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; +- int i,j; +- for (i = rowStart; i < rowEnd; i++) { +- for (j = colStart; j < colEnd; j++) { +- m_pTileBuffer->tile_buffer_set_invalid(i, j); +- } +- } ++ setTilesInvalid(aRectangle); + renderDocument(0); + } + else +@@ -943,21 +951,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + { + m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + m_bCursorOverlayVisible = true; +- GdkRectangle aRectanglePixels; +- aRectanglePixels.x = twipToPixel(m_aVisibleCursor.x, m_fZoom); +- aRectanglePixels.y = twipToPixel(m_aVisibleCursor.y, m_fZoom); +- aRectanglePixels.width = twipToPixel(m_aVisibleCursor.width, m_fZoom); +- aRectanglePixels.height = twipToPixel(m_aVisibleCursor.height, m_fZoom); +- int rowStart = aRectanglePixels.y / nTileSizePixels; +- int colStart = aRectanglePixels.x / nTileSizePixels; +- int rowEnd = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; +- int colEnd = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; +- int i,j; +- for (i = rowStart; i < rowEnd; i++) { +- for (j = colStart; j < colEnd; j++) { +- m_pTileBuffer->tile_buffer_set_invalid(i, j); +- } +- } ++ setTilesInvalid(m_aVisibleCursor); + renderDocument(0); + } + break; +-- +2.12.0 + diff --git a/SOURCES/0017-lokdocview-tilebuffer-clean-up.patch b/SOURCES/0017-lokdocview-tilebuffer-clean-up.patch new file mode 100644 index 0000000..1c5a535 --- /dev/null +++ b/SOURCES/0017-lokdocview-tilebuffer-clean-up.patch @@ -0,0 +1,460 @@ +From 0ad2976627386e126ae310d85aa6d771b3df1353 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 4 Jun 2015 22:09:57 +0530 +Subject: [PATCH 017/398] lokdocview, tilebuffer: clean up + +Improve documentation, style fixes + +Change-Id: I5000e32e90cd8e3b75e8df2907673efc303a55fd +(cherry picked from commit c074cfa4d48736d1703949ccfe1a6c534a2742ae) +--- + libreofficekit/source/gtk/lokdocview.cxx | 59 ++++++++++------- + libreofficekit/source/gtk/tilebuffer.cxx | 104 +++++++++++++++++------------- + libreofficekit/source/gtk/tilebuffer.hxx | 107 +++++++++++++++++++++++++------ + 3 files changed, 182 insertions(+), 88 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index cfa71a357f22..2181dc9a21b1 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1,4 +1,4 @@ +-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + /* + * This file is part of the LibreOffice project. + * +@@ -177,12 +177,12 @@ struct LOKDocView_Impl + /// Implementation of the timeout handler, invoked by handleTimeout(). + gboolean handleTimeoutImpl(); + /** +- * Renders the document to a number of tiles. ++ * Renders the document to a number of visible tiles. + * + * This method is invoked only manually, not when some Gtk signal is + * emitted. + * +- * @param pPartial if 0, then the full document is rendered, otherwise only ++ * @param pPartial if 0, then the full visible document is rendered, otherwise only + * the tiles that intersect with pPartial. + */ + void renderDocument(GdkRectangle* pPartial); +@@ -665,7 +665,7 @@ void LOKDocView_Impl::setTilesInvalid(const GdkRectangle& rRectangle) + + for (int i = aStart.x; i < aEnd.x; i++) + for (int j = aStart.y; j < aEnd.y; j++) +- m_pTileBuffer->tile_buffer_set_invalid(i, j); ++ m_pTileBuffer->setInvalid(i, j); + } + + void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle) +@@ -801,7 +801,8 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + GdkRectangle aTileRectangleTwips, aTileRectanglePixels; + bool bPaint = true; + +- // Determine size of the tile: the rightmost/bottommost tiles may be smaller and we need the size to decide if we need to repaint. ++ // Determine size of the tile: the rightmost/bottommost tiles may ++ // be smaller, and we need the size to decide if we need to repaint. + if (nColumn == nColumns - 1) + aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels; + else +@@ -811,7 +812,8 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + else + aTileRectanglePixels.height = nTileSizePixels; + +- // Determine size and position of the tile in document coordinates, so we can decide if we can skip painting for partial rendering. ++ // Determine size and position of the tile in document coordinates, ++ // so we can decide if we can skip painting for partial rendering. + aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, m_fZoom) * nColumn; + aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, m_fZoom) * nRow; + aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, m_fZoom); +@@ -824,12 +826,14 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + + if (bPaint) + { +- // g_info("gettile: (%d %d)", nRow, nColumn); ++ g_info("tile_buffer_get_tile (%d, %d)", nRow, nColumn); + +- Tile& currentTile = m_pTileBuffer->tile_buffer_get_tile(nRow, nColumn); +- GdkPixbuf* pPixBuf = currentTile.tile_get_buffer(); ++ Tile& currentTile = m_pTileBuffer->getTile(nRow, nColumn); ++ GdkPixbuf* pPixBuf = currentTile.getBuffer(); + +- gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, twipToPixel(aTileRectangleTwips.x, m_fZoom), twipToPixel(aTileRectangleTwips.y, m_fZoom)); ++ gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, ++ twipToPixel(aTileRectangleTwips.x, m_fZoom), ++ twipToPixel(aTileRectangleTwips.y, m_fZoom)); + cairo_paint(pcairo); + } + } +@@ -942,7 +946,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + } + else + { +- m_pTileBuffer->tile_buffer_reset_all_tiles(); ++ m_pTileBuffer->resetAllTiles(); + renderDocument(0); + } + } +@@ -1148,21 +1152,28 @@ static void lok_docview_init( GTypeInstance* pInstance, gpointer ) + gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView), + pDocView->m_pImpl->m_pDrawingArea ); + +- g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + "expose-event", +- GTK_SIGNAL_FUNC(LOKDocView_Impl::on_exposed), pDocView); +- g_signal_connect(GTK_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ G_CALLBACK(LOKDocView_Impl::on_exposed), pDocView); ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), + "expose-event", +- GTK_SIGNAL_FUNC(LOKDocView_Impl::renderOverlay), pDocView); ++ G_CALLBACK(LOKDocView_Impl::renderOverlay), pDocView); + gtk_widget_add_events(pDocView->m_pImpl->m_pDrawingArea, +- GDK_BUTTON_PRESS_MASK +- | GDK_BUTTON_RELEASE_MASK +- | GDK_BUTTON_MOTION_MASK); +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-press-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "button-release-event", G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), "motion-notify-event", G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView); +- +- gtk_signal_connect(GTK_OBJECT(pDocView), "destroy", GTK_SIGNAL_FUNC(LOKDocView_Impl::destroy), 0); ++ GDK_BUTTON_PRESS_MASK ++ |GDK_BUTTON_RELEASE_MASK ++ |GDK_BUTTON_MOTION_MASK); ++ ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ "button-press-event", ++ G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ "button-release-event", ++ G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); ++ g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ "motion-notify-event", ++ G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView); ++ ++ g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0); + } + + SAL_DLLPUBLIC_EXPORT guint lok_docview_get_type() +@@ -1253,7 +1264,7 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZo + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- pDocView->m_pImpl->m_pTileBuffer->tile_buffer_set_zoom(fZoom, nRows, nColumns); ++ pDocView->m_pImpl->m_pTileBuffer->setZoom(fZoom, nRows, nColumns); + + if ( pDocView->m_pImpl->m_pDocument ) + pDocView->m_pImpl->renderDocument(0); +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 3e5e01f8d686..338038078ab3 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -1,4 +1,4 @@ +-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + /* + * This file is part of the LibreOffice project. + * +@@ -9,6 +9,10 @@ + + #include "tilebuffer.hxx" + ++/* ------------------ ++ Utility functions ++ ------------------ ++*/ + float pixelToTwip(float fInput, float zoom) + { + return (fInput / DPI / zoom) * 1440.0f; +@@ -19,84 +23,96 @@ float twipToPixel(float fInput, float zoom) + return fInput / 1440.0f * DPI * zoom; + } + +-GdkPixbuf* Tile::tile_get_buffer() ++/* ---------------------------- ++ Tile class member functions ++ ---------------------------- ++*/ ++GdkPixbuf* Tile::getBuffer() + { + return m_pBuffer; + } + +-void Tile::tile_release() ++void Tile::release() + { + g_object_unref (m_pBuffer); + m_pBuffer = NULL; + } + +-void TileBuffer::tile_buffer_set_zoom(float newZoomFactor, int rows, int columns) ++void Tile::setPixbuf(GdkPixbuf *buffer) ++{ ++ m_pBuffer = buffer; ++} ++ ++/* ---------------------------------- ++ TileBuffer class member functions ++ ---------------------------------- ++*/ ++void TileBuffer::setZoom(float newZoomFactor, int rows, int columns) + { + m_fZoomFactor = newZoomFactor; + +- tile_buffer_reset_all_tiles(); ++ resetAllTiles(); + + // set new buffer width and height + m_nWidth = columns; + m_nHeight = rows; + } + +-void TileBuffer::tile_buffer_reset_all_tiles() ++void TileBuffer::resetAllTiles() + { + std::map::iterator it = m_mTiles.begin(); + for (; it != m_mTiles.end(); it++) +- { +- it->second.tile_release(); +- } ++ { ++ it->second.release(); ++ } + m_mTiles.clear(); + } + +-void TileBuffer::tile_buffer_set_invalid(int x, int y) ++void TileBuffer::setInvalid(int x, int y) + { + int index = x * m_nWidth + y; +- g_info("setting invalid : %d %d",x, y); ++ g_info("Setting tile invalid (%d, %d)", x, y); + if (m_mTiles.find(index) != m_mTiles.end()) +- { +- m_mTiles[index].valid = 0; +- m_mTiles[index].tile_release(); +- m_mTiles.erase(index); +- } ++ { ++ m_mTiles[index].valid = 0; ++ m_mTiles[index].release(); ++ m_mTiles.erase(index); ++ } + } + +-Tile& TileBuffer::tile_buffer_get_tile(int x, int y) ++Tile& TileBuffer::getTile(int x, int y) + { + int index = x * m_nWidth + y; + if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[index].valid) +- { ++ { + +- GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); +- if (!pPixBuf){ +- g_info ("error allocating memory to pixbuf"); +- } +- unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); +- GdkRectangle aTileRectangle; +- aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y; +- aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x; +- +- g_info ("rendering (%d %d)", x, y); +- m_pLOKDocument->pClass->paintTile(m_pLOKDocument, +- // Buffer and its size, depends on the position only. +- pBuffer, +- m_nTileSize, m_nTileSize, +- // Position of the tile. +- aTileRectangle.x, aTileRectangle.y, +- // Size of the tile, depends on the zoom factor and the tile position only. +- pixelToTwip(m_nTileSize, m_fZoomFactor), pixelToTwip(m_nTileSize, m_fZoomFactor)); +- +- //create a mapping for it +- m_mTiles[index].tile_set_pixbuf(pPixBuf); +- m_mTiles[index].valid = 1; ++ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); ++ if (!pPixBuf) ++ { ++ g_info ("Error allocating memory to pixbuf"); ++ return m_mTiles[index]; + } + ++ unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); ++ GdkRectangle aTileRectangle; ++ aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y; ++ aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x; ++ ++ g_info ("Rendering (%d, %d)", x, y); ++ m_pLOKDocument->pClass->paintTile(m_pLOKDocument, ++ pBuffer, ++ m_nTileSize, m_nTileSize, ++ aTileRectangle.x, aTileRectangle.y, ++ pixelToTwip(m_nTileSize, m_fZoomFactor), ++ pixelToTwip(m_nTileSize, m_fZoomFactor)); ++ ++ //create a mapping for it ++ m_mTiles[index].setPixbuf(pPixBuf); ++ m_mTiles[index].valid = 1; ++ } ++ + return m_mTiles[index]; + } + +-void Tile::tile_set_pixbuf(GdkPixbuf *buffer) +-{ +- m_pBuffer = buffer; +-} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 15b276f238aa..7e2132f4d512 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -1,4 +1,4 @@ +-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + /* + * This file is part of the LibreOffice project. + * +@@ -24,32 +24,60 @@ const int DPI = 96; + // Lets use a square of side 256 pixels for each tile. + const int nTileSizePixels = 256; + ++/** ++ Converts the pixel value to zoom independent twip value. ++ ++ @param fInput value to convert ++ @param zoom the current zoom level ++ ++ @return the pixels value corresponding to given twip value ++*/ + float pixelToTwip(float fInput, float zoom); + ++/** ++ Converts the zoom independent twip value pixel value. ++ ++ @param fInput value to convert ++ @param zoom the current zoom level ++ ++ @return the twip value corresponding to given pixel value ++*/ + float twipToPixel(float fInput, float zoom); + +-/* +- This class represents a single tile in the tile buffer. +- TODO: Extend it to support features like double buffering ++/** ++ This class represents a single tile in the tile buffer. ++ It encloses a reference to GdkPixBuf containing the pixel data of the tile. + */ + class Tile + { + public: +- Tile() : valid(0) {} +- ~Tile() { +- } ++ Tile() : valid(0) {} ++ ~Tile() { } + +- GdkPixbuf* tile_get_buffer(); +- void tile_release(); +- void tile_set_pixbuf(GdkPixbuf*); ++ /** ++ Tells if this tile is valid or not. Initialised to 0 (invalid) during ++ object creation. ++ */ + bool valid; +- private: ++ ++ /// Function to get the pointer to enclosing GdkPixbuf ++ GdkPixbuf* getBuffer(); ++ /// Destroys the enclosing GdkPixbuf object pointed to by m_pBuffer ++ void release(); ++ /// Used to set the pixel buffer of this object ++ void setPixbuf(GdkPixbuf*); ++ ++private: ++ /// Pixel buffer data for this tile + GdkPixbuf *m_pBuffer; + }; + +-/* +- TileBuffer is the buffer caching all the recently rendered tiles. +- The buffer is set to invalid when zoom factor changes. ++/** ++ This class represents the tile buffer which is responsible for managing, ++ reusing and caching all the already rendered tiles. If the given tile is not ++ present in the buffer, call to LOK Document's (m_pLOKDocument) paintTile ++ method is made which fetches the rendered tile from LO core and store it in ++ buffer for future reuse. + */ + class TileBuffer + { +@@ -67,19 +95,58 @@ class TileBuffer + + ~TileBuffer() {} + +- void tile_buffer_set_zoom(float zoomFactor, int rows, int columns); +- Tile& tile_buffer_get_tile(int x, int y); +- void tile_buffer_update(); +- void tile_buffer_reset_all_tiles(); +- void tile_buffer_set_invalid(int x, int y); ++ /** ++ Sets the zoom factor (m_fZoomFactor) for this tile buffer. Setting the ++ zoom factor invalidates whole of the tile buffer, destroys all tiles ++ contained within it, and sets new width, height values for tile ++ buffer. The width, height value of tile buffer is the width and height of ++ the table containing all possible tiles (rendered and non-rendered) that ++ this buffer can have. ++ ++ @param zoomFactor the new zoom factor value to set ++ */ ++ void setZoom(float zoomFactor, int rows, int columns); ++ /** ++ Gets the underlying Tile object for given position. The position (0, 0) ++ points to the left top most tile of the buffer. ++ ++ If the tile is not cached by the tile buffer, it makes a paintTile call ++ to LO core asking to render the given tile. It then stores the tile for ++ future reuse. ++ ++ @param x the tile along the x-axis of the buffer ++ @param y the tile along the y-axis of the buffer ++ ++ @return the tile at the mentioned position (x, y) ++ */ ++ Tile& getTile(int x, int y); ++ /// Destroys all the tiles in the tile buffer; also frees the memory allocated ++ /// for all the Tile objects. ++ void resetAllTiles(); ++ /** ++ Marks the tile as invalid. The tile (0, 0) is the left topmost tile in ++ the tile buffer. ++ ++ @param x the position of tile along x-axis ++ @param y the position of tile along y-axis ++ */ ++ void setInvalid(int x, int y); ++ + private: ++ /// Contains the reference to the LOK Document that this tile buffer is for. + LibreOfficeKitDocument *m_pLOKDocument; ++ /// The side of each squared tile in pixels. + int m_nTileSize; ++ /// The zoom factor that the tile buffer is currently rendered to. + float m_fZoomFactor; ++ /// Stores all the tiles cached by this tile buffer. + std::map m_mTiles; +- //TODO: Also set width and height when document size changes ++ /// Width of the current tile buffer (number of columns) + int m_nWidth; ++ /// Height of the current tile buffer (numbero of rows) + int m_nHeight; + }; + + #endif // INCLUDED_TILEBUFFER_HXX ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0018-lokdocview-fixed-rectangle-format-in-documentation-c.patch b/SOURCES/0018-lokdocview-fixed-rectangle-format-in-documentation-c.patch new file mode 100644 index 0000000..7419bbd --- /dev/null +++ b/SOURCES/0018-lokdocview-fixed-rectangle-format-in-documentation-c.patch @@ -0,0 +1,31 @@ +From 85532b0dc16409922bcb6b1f7193e59e8d5add56 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 5 Jun 2015 17:05:28 +0530 +Subject: [PATCH 018/398] lokdocview: fixed rectangle format in + documentation/comments + +Change-Id: Iaf4a5fba5c4c34d03b91ca9ca4dd4eff1dbf39f6 +(cherry picked from commit f4278176b031f0588269599ba8b59aa6ebbb9464) +--- + libreofficekit/source/gtk/lokdocview.cxx | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 2181dc9a21b1..48b3ed6e2080 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -186,9 +186,9 @@ struct LOKDocView_Impl + * the tiles that intersect with pPartial. + */ + void renderDocument(GdkRectangle* pPartial); +- /// Returns the GdkRectangle of a width,height,x,y string. ++ /// Returns the GdkRectangle of a x,y,width,height string. + static GdkRectangle payloadToRectangle(const char* pPayload); +- /// Returns the GdkRectangles of a w,h,x,y;w2,h2,x2,y2;... string. ++ /// Returns the GdkRectangles of a x1,y1,w1,h1;x2,y2,w2,h2;... string. + static std::vector payloadToRectangles(const char* pPayload); + /// Returns the string representation of a LibreOfficeKitCallbackType enumeration element. + static const char* callbackTypeToString(int nType); +-- +2.12.0 + diff --git a/SOURCES/0019-lokdocview-check-payload-for-inconsistencies-before-.patch b/SOURCES/0019-lokdocview-check-payload-for-inconsistencies-before-.patch new file mode 100644 index 0000000..aeb3080 --- /dev/null +++ b/SOURCES/0019-lokdocview-check-payload-for-inconsistencies-before-.patch @@ -0,0 +1,65 @@ +From b049bfd09192d01aa5dcbc48975cf9eb3e1997b9 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 5 Jun 2015 17:06:54 +0530 +Subject: [PATCH 019/398] lokdocview: check payload for inconsistencies before + using it + +Lets follow the old advice: "Be liberal in what you accept, be strict in +what you produce". + +This is after noticing negative values for x, y in +the payload in some situation, such as, hitting a backspace key when the +cursor is at the start of a line + +Change-Id: I11939b981f75969b88214baee66b4c69c5e41906 +(cherry picked from commit 35e03615066a6525e0259ff1823a0da0c2d4820a) +--- + libreofficekit/source/gtk/lokdocview.cxx | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 48b3ed6e2080..d9e8c14aa9d5 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -187,9 +187,9 @@ struct LOKDocView_Impl + */ + void renderDocument(GdkRectangle* pPartial); + /// Returns the GdkRectangle of a x,y,width,height string. +- static GdkRectangle payloadToRectangle(const char* pPayload); ++ GdkRectangle payloadToRectangle(const char* pPayload); + /// Returns the GdkRectangles of a x1,y1,w1,h1;x2,y2,w2,h2;... string. +- static std::vector payloadToRectangles(const char* pPayload); ++ std::vector payloadToRectangles(const char* pPayload); + /// Returns the string representation of a LibreOfficeKitCallbackType enumeration element. + static const char* callbackTypeToString(int nType); + /// Invoked on the main thread if callbackWorker() requests so. +@@ -853,18 +853,26 @@ GdkRectangle LOKDocView_Impl::payloadToRectangle(const char* pPayload) + if (!*ppCoordinate) + return aRet; + aRet.x = atoi(*ppCoordinate); ++ if (aRet.x < 0) ++ aRet.x = 0; + ++ppCoordinate; + if (!*ppCoordinate) + return aRet; + aRet.y = atoi(*ppCoordinate); ++ if (aRet.y < 0) ++ aRet.y = 0; + ++ppCoordinate; + if (!*ppCoordinate) + return aRet; + aRet.width = atoi(*ppCoordinate); ++ if (aRet.x + aRet.width > m_nDocumentWidthTwips) ++ aRet.width = m_nDocumentWidthTwips - aRet.x; + ++ppCoordinate; + if (!*ppCoordinate) + return aRet; + aRet.height = atoi(*ppCoordinate); ++ if (aRet.y + aRet.height > m_nDocumentHeightTwips) ++ aRet.height = m_nDocumentHeightTwips - aRet.y; + g_strfreev(ppCoordinates); + return aRet; + } +-- +2.12.0 + diff --git a/SOURCES/0020-lokdocview-move-GtkDrawingArea-size-request-out-of-r.patch b/SOURCES/0020-lokdocview-move-GtkDrawingArea-size-request-out-of-r.patch new file mode 100644 index 0000000..2acdd7d --- /dev/null +++ b/SOURCES/0020-lokdocview-move-GtkDrawingArea-size-request-out-of-r.patch @@ -0,0 +1,69 @@ +From 71ce3c4cc6e973d252f6db0a22c01670d9fc571f Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 5 Jun 2015 20:38:55 +0530 +Subject: [PATCH 020/398] lokdocview: move GtkDrawingArea size request out of + renderDocument() + +... and place it at places only where the widget can change its size. + +Change-Id: I4a4b28b35eba06a6faab434677d4d70d2a33339a +(cherry picked from commit 1483643ba5930474b9eab73b723a775dd3c8c850) +--- + libreofficekit/source/gtk/lokdocview.cxx | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d9e8c14aa9d5..42dd14cb34ed 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -790,7 +790,6 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- gtk_widget_set_size_request(m_pDrawingArea, nDocumentWidthPixels, nDocumentHeightPixels); + cairo_t *pcairo = gdk_cairo_create(m_pDrawingArea->window); + + // Render the tiles. +@@ -826,7 +825,7 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + + if (bPaint) + { +- g_info("tile_buffer_get_tile (%d, %d)", nRow, nColumn); ++ //g_info("tile_buffer_get_tile (%d, %d)", nRow, nColumn); + + Tile& currentTile = m_pTileBuffer->getTile(nRow, nColumn); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); +@@ -1028,6 +1027,10 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + { + payloadToSize(pCallback->m_aPayload.c_str(), m_nDocumentWidthTwips, m_nDocumentHeightTwips); ++ gtk_widget_set_size_request(m_pDrawingArea, ++ twipToPixel(m_nDocumentWidthTwips, m_fZoom), ++ twipToPixel(m_nDocumentHeightTwips, m_fZoom)); ++ m_pTileBuffer->resetAllTiles(); + } + break; + case LOK_CALLBACK_SET_PART: +@@ -1252,6 +1255,9 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, c + nTileSizePixels, + nRows, + nColumns); ++ gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, ++ nDocumentWidthPixels, ++ nDocumentHeightPixels); + pDocView->m_pImpl->renderDocument(0); + } + +@@ -1273,6 +1279,9 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZo + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + + pDocView->m_pImpl->m_pTileBuffer->setZoom(fZoom, nRows, nColumns); ++ gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, ++ nDocumentWidthPixels, ++ nDocumentHeightPixels); + + if ( pDocView->m_pImpl->m_pDocument ) + pDocView->m_pImpl->renderDocument(0); +-- +2.12.0 + diff --git a/SOURCES/0021-lokdocview-fix-render-calls-after-LOK-callbacks.patch b/SOURCES/0021-lokdocview-fix-render-calls-after-LOK-callbacks.patch new file mode 100644 index 0000000..9140e58 --- /dev/null +++ b/SOURCES/0021-lokdocview-fix-render-calls-after-LOK-callbacks.patch @@ -0,0 +1,51 @@ +From 0dec0cdd711d87ec1741b4b66e8060d2f13a4496 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 6 Jun 2015 00:36:54 +0530 +Subject: [PATCH 021/398] lokdocview: fix render calls after LOK callbacks + +Change-Id: Ib33f0e1dcf257350be1e2cf6c49cd92494472a55 +(cherry picked from commit 085f31a435eed43e3b7927e10309ddd00fb5b9a5) +--- + libreofficekit/source/gtk/lokdocview.cxx | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 42dd14cb34ed..6c3176783953 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -949,21 +949,18 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + { + GdkRectangle aRectangle = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + setTilesInvalid(aRectangle); +- renderDocument(0); + } + else +- { + m_pTileBuffer->resetAllTiles(); +- renderDocument(0); +- } ++ ++ gtk_widget_queue_draw(m_pDrawingArea); + } + break; + case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: + { + m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + m_bCursorOverlayVisible = true; +- setTilesInvalid(m_aVisibleCursor); +- renderDocument(0); ++ gtk_widget_queue_draw(m_pDrawingArea); + } + break; + case LOK_CALLBACK_TEXT_SELECTION: +@@ -1030,7 +1027,6 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + gtk_widget_set_size_request(m_pDrawingArea, + twipToPixel(m_nDocumentWidthTwips, m_fZoom), + twipToPixel(m_nDocumentHeightTwips, m_fZoom)); +- m_pTileBuffer->resetAllTiles(); + } + break; + case LOK_CALLBACK_SET_PART: +-- +2.12.0 + diff --git a/SOURCES/0022-lokdocview-Let-G_BEGIN-END_DECLS-handle-the-compiler.patch b/SOURCES/0022-lokdocview-Let-G_BEGIN-END_DECLS-handle-the-compiler.patch new file mode 100644 index 0000000..b513c24 --- /dev/null +++ b/SOURCES/0022-lokdocview-Let-G_BEGIN-END_DECLS-handle-the-compiler.patch @@ -0,0 +1,43 @@ +From 0cb9d5c152804c2cdcd173acb99d7870912d6f26 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 6 Jun 2015 02:07:31 +0530 +Subject: [PATCH 022/398] lokdocview: Let G_BEGIN/END_DECLS handle the compiler + check + +Change-Id: I8c60c9ba13516fc2b3a926c19b41ee19805d74a5 +(cherry picked from commit 1493e66bfbceb2e57d069c0a0dbcfa64f7043da9) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index b3e50d31b01d..9668904b0230 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -16,10 +16,7 @@ + #define LOK_USE_UNSTABLE_API + #include + +-#ifdef __cplusplus +-extern "C" +-{ +-#endif ++G_BEGIN_DECLS + + #define LOK_DOCVIEW(obj) GTK_CHECK_CAST (obj, lok_docview_get_type(), LOKDocView) + #define LOK_DOCVIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, lok_docview_get_type(), LOKDocViewClass) +@@ -77,9 +74,8 @@ void lok_docview_post_key (GtkWidget* pWidget, GdkEventKey* pEvent + + /// Get the visible area of the document (in twips). + void lok_docview_get_visarea(LOKDocView* pThis, GdkRectangle* pArea); +-#ifdef __cplusplus +-} +-#endif ++ ++G_END_DECLS + + #endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITGTK_H + +-- +2.12.0 + diff --git a/SOURCES/0023-lokdocview-Lets-follow-the-GObject-naming-convention.patch b/SOURCES/0023-lokdocview-Lets-follow-the-GObject-naming-convention.patch new file mode 100644 index 0000000..ee51df8 --- /dev/null +++ b/SOURCES/0023-lokdocview-Lets-follow-the-GObject-naming-convention.patch @@ -0,0 +1,537 @@ +From 414256913a71a94430f53f34093c75740754e037 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 6 Jun 2015 02:32:54 +0530 +Subject: [PATCH 023/398] lokdocview: Lets follow the GObject naming convention + +If we are mentioning this type as DocView, we should break it at each +capital letter. + +Change-Id: I76c7eea455281e541b2196a03778018aa127cebe +(cherry picked from commit c8caa803b43d7091318f1129b7b4cc7ee417c336) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 38 +++++----- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 52 +++++++------- + libreofficekit/source/gtk/lokdocview.cxx | 84 +++++++++++----------- + 3 files changed, 87 insertions(+), 87 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 9668904b0230..069c565435bb 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -18,9 +18,9 @@ + + G_BEGIN_DECLS + +-#define LOK_DOCVIEW(obj) GTK_CHECK_CAST (obj, lok_docview_get_type(), LOKDocView) +-#define LOK_DOCVIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, lok_docview_get_type(), LOKDocViewClass) +-#define IS_LOK_DOCVIEW(obj) GTK_CHECK_TYPE (obj, lok_docview_get_type()) ++#define LOK_DOC_VIEW(obj) GTK_CHECK_CAST (obj, lok_doc_view_get_type(), LOKDocView) ++#define LOK_DOC_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, lok_doc_view_get_type(), LOKDocViewClass) ++#define IS_LOK_DOC_VIEW(obj) GTK_CHECK_TYPE (obj, lok_doc_view_get_type()) + + typedef struct _LOKDocView LOKDocView; + typedef struct _LOKDocViewClass LOKDocViewClass; +@@ -40,40 +40,40 @@ struct _LOKDocViewClass + void (* part_changed) (LOKDocView* pView, int new_part); + }; + +-guint lok_docview_get_type (void); +-GtkWidget* lok_docview_new ( LibreOfficeKit* pOffice ); +-gboolean lok_docview_open_document (LOKDocView* pDocView, ++guint lok_doc_view_get_type (void); ++GtkWidget* lok_doc_view_new ( LibreOfficeKit* pOffice ); ++gboolean lok_doc_view_open_document (LOKDocView* pDocView, + char* pPath); + + /// Gets the document the viewer displays. +-LibreOfficeKitDocument* lok_docview_get_document(LOKDocView* pDocView); ++LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocView* pDocView); + +-void lok_docview_set_zoom (LOKDocView* pDocView, ++void lok_doc_view_set_zoom (LOKDocView* pDocView, + float fZoom); +-float lok_docview_get_zoom (LOKDocView* pDocView); ++float lok_doc_view_get_zoom (LOKDocView* pDocView); + +-int lok_docview_get_parts (LOKDocView* pDocView); +-int lok_docview_get_part (LOKDocView* pDocView); +-void lok_docview_set_part (LOKDocView* pDocView, ++int lok_doc_view_get_parts (LOKDocView* pDocView); ++int lok_doc_view_get_part (LOKDocView* pDocView); ++void lok_doc_view_set_part (LOKDocView* pDocView, + int nPart); +-char* lok_docview_get_part_name (LOKDocView* pDocView, ++char* lok_doc_view_get_part_name (LOKDocView* pDocView, + int nPart); +-void lok_docview_set_partmode (LOKDocView* pDocView, ++void lok_doc_view_set_partmode (LOKDocView* pDocView, + int nPartMode); + /// Sets if the viewer is actually an editor or not. +-void lok_docview_set_edit (LOKDocView* pDocView, ++void lok_doc_view_set_edit (LOKDocView* pDocView, + gboolean bEdit); + /// Gets if the viewer is actually an editor or not. +-gboolean lok_docview_get_edit (LOKDocView* pDocView); ++gboolean lok_doc_view_get_edit (LOKDocView* pDocView); + + /// Posts the .uno: command to the LibreOfficeKit. +-void lok_docview_post_command (LOKDocView* pDocView, const char* pCommand, const char* pArguments); ++void lok_doc_view_post_command (LOKDocView* pDocView, const char* pCommand, const char* pArguments); + + /// Posts a keyboard event to LibreOfficeKit. +-void lok_docview_post_key (GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData); ++void lok_doc_view_post_key (GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData); + + /// Get the visible area of the document (in twips). +-void lok_docview_get_visarea(LOKDocView* pThis, GdkRectangle* pArea); ++void lok_doc_view_get_visarea(LOKDocView* pThis, GdkRectangle* pArea); + + G_END_DECLS + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index d20f43d90627..38b29ee40a3b 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -71,7 +71,7 @@ static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + + if ( pDocView ) + { +- fCurrentZoom = lok_docview_get_zoom( LOK_DOCVIEW(pDocView) ); ++ fCurrentZoom = lok_doc_view_get_zoom( LOK_DOC_VIEW(pDocView) ); + } + + if ( strcmp(sName, "gtk-zoom-in") == 0) +@@ -104,7 +104,7 @@ static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + { + if ( pDocView ) + { +- lok_docview_set_zoom( LOK_DOCVIEW(pDocView), fZoom ); ++ lok_doc_view_set_zoom( LOK_DOC_VIEW(pDocView), fZoom ); + } + } + } +@@ -112,10 +112,10 @@ static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + /// User clicked on the button -> inform LOKDocView. + static void toggleEditing(GtkWidget* /*pButton*/, gpointer /*pItem*/) + { +- LOKDocView* pLOKDocView = LOK_DOCVIEW(pDocView); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); + bool bActive = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pEnableEditing)); +- if (bool(lok_docview_get_edit(pLOKDocView)) != bActive) +- lok_docview_set_edit(pLOKDocView, bActive); ++ if (bool(lok_doc_view_get_edit(pLOKDocView)) != bActive) ++ lok_doc_view_set_edit(pLOKDocView, bActive); + } + + /// Toggle the visibility of the findbar. +@@ -137,11 +137,11 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + /// Handles the key-press-event of the window. + static gboolean signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData) + { +- LOKDocView* pLOKDocView = LOK_DOCVIEW(pDocView); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); + #if GTK_CHECK_VERSION(2,18,0) // we need gtk_widget_get_visible() +- if (!gtk_widget_get_visible(pFindbar) && bool(lok_docview_get_edit(pLOKDocView))) ++ if (!gtk_widget_get_visible(pFindbar) && bool(lok_doc_view_get_edit(pLOKDocView))) + { +- lok_docview_post_key(pWidget, pEvent, pData); ++ lok_doc_view_post_key(pWidget, pEvent, pData); + return TRUE; + } + #endif +@@ -159,9 +159,9 @@ static void doSearch(bool bBackwards) + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards); + +- LOKDocView* pLOKDocView = LOK_DOCVIEW(pDocView); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); + GdkRectangle aArea; +- lok_docview_get_visarea(pLOKDocView, &aArea); ++ lok_doc_view_get_visarea(pLOKDocView, &aArea); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/type", '/'), "long"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/value", '/'), aArea.x); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/type", '/'), "long"); +@@ -170,7 +170,7 @@ static void doSearch(bool bBackwards) + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + +- lok_docview_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str()); ++ lok_doc_view_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str()); + } + + /// Click handler for the search next button. +@@ -210,8 +210,8 @@ static gboolean signalFindbar(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpoin + /// LOKDocView changed edit state -> inform the tool button. + static void signalEdit(LOKDocView* pLOKDocView, gboolean bWasEdit, gpointer /*pData*/) + { +- gboolean bEdit = lok_docview_get_edit(pLOKDocView); +- g_info("signalEdit: %d -> %d", bWasEdit, lok_docview_get_edit(pLOKDocView)); ++ gboolean bEdit = lok_doc_view_get_edit(pLOKDocView); ++ g_info("signalEdit: %d -> %d", bWasEdit, lok_doc_view_get_edit(pLOKDocView)); + if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pEnableEditing)) != bEdit) + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(pEnableEditing), bEdit); + } +@@ -233,7 +233,7 @@ static void signalCommand(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer + gboolean bEdit = aValue == "true"; + if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pItem)) != bEdit) + { +- // Avoid invoking lok_docview_post_command(). ++ // Avoid invoking lok_doc_view_post_command(). + g_bToolItemBroadcast = false; + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(pItem), bEdit); + g_bToolItemBroadcast = true; +@@ -262,11 +262,11 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + { + if (g_bToolItemBroadcast) + { +- LOKDocView* pLOKDocView = LOK_DOCVIEW(pDocView); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); + GtkToolItem* pItem = GTK_TOOL_ITEM(pWidget); + const std::string& rString = g_aToolItemCommandNames[pItem]; +- g_info("toggleToolItem: lok_docview_post_command('%s')", rString.c_str()); +- lok_docview_post_command(pLOKDocView, rString.c_str(), 0); ++ g_info("toggleToolItem: lok_doc_view_post_command('%s')", rString.c_str()); ++ lok_doc_view_post_command(pLOKDocView, rString.c_str(), 0); + } + } + +@@ -286,10 +286,10 @@ static void populatePartSelector() + const int nMaxLength = 50; + char sText[nMaxLength]; + +- int nParts = lok_docview_get_parts( LOK_DOCVIEW(pDocView) ); ++ int nParts = lok_doc_view_get_parts( LOK_DOC_VIEW(pDocView) ); + for ( int i = 0; i < nParts; i++ ) + { +- char* pName = lok_docview_get_part_name( LOK_DOCVIEW(pDocView), i ); ++ char* pName = lok_doc_view_get_part_name( LOK_DOC_VIEW(pDocView), i ); + assert( pName ); + snprintf( sText, nMaxLength, "%i (%s)", i+1, pName ); + free( pName ); +@@ -297,7 +297,7 @@ static void populatePartSelector() + gtk_combo_box_text_append_text( pPartSelector, sText ); + } + gtk_combo_box_set_active( GTK_COMBO_BOX(pPartSelector), +- lok_docview_get_part( LOK_DOCVIEW(pDocView) ) ); ++ lok_doc_view_get_part( LOK_DOC_VIEW(pDocView) ) ); + } + + static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) +@@ -306,7 +306,7 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + + if (g_bPartSelectorBroadcast && pDocView) + { +- lok_docview_set_part( LOK_DOCVIEW(pDocView), nPart ); ++ lok_doc_view_set_part( LOK_DOC_VIEW(pDocView), nPart ); + } + } + +@@ -326,7 +326,7 @@ static void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ ) + + if ( pDocView ) + { +- lok_docview_set_partmode( LOK_DOCVIEW(pDocView), ePartMode ); ++ lok_doc_view_set_partmode( LOK_DOC_VIEW(pDocView), ePartMode ); + } + } + #endif +@@ -451,7 +451,7 @@ int main( int argc, char* argv[] ) + gtk_box_pack_end(GTK_BOX(pVBox), pFindbar, FALSE, FALSE, 0); + + // Docview +- pDocView = lok_docview_new( pOffice ); ++ pDocView = lok_doc_view_new( pOffice ); + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); +@@ -467,10 +467,10 @@ int main( int argc, char* argv[] ) + // Hide the findbar by default. + gtk_widget_hide(pFindbar); + +- int bOpened = lok_docview_open_document( LOK_DOCVIEW(pDocView), argv[2] ); ++ int bOpened = lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2] ); + if (!bOpened) +- g_error("main: lok_docview_open_document() failed with '%s'", pOffice->pClass->getError(pOffice)); +- assert(lok_docview_get_document(LOK_DOCVIEW(pDocView))); ++ g_error("main: lok_doc_view_open_document() failed with '%s'", pOffice->pClass->getError(pOffice)); ++ assert(lok_doc_view_get_document(LOK_DOC_VIEW(pDocView))); + + // GtkComboBox requires gtk 2.24 or later + #if ( GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 24 ) || GTK_MAJOR_VERSION > 2 +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 6c3176783953..b1e31887599d 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -123,7 +123,7 @@ struct LOKDocView_Impl + bool m_bInDragGraphicHandles[8]; + ///@} + +- /// Callback data, allocated in lok_docview_callback_worker(), released in lok_docview_callback(). ++ /// Callback data, allocated in lok_doc_view_callback_worker(), released in lok_doc_view_callback(). + struct CallbackData + { + int m_nType; +@@ -305,7 +305,7 @@ void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/) + + void LOKDocView_Impl::on_exposed(GtkWidget* /*widget*/, GdkEvent* /*event*/, gpointer userdata) + { +- LOKDocView *pDocView = LOK_DOCVIEW (userdata); ++ LOKDocView *pDocView = LOK_DOC_VIEW (userdata); + pDocView->m_pImpl->renderDocument(0); + } + +@@ -461,7 +461,7 @@ gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) + } + + if (!m_bEdit) +- lok_docview_set_edit(m_pDocView, TRUE); ++ lok_doc_view_set_edit(m_pDocView, TRUE); + + switch (pEvent->type) + { +@@ -782,7 +782,7 @@ gboolean LOKDocView_Impl::handleTimeoutImpl() + void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + { + GdkRectangle visibleArea; +- lok_docview_get_visarea (m_pDocView, &visibleArea); ++ lok_doc_view_get_visarea (m_pDocView, &visibleArea); + + long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips, m_fZoom); + long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips, m_fZoom); +@@ -1058,7 +1058,7 @@ void LOKDocView_Impl::globalCallbackWorker(int nType, const char* pPayload, void + void LOKDocView_Impl::callbackWorkerImpl(int nType, const char* pPayload) + { + LOKDocView_Impl::CallbackData* pCallback = new LOKDocView_Impl::CallbackData(nType, pPayload ? pPayload : "(nil)", m_pDocView); +- g_info("lok_docview_callback_worker: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload); ++ g_info("lok_doc_view_callback_worker: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload); + #if GTK_CHECK_VERSION(2,12,0) + gdk_threads_add_idle(LOKDocView_Impl::callback, pCallback); + #endif +@@ -1082,30 +1082,30 @@ enum + LAST_SIGNAL + }; + +-static guint docview_signals[LAST_SIGNAL] = { 0 }; ++static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + + void LOKDocView_Impl::commandChanged(const std::string& rString) + { +- g_signal_emit(m_pDocView, docview_signals[COMMAND_CHANGED], 0, rString.c_str()); ++ g_signal_emit(m_pDocView, doc_view_signals[COMMAND_CHANGED], 0, rString.c_str()); + } + + void LOKDocView_Impl::searchNotFound(const std::string& rString) + { +- g_signal_emit(m_pDocView, docview_signals[SEARCH_NOT_FOUND], 0, rString.c_str()); ++ g_signal_emit(m_pDocView, doc_view_signals[SEARCH_NOT_FOUND], 0, rString.c_str()); + } + + void LOKDocView_Impl::setPart(const std::string& rString) + { +- g_signal_emit(m_pDocView, docview_signals[PART_CHANGED], 0, std::stoi(rString)); ++ g_signal_emit(m_pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString)); + renderDocument(0); + } + +-static void lok_docview_class_init( gpointer ptr ) ++static void lok_doc_view_class_init( gpointer ptr ) + { + LOKDocViewClass* pClass = static_cast(ptr); + GObjectClass *gobject_class = G_OBJECT_CLASS(pClass); + pClass->edit_changed = NULL; +- docview_signals[EDIT_CHANGED] = ++ doc_view_signals[EDIT_CHANGED] = + g_signal_new("edit-changed", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, +@@ -1115,7 +1115,7 @@ static void lok_docview_class_init( gpointer ptr ) + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); + pClass->command_changed = NULL; +- docview_signals[COMMAND_CHANGED] = ++ doc_view_signals[COMMAND_CHANGED] = + g_signal_new("command-changed", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, +@@ -1125,7 +1125,7 @@ static void lok_docview_class_init( gpointer ptr ) + G_TYPE_NONE, 1, + G_TYPE_STRING); + pClass->search_not_found = 0; +- docview_signals[SEARCH_NOT_FOUND] = ++ doc_view_signals[SEARCH_NOT_FOUND] = + g_signal_new("search-not-found", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, +@@ -1135,7 +1135,7 @@ static void lok_docview_class_init( gpointer ptr ) + G_TYPE_NONE, 1, + G_TYPE_STRING); + pClass->part_changed = 0; +- docview_signals[PART_CHANGED] = ++ doc_view_signals[PART_CHANGED] = + g_signal_new("part-changed", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_FIRST, +@@ -1146,7 +1146,7 @@ static void lok_docview_class_init( gpointer ptr ) + G_TYPE_INT); + } + +-static void lok_docview_init( GTypeInstance* pInstance, gpointer ) ++static void lok_doc_view_init( GTypeInstance* pInstance, gpointer ) + { + LOKDocView* pDocView = reinterpret_cast(pInstance); + // Gtk ScrolledWindow is apparently not fully initialised yet, we specifically +@@ -1183,38 +1183,38 @@ static void lok_docview_init( GTypeInstance* pInstance, gpointer ) + g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0); + } + +-SAL_DLLPUBLIC_EXPORT guint lok_docview_get_type() ++SAL_DLLPUBLIC_EXPORT guint lok_doc_view_get_type() + { +- static guint lok_docview_type = 0; ++ static guint lok_doc_view_type = 0; + +- if (!lok_docview_type) ++ if (!lok_doc_view_type) + { + char pName[] = "LokDocView"; +- GtkTypeInfo lok_docview_info = ++ GtkTypeInfo lok_doc_view_info = + { + pName, + sizeof( LOKDocView ), + sizeof( LOKDocViewClass ), +- lok_docview_class_init, +- lok_docview_init, ++ lok_doc_view_class_init, ++ lok_doc_view_init, + NULL, + NULL, + nullptr + }; + +- lok_docview_type = gtk_type_unique( gtk_scrolled_window_get_type(), &lok_docview_info ); ++ lok_doc_view_type = gtk_type_unique( gtk_scrolled_window_get_type(), &lok_doc_view_info ); + } +- return lok_docview_type; ++ return lok_doc_view_type; + } + +-SAL_DLLPUBLIC_EXPORT GtkWidget* lok_docview_new( LibreOfficeKit* pOffice ) ++SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new( LibreOfficeKit* pOffice ) + { +- LOKDocView* pDocView = LOK_DOCVIEW(gtk_type_new(lok_docview_get_type())); ++ LOKDocView* pDocView = LOK_DOC_VIEW(gtk_type_new(lok_doc_view_get_type())); + pDocView->m_pImpl->m_pOffice = pOffice; + return GTK_WIDGET( pDocView ); + } + +-SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, char* pPath ) ++SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, char* pPath ) + { + if ( pDocView->m_pImpl->m_pDocument ) + { +@@ -1260,12 +1260,12 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_docview_open_document( LOKDocView* pDocView, c + return TRUE; + } + +-SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_docview_get_document(LOKDocView* pDocView) ++SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocView* pDocView) + { + return pDocView->m_pImpl->m_pDocument; + } + +-SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZoom ) ++SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZoom ) + { + pDocView->m_pImpl->m_fZoom = fZoom; + long nDocumentWidthPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips, fZoom); +@@ -1283,72 +1283,72 @@ SAL_DLLPUBLIC_EXPORT void lok_docview_set_zoom ( LOKDocView* pDocView, float fZo + pDocView->m_pImpl->renderDocument(0); + } + +-SAL_DLLPUBLIC_EXPORT float lok_docview_get_zoom ( LOKDocView* pDocView ) ++SAL_DLLPUBLIC_EXPORT float lok_doc_view_get_zoom ( LOKDocView* pDocView ) + { + return pDocView->m_pImpl->m_fZoom; + } + +-SAL_DLLPUBLIC_EXPORT int lok_docview_get_parts( LOKDocView* pDocView ) ++SAL_DLLPUBLIC_EXPORT int lok_doc_view_get_parts( LOKDocView* pDocView ) + { + return pDocView->m_pImpl->m_pDocument->pClass->getParts( pDocView->m_pImpl->m_pDocument ); + } + +-SAL_DLLPUBLIC_EXPORT int lok_docview_get_part( LOKDocView* pDocView ) ++SAL_DLLPUBLIC_EXPORT int lok_doc_view_get_part( LOKDocView* pDocView ) + { + return pDocView->m_pImpl->m_pDocument->pClass->getPart( pDocView->m_pImpl->m_pDocument ); + } + +-SAL_DLLPUBLIC_EXPORT void lok_docview_set_part( LOKDocView* pDocView, int nPart) ++SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_part( LOKDocView* pDocView, int nPart) + { + pDocView->m_pImpl->m_pDocument->pClass->setPart( pDocView->m_pImpl->m_pDocument, nPart ); + } + +-SAL_DLLPUBLIC_EXPORT char* lok_docview_get_part_name( LOKDocView* pDocView, int nPart ) ++SAL_DLLPUBLIC_EXPORT char* lok_doc_view_get_part_name( LOKDocView* pDocView, int nPart ) + { + return pDocView->m_pImpl->m_pDocument->pClass->getPartName( pDocView->m_pImpl->m_pDocument, nPart ); + } + +-SAL_DLLPUBLIC_EXPORT void lok_docview_set_partmode( LOKDocView* pDocView, ++SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_partmode( LOKDocView* pDocView, + int nPartMode ) + { + pDocView->m_pImpl->m_pDocument->pClass->setPartMode( pDocView->m_pImpl->m_pDocument, nPartMode ); + pDocView->m_pImpl->renderDocument(0); + } + +-SAL_DLLPUBLIC_EXPORT void lok_docview_set_edit( LOKDocView* pDocView, ++SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView, + gboolean bEdit ) + { + gboolean bWasEdit = pDocView->m_pImpl->m_bEdit; + + if (!pDocView->m_pImpl->m_bEdit && bEdit) +- g_info("lok_docview_set_edit: entering edit mode"); ++ g_info("lok_doc_view_set_edit: entering edit mode"); + else if (pDocView->m_pImpl->m_bEdit && !bEdit) + { +- g_info("lok_docview_set_edit: leaving edit mode"); ++ g_info("lok_doc_view_set_edit: leaving edit mode"); + pDocView->m_pImpl->m_pDocument->pClass->resetSelection(pDocView->m_pImpl->m_pDocument); + } + pDocView->m_pImpl->m_bEdit = bEdit; +- g_signal_emit(pDocView, docview_signals[EDIT_CHANGED], 0, bWasEdit); ++ g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit); + gtk_widget_queue_draw(GTK_WIDGET(pDocView->m_pImpl->m_pDrawingArea)); + } + +-SAL_DLLPUBLIC_EXPORT gboolean lok_docview_get_edit(LOKDocView* pDocView) ++SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_get_edit(LOKDocView* pDocView) + { + return pDocView->m_pImpl->m_bEdit; + } + +-SAL_DLLPUBLIC_EXPORT void lok_docview_post_command(LOKDocView* pDocView, const char* pCommand, const char* pArguments) ++SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_command(LOKDocView* pDocView, const char* pCommand, const char* pArguments) + { + pDocView->m_pImpl->m_pDocument->pClass->postUnoCommand(pDocView->m_pImpl->m_pDocument, pCommand, pArguments); + } + +-SAL_DLLPUBLIC_EXPORT void lok_docview_post_key(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer pData) ++SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer pData) + { + LOKDocView* pDocView = static_cast(pData); + pDocView->m_pImpl->signalKey(pEvent); + } + +-SAL_DLLPUBLIC_EXPORT void lok_docview_get_visarea(LOKDocView* pThis, GdkRectangle* pArea) ++SAL_DLLPUBLIC_EXPORT void lok_doc_view_get_visarea(LOKDocView* pThis, GdkRectangle* pArea) + { + float zoom = pThis->m_pImpl->m_fZoom; + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pThis)); +-- +2.12.0 + diff --git a/SOURCES/0024-lokdocview-Modernise-LOKDocView-as-GObject.patch b/SOURCES/0024-lokdocview-Modernise-LOKDocView-as-GObject.patch new file mode 100644 index 0000000..8b38cd8 --- /dev/null +++ b/SOURCES/0024-lokdocview-Modernise-LOKDocView-as-GObject.patch @@ -0,0 +1,252 @@ +From 9d8fd399aa92d5bcfc11399f296ed2ffdd741286 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 6 Jun 2015 03:10:31 +0530 +Subject: [PATCH 024/398] lokdocview: Modernise LOKDocView as GObject + +Change-Id: I3bbd07ce8163890f9b88567966622dd4fbe9d94d +(cherry picked from commit c5f1f7ad2710914fdd6645dd8ce958c70d1d8381) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 63 ++++++++++--------- + libreofficekit/source/gtk/lokdocview.cxx | 97 +++++++++++++----------------- + 2 files changed, 77 insertions(+), 83 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 069c565435bb..747e45e531f9 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -18,9 +18,13 @@ + + G_BEGIN_DECLS + +-#define LOK_DOC_VIEW(obj) GTK_CHECK_CAST (obj, lok_doc_view_get_type(), LOKDocView) +-#define LOK_DOC_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, lok_doc_view_get_type(), LOKDocViewClass) +-#define IS_LOK_DOC_VIEW(obj) GTK_CHECK_TYPE (obj, lok_doc_view_get_type()) ++#define LOK_TYPE_DOC_VIEW (lok_doc_view_get_type()) ++#define LOK_DOC_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), LOK_TYPE_DOC_VIEW, LOKDocView)) ++#define LOK_IS_DOC_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), LOK_TYPE_DOC_VIEW)) ++#define LOK_DOC_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), LOK_TYPE_DOC_VIEW, LOKDocViewClass)) ++#define LOK_IS_DOC_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LOK_TYPE_DOC_VIEW)) ++#define LOK_DOC_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LOK_TYPE_DOC_VIEW, LOKDocViewClass)) ++ + + typedef struct _LOKDocView LOKDocView; + typedef struct _LOKDocViewClass LOKDocViewClass; +@@ -40,40 +44,45 @@ struct _LOKDocViewClass + void (* part_changed) (LOKDocView* pView, int new_part); + }; + +-guint lok_doc_view_get_type (void); +-GtkWidget* lok_doc_view_new ( LibreOfficeKit* pOffice ); +-gboolean lok_doc_view_open_document (LOKDocView* pDocView, +- char* pPath); ++GType lok_doc_view_get_type (void); ++GtkWidget* lok_doc_view_new (LibreOfficeKit* pOffice ); ++gboolean lok_doc_view_open_document (LOKDocView* pDocView, ++ char* pPath); + + /// Gets the document the viewer displays. +-LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocView* pDocView); +- +-void lok_doc_view_set_zoom (LOKDocView* pDocView, +- float fZoom); +-float lok_doc_view_get_zoom (LOKDocView* pDocView); +- +-int lok_doc_view_get_parts (LOKDocView* pDocView); +-int lok_doc_view_get_part (LOKDocView* pDocView); +-void lok_doc_view_set_part (LOKDocView* pDocView, +- int nPart); +-char* lok_doc_view_get_part_name (LOKDocView* pDocView, +- int nPart); +-void lok_doc_view_set_partmode (LOKDocView* pDocView, +- int nPartMode); ++LibreOfficeKitDocument* lok_doc_view_get_document (LOKDocView* pDocView); ++ ++void lok_doc_view_set_zoom (LOKDocView* pDocView, ++ float fZoom); ++float lok_doc_view_get_zoom (LOKDocView* pDocView); ++ ++int lok_doc_view_get_parts (LOKDocView* pDocView); ++int lok_doc_view_get_part (LOKDocView* pDocView); ++void lok_doc_view_set_part (LOKDocView* pDocView, ++ int nPart); ++char* lok_doc_view_get_part_name (LOKDocView* pDocView, ++ int nPart); ++void lok_doc_view_set_partmode (LOKDocView* pDocView, ++ int nPartMode); + /// Sets if the viewer is actually an editor or not. +-void lok_doc_view_set_edit (LOKDocView* pDocView, +- gboolean bEdit); ++void lok_doc_view_set_edit (LOKDocView* pDocView, ++ gboolean bEdit); + /// Gets if the viewer is actually an editor or not. +-gboolean lok_doc_view_get_edit (LOKDocView* pDocView); ++gboolean lok_doc_view_get_edit (LOKDocView* pDocView); + + /// Posts the .uno: command to the LibreOfficeKit. +-void lok_doc_view_post_command (LOKDocView* pDocView, const char* pCommand, const char* pArguments); ++void lok_doc_view_post_command (LOKDocView* pDocView, ++ const char* pCommand, ++ const char* pArguments); + + /// Posts a keyboard event to LibreOfficeKit. +-void lok_doc_view_post_key (GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData); ++void lok_doc_view_post_key (GtkWidget* pWidget, ++ GdkEventKey* pEvent, ++ gpointer pData); + + /// Get the visible area of the document (in twips). +-void lok_doc_view_get_visarea(LOKDocView* pThis, GdkRectangle* pArea); ++void lok_doc_view_get_visarea (LOKDocView* pThis, ++ GdkRectangle* pArea); + + G_END_DECLS + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index b1e31887599d..9b09ef6452bb 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -37,26 +37,6 @@ + // Number of handles around a graphic selection. + #define GRAPHIC_HANDLE_COUNT 8 + +-namespace { +- +-/// Sets rWidth and rHeight from a "width, height" string. +-void payloadToSize(const char* pPayload, long& rWidth, long& rHeight) +-{ +- rWidth = rHeight = 0; +- gchar** ppCoordinates = g_strsplit(pPayload, ", ", 2); +- gchar** ppCoordinate = ppCoordinates; +- if (!*ppCoordinate) +- return; +- rWidth = atoi(*ppCoordinate); +- ++ppCoordinate; +- if (!*ppCoordinate) +- return; +- rHeight = atoi(*ppCoordinate); +- g_strfreev(ppCoordinates); +-} +- +-} +- + /// Holds data used by LOKDocView only. + struct LOKDocView_Impl + { +@@ -216,6 +196,44 @@ struct LOKDocView_Impl + void setTilesInvalid(const GdkRectangle& rRectangle); + }; + ++enum ++{ ++ EDIT_CHANGED, ++ COMMAND_CHANGED, ++ SEARCH_NOT_FOUND, ++ PART_CHANGED, ++ LAST_SIGNAL ++}; ++ ++ ++static guint doc_view_signals[LAST_SIGNAL] = { 0 }; ++ ++ ++G_DEFINE_TYPE(LOKDocView, lok_doc_view, GTK_TYPE_SCROLLED_WINDOW) ++ ++ ++namespace { ++ ++/// Sets rWidth and rHeight from a "width, height" string. ++void payloadToSize(const char* pPayload, long& rWidth, long& rHeight) ++{ ++ rWidth = rHeight = 0; ++ gchar** ppCoordinates = g_strsplit(pPayload, ", ", 2); ++ gchar** ppCoordinate = ppCoordinates; ++ if (!*ppCoordinate) ++ return; ++ rWidth = atoi(*ppCoordinate); ++ ++ppCoordinate; ++ if (!*ppCoordinate) ++ return; ++ rHeight = atoi(*ppCoordinate); ++ g_strfreev(ppCoordinates); ++} ++ ++} ++ ++ ++ + namespace { + + /// Implementation of the global callback handler, invoked by globalCallback(); +@@ -1073,16 +1091,7 @@ void LOKDocView_Impl::globalCallbackWorkerImpl(int nType, const char* pPayload) + #endif + } + +-enum +-{ +- EDIT_CHANGED, +- COMMAND_CHANGED, +- SEARCH_NOT_FOUND, +- PART_CHANGED, +- LAST_SIGNAL +-}; + +-static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + + void LOKDocView_Impl::commandChanged(const std::string& rString) + { +@@ -1100,9 +1109,8 @@ void LOKDocView_Impl::setPart(const std::string& rString) + renderDocument(0); + } + +-static void lok_doc_view_class_init( gpointer ptr ) ++static void lok_doc_view_class_init (LOKDocViewClass* pClass) + { +- LOKDocViewClass* pClass = static_cast(ptr); + GObjectClass *gobject_class = G_OBJECT_CLASS(pClass); + pClass->edit_changed = NULL; + doc_view_signals[EDIT_CHANGED] = +@@ -1146,9 +1154,8 @@ static void lok_doc_view_class_init( gpointer ptr ) + G_TYPE_INT); + } + +-static void lok_doc_view_init( GTypeInstance* pInstance, gpointer ) ++static void lok_doc_view_init (LOKDocView* pDocView) + { +- LOKDocView* pDocView = reinterpret_cast(pInstance); + // Gtk ScrolledWindow is apparently not fully initialised yet, we specifically + // have to set the [hv]adjustment to prevent GTK assertions from firing, see + // https://bugzilla.gnome.org/show_bug.cgi?id=438114 for more info. +@@ -1183,29 +1190,7 @@ static void lok_doc_view_init( GTypeInstance* pInstance, gpointer ) + g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0); + } + +-SAL_DLLPUBLIC_EXPORT guint lok_doc_view_get_type() +-{ +- static guint lok_doc_view_type = 0; +- +- if (!lok_doc_view_type) +- { +- char pName[] = "LokDocView"; +- GtkTypeInfo lok_doc_view_info = +- { +- pName, +- sizeof( LOKDocView ), +- sizeof( LOKDocViewClass ), +- lok_doc_view_class_init, +- lok_doc_view_init, +- NULL, +- NULL, +- nullptr +- }; +- +- lok_doc_view_type = gtk_type_unique( gtk_scrolled_window_get_type(), &lok_doc_view_info ); +- } +- return lok_doc_view_type; +-} ++SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); + + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new( LibreOfficeKit* pOffice ) + { +-- +2.12.0 + diff --git a/SOURCES/0025-lokdocview-mark-_get_type-with-const-function-attrib.patch b/SOURCES/0025-lokdocview-mark-_get_type-with-const-function-attrib.patch new file mode 100644 index 0000000..54d6de1 --- /dev/null +++ b/SOURCES/0025-lokdocview-mark-_get_type-with-const-function-attrib.patch @@ -0,0 +1,31 @@ +From e00227ccfd0028fdc00683166217541df4685f94 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 7 Jun 2015 22:28:01 +0530 +Subject: [PATCH 025/398] lokdocview: mark *_get_type() with const function + attribute + +Use G_GNUC_CONST that adds const function attribute to +lok_doc_view_get_type() for better performance. + +Change-Id: Id79f0395a98c4f98b46303e9b5ee1e103fbe331f +(cherry picked from commit 0e947f33130c55881035e39dcb1c5e64c33297e9) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 747e45e531f9..e84feee9bd57 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -44,7 +44,7 @@ struct _LOKDocViewClass + void (* part_changed) (LOKDocView* pView, int new_part); + }; + +-GType lok_doc_view_get_type (void); ++GType lok_doc_view_get_type (void) G_GNUC_CONST; + GtkWidget* lok_doc_view_new (LibreOfficeKit* pOffice ); + gboolean lok_doc_view_open_document (LOKDocView* pDocView, + char* pPath); +-- +2.12.0 + diff --git a/SOURCES/0026-libreofficekit-fix-RHEL5-build-of-tilebuffer.patch b/SOURCES/0026-libreofficekit-fix-RHEL5-build-of-tilebuffer.patch new file mode 100644 index 0000000..047b01e --- /dev/null +++ b/SOURCES/0026-libreofficekit-fix-RHEL5-build-of-tilebuffer.patch @@ -0,0 +1,50 @@ +From 0fb343d2b27c75fa77b5a740c7e7cf53c2ecbe1e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 8 Jun 2015 08:02:37 +0200 +Subject: [PATCH 026/398] libreofficekit: fix RHEL5 build of tilebuffer + +Change-Id: I27da86c774f0450c844e742563c4a8de3f23ad34 +(cherry picked from commit a0ce0dd519ec298bf7df0111dca1e1c6fdc3a1ee) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 ++ + libreofficekit/source/gtk/tilebuffer.cxx | 4 ++++ + 2 files changed, 6 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 9b09ef6452bb..a5cf7aaac741 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1335,6 +1335,7 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEvent + + SAL_DLLPUBLIC_EXPORT void lok_doc_view_get_visarea(LOKDocView* pThis, GdkRectangle* pArea) + { ++#if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() + float zoom = pThis->m_pImpl->m_fZoom; + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pThis)); + pArea->x = pixelToTwip(gtk_adjustment_get_value(pHAdjustment),zoom); +@@ -1342,6 +1343,7 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_get_visarea(LOKDocView* pThis, GdkRectang + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pThis)); + pArea->y = pixelToTwip(gtk_adjustment_get_value(pVAdjustment), zoom); + pArea->height = pixelToTwip(gtk_adjustment_get_page_size(pVAdjustment), zoom); ++#endif + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 338038078ab3..0c798232326b 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -9,6 +9,10 @@ + + #include "tilebuffer.hxx" + ++#if !GLIB_CHECK_VERSION(2,40,0) ++#define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__) ++#endif ++ + /* ------------------ + Utility functions + ------------------ +-- +2.12.0 + diff --git a/SOURCES/0027-lokdocview-Make-tilebuffer-an-instance.patch b/SOURCES/0027-lokdocview-Make-tilebuffer-an-instance.patch new file mode 100644 index 0000000..e087866 --- /dev/null +++ b/SOURCES/0027-lokdocview-Make-tilebuffer-an-instance.patch @@ -0,0 +1,155 @@ +From bcb1637523f79f0b26bb28d4304969eb95a09944 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 8 Jun 2015 14:17:17 +0530 +Subject: [PATCH 027/398] lokdocview: Make tilebuffer an instance + +Change-Id: I06dae2e7a5067160326f4c65f5975c4e5afb05ce +(cherry picked from commit 03655e67cbb26a6a7b8da4b5e5a18eae4742b412) +--- + libreofficekit/source/gtk/lokdocview.cxx | 81 +++++++++++++++++--------------- + 1 file changed, 42 insertions(+), 39 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index a5cf7aaac741..2997feddf1d4 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -42,7 +42,7 @@ struct LOKDocView_Impl + { + LOKDocView* m_pDocView; + GtkWidget *m_pDrawingArea; +- TileBuffer *m_pTileBuffer; ++ TileBuffer m_aTileBuffer; + + float m_fZoom; + +@@ -192,7 +192,7 @@ struct LOKDocView_Impl + void searchNotFound(const std::string& rPayload); + /// LOK decided to change parts, need to update UI. + void setPart(const std::string& rPayload); +- /// Sets the tiles enclosed by rRectangle as invalid in m_pTileBuffer ++ /// Sets the tiles enclosed by rRectangle as invalid in m_aTileBuffer + void setTilesInvalid(const GdkRectangle& rRectangle); + }; + +@@ -273,35 +273,36 @@ LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPaylo + + LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView) + : m_pDocView(pDocView), +- m_pDrawingArea(gtk_drawing_area_new()), +- m_fZoom(1), +- m_pOffice(0), +- m_pDocument(0), +- m_nDocumentWidthTwips(0), +- m_nDocumentHeightTwips(0), +- m_bEdit(false), +- m_aVisibleCursor({0, 0, 0, 0}), +- m_bCursorOverlayVisible(false), +- m_bCursorVisible(true), +- m_nLastButtonPressTime(0), +- m_nLastButtonReleaseTime(0), +- m_aTextSelectionStart({0, 0, 0, 0}), +- m_aTextSelectionEnd({0, 0, 0, 0}), +- m_aGraphicSelection({0, 0, 0, 0}), +- m_bInDragGraphicSelection(false), +- +- // Start/middle/end handle. +- m_pHandleStart(0), +- m_aHandleStartRect({0, 0, 0, 0}), +- m_bInDragStartHandle(false), +- m_pHandleMiddle(0), +- m_aHandleMiddleRect({0, 0, 0, 0}), +- m_bInDragMiddleHandle(false), +- m_pHandleEnd(0), +- m_aHandleEndRect({0, 0, 0, 0}), +- m_bInDragEndHandle(false), +- +- m_pGraphicHandle(0) ++ m_pDrawingArea(gtk_drawing_area_new()), ++ m_aTileBuffer(TileBuffer(0,0,0,0)), ++ m_fZoom(1), ++ m_pOffice(0), ++ m_pDocument(0), ++ m_nDocumentWidthTwips(0), ++ m_nDocumentHeightTwips(0), ++ m_bEdit(false), ++ m_aVisibleCursor({0, 0, 0, 0}), ++ m_bCursorOverlayVisible(false), ++ m_bCursorVisible(true), ++ m_nLastButtonPressTime(0), ++ m_nLastButtonReleaseTime(0), ++ m_aTextSelectionStart({0, 0, 0, 0}), ++ m_aTextSelectionEnd({0, 0, 0, 0}), ++ m_aGraphicSelection({0, 0, 0, 0}), ++ m_bInDragGraphicSelection(false), ++ ++ // Start/middle/end handle. ++ m_pHandleStart(0), ++ m_aHandleStartRect({0, 0, 0, 0}), ++ m_bInDragStartHandle(false), ++ m_pHandleMiddle(0), ++ m_aHandleMiddleRect({0, 0, 0, 0}), ++ m_bInDragMiddleHandle(false), ++ m_pHandleEnd(0), ++ m_aHandleEndRect({0, 0, 0, 0}), ++ m_bInDragEndHandle(false), ++ ++ m_pGraphicHandle(0) + { + memset(&m_aGraphicHandleRects, 0, sizeof(m_aGraphicHandleRects)); + memset(&m_bInDragGraphicHandles, 0, sizeof(m_bInDragGraphicHandles)); +@@ -683,7 +684,7 @@ void LOKDocView_Impl::setTilesInvalid(const GdkRectangle& rRectangle) + + for (int i = aStart.x; i < aEnd.x; i++) + for (int j = aStart.y; j < aEnd.y; j++) +- m_pTileBuffer->setInvalid(i, j); ++ m_aTileBuffer.setInvalid(i, j); + } + + void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle) +@@ -845,7 +846,7 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + { + //g_info("tile_buffer_get_tile (%d, %d)", nRow, nColumn); + +- Tile& currentTile = m_pTileBuffer->getTile(nRow, nColumn); ++ Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + + gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, +@@ -969,7 +970,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + setTilesInvalid(aRectangle); + } + else +- m_pTileBuffer->resetAllTiles(); ++ m_aTileBuffer.resetAllTiles(); + + gtk_widget_queue_draw(m_pDrawingArea); + } +@@ -1232,10 +1233,12 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, + // Total number of rows / columns in this document. + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +- pDocView->m_pImpl->m_pTileBuffer = new TileBuffer(pDocView->m_pImpl->m_pDocument, +- nTileSizePixels, +- nRows, +- nColumns); ++ ++ ++ pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, ++ nTileSizePixels, ++ nRows, ++ nColumns); + gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, + nDocumentWidthPixels, + nDocumentHeightPixels); +@@ -1259,7 +1262,7 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- pDocView->m_pImpl->m_pTileBuffer->setZoom(fZoom, nRows, nColumns); ++ pDocView->m_pImpl->m_aTileBuffer.setZoom(fZoom, nRows, nColumns); + gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, + nDocumentWidthPixels, + nDocumentHeightPixels); +-- +2.12.0 + diff --git a/SOURCES/0028-tilebuffer-ZoomFactor-as-member-variable-is-superflu.patch b/SOURCES/0028-tilebuffer-ZoomFactor-as-member-variable-is-superflu.patch new file mode 100644 index 0000000..1d81bcd --- /dev/null +++ b/SOURCES/0028-tilebuffer-ZoomFactor-as-member-variable-is-superflu.patch @@ -0,0 +1,133 @@ +From ecbfe4c719be7ed5919a7e6f66388bdb51948cbb Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 8 Jun 2015 15:08:44 +0530 +Subject: [PATCH 028/398] tilebuffer: ZoomFactor as member variable is + superfluous + +Change-Id: I9f533f577f959c9a715e5214be99ca59cb0d206c +(cherry picked from commit 16222190ec4cf6b83e7771a8d714a7dbb968c42b) +--- + libreofficekit/source/gtk/lokdocview.cxx | 7 +++++-- + libreofficekit/source/gtk/tilebuffer.cxx | 21 +++++---------------- + libreofficekit/source/gtk/tilebuffer.hxx | 14 -------------- + 3 files changed, 10 insertions(+), 32 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 2997feddf1d4..d790b2b43c08 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -846,7 +846,7 @@ void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) + { + //g_info("tile_buffer_get_tile (%d, %d)", nRow, nColumn); + +- Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn); ++ Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn, m_fZoom); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + + gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, +@@ -1262,7 +1262,10 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- pDocView->m_pImpl->m_aTileBuffer.setZoom(fZoom, nRows, nColumns); ++ pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, ++ nTileSizePixels, ++ nRows, ++ nColumns); + gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, + nDocumentWidthPixels, + nDocumentHeightPixels); +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 0c798232326b..774806bc414d 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -51,17 +51,6 @@ void Tile::setPixbuf(GdkPixbuf *buffer) + TileBuffer class member functions + ---------------------------------- + */ +-void TileBuffer::setZoom(float newZoomFactor, int rows, int columns) +-{ +- m_fZoomFactor = newZoomFactor; +- +- resetAllTiles(); +- +- // set new buffer width and height +- m_nWidth = columns; +- m_nHeight = rows; +-} +- + void TileBuffer::resetAllTiles() + { + std::map::iterator it = m_mTiles.begin(); +@@ -84,7 +73,7 @@ void TileBuffer::setInvalid(int x, int y) + } + } + +-Tile& TileBuffer::getTile(int x, int y) ++Tile& TileBuffer::getTile(int x, int y, float aZoom) + { + int index = x * m_nWidth + y; + if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[index].valid) +@@ -99,16 +88,16 @@ Tile& TileBuffer::getTile(int x, int y) + + unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); + GdkRectangle aTileRectangle; +- aTileRectangle.x = pixelToTwip(m_nTileSize, m_fZoomFactor) * y; +- aTileRectangle.y = pixelToTwip(m_nTileSize, m_fZoomFactor) * x; ++ aTileRectangle.x = pixelToTwip(m_nTileSize, aZoom) * y; ++ aTileRectangle.y = pixelToTwip(m_nTileSize, aZoom) * x; + + g_info ("Rendering (%d, %d)", x, y); + m_pLOKDocument->pClass->paintTile(m_pLOKDocument, + pBuffer, + m_nTileSize, m_nTileSize, + aTileRectangle.x, aTileRectangle.y, +- pixelToTwip(m_nTileSize, m_fZoomFactor), +- pixelToTwip(m_nTileSize, m_fZoomFactor)); ++ pixelToTwip(m_nTileSize, aZoom), ++ pixelToTwip(m_nTileSize, aZoom)); + + //create a mapping for it + m_mTiles[index].setPixbuf(pPixBuf); +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 7e2132f4d512..59660042f544 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -88,7 +88,6 @@ class TileBuffer + int columns) + : m_pLOKDocument(document) + , m_nTileSize(tileSize) +- , m_fZoomFactor(1) + , m_nWidth(columns) + , m_nHeight(rows) + { } +@@ -96,17 +95,6 @@ class TileBuffer + ~TileBuffer() {} + + /** +- Sets the zoom factor (m_fZoomFactor) for this tile buffer. Setting the +- zoom factor invalidates whole of the tile buffer, destroys all tiles +- contained within it, and sets new width, height values for tile +- buffer. The width, height value of tile buffer is the width and height of +- the table containing all possible tiles (rendered and non-rendered) that +- this buffer can have. +- +- @param zoomFactor the new zoom factor value to set +- */ +- void setZoom(float zoomFactor, int rows, int columns); +- /** + Gets the underlying Tile object for given position. The position (0, 0) + points to the left top most tile of the buffer. + +@@ -137,8 +125,6 @@ class TileBuffer + LibreOfficeKitDocument *m_pLOKDocument; + /// The side of each squared tile in pixels. + int m_nTileSize; +- /// The zoom factor that the tile buffer is currently rendered to. +- float m_fZoomFactor; + /// Stores all the tiles cached by this tile buffer. + std::map m_mTiles; + /// Width of the current tile buffer (number of columns) +-- +2.12.0 + diff --git a/SOURCES/0029-tilebuffer-tileSize-as-member-variable-is-superfluou.patch b/SOURCES/0029-tilebuffer-tileSize-as-member-variable-is-superfluou.patch new file mode 100644 index 0000000..792d4bb --- /dev/null +++ b/SOURCES/0029-tilebuffer-tileSize-as-member-variable-is-superfluou.patch @@ -0,0 +1,119 @@ +From f72510427d6076b304ed14879b00eb253367e161 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 8 Jun 2015 15:24:12 +0530 +Subject: [PATCH 029/398] tilebuffer: tileSize as member variable is + superfluous + +Change-Id: I1eae8c96c12ba4d272341f45fee6c1fd66ab9e28 +(cherry picked from commit 2afe94dbfc85cbcde1399267379a466d527998a4) +--- + libreofficekit/source/gtk/lokdocview.cxx | 4 +--- + libreofficekit/source/gtk/tilebuffer.cxx | 12 ++++++------ + libreofficekit/source/gtk/tilebuffer.hxx | 7 ++----- + 3 files changed, 9 insertions(+), 14 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d790b2b43c08..0124704d6784 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -274,7 +274,7 @@ LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPaylo + LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView) + : m_pDocView(pDocView), + m_pDrawingArea(gtk_drawing_area_new()), +- m_aTileBuffer(TileBuffer(0,0,0,0)), ++ m_aTileBuffer(TileBuffer(0,0,0)), + m_fZoom(1), + m_pOffice(0), + m_pDocument(0), +@@ -1236,7 +1236,6 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, + + + pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, +- nTileSizePixels, + nRows, + nColumns); + gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, +@@ -1263,7 +1262,6 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + + pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, +- nTileSizePixels, + nRows, + nColumns); + gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 774806bc414d..1d6a8b66ec80 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -79,7 +79,7 @@ Tile& TileBuffer::getTile(int x, int y, float aZoom) + if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[index].valid) + { + +- GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, m_nTileSize, m_nTileSize); ++ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); + if (!pPixBuf) + { + g_info ("Error allocating memory to pixbuf"); +@@ -88,16 +88,16 @@ Tile& TileBuffer::getTile(int x, int y, float aZoom) + + unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); + GdkRectangle aTileRectangle; +- aTileRectangle.x = pixelToTwip(m_nTileSize, aZoom) * y; +- aTileRectangle.y = pixelToTwip(m_nTileSize, aZoom) * x; ++ aTileRectangle.x = pixelToTwip(nTileSizePixels, aZoom) * y; ++ aTileRectangle.y = pixelToTwip(nTileSizePixels, aZoom) * x; + + g_info ("Rendering (%d, %d)", x, y); + m_pLOKDocument->pClass->paintTile(m_pLOKDocument, + pBuffer, +- m_nTileSize, m_nTileSize, ++ nTileSizePixels, nTileSizePixels, + aTileRectangle.x, aTileRectangle.y, +- pixelToTwip(m_nTileSize, aZoom), +- pixelToTwip(m_nTileSize, aZoom)); ++ pixelToTwip(nTileSizePixels, aZoom), ++ pixelToTwip(nTileSizePixels, aZoom)); + + //create a mapping for it + m_mTiles[index].setPixbuf(pPixBuf); +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 59660042f544..ea8e52452c8d 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -83,11 +83,9 @@ class TileBuffer + { + public: + TileBuffer(LibreOfficeKitDocument *document, +- int tileSize, + int rows, + int columns) + : m_pLOKDocument(document) +- , m_nTileSize(tileSize) + , m_nWidth(columns) + , m_nHeight(rows) + { } +@@ -104,10 +102,11 @@ class TileBuffer + + @param x the tile along the x-axis of the buffer + @param y the tile along the y-axis of the buffer ++ @param aZoom This function needs the zoom factor to draw the tile using paintTile() + + @return the tile at the mentioned position (x, y) + */ +- Tile& getTile(int x, int y); ++ Tile& getTile(int x, int y, float aZoom); + /// Destroys all the tiles in the tile buffer; also frees the memory allocated + /// for all the Tile objects. + void resetAllTiles(); +@@ -123,8 +122,6 @@ class TileBuffer + private: + /// Contains the reference to the LOK Document that this tile buffer is for. + LibreOfficeKitDocument *m_pLOKDocument; +- /// The side of each squared tile in pixels. +- int m_nTileSize; + /// Stores all the tiles cached by this tile buffer. + std::map m_mTiles; + /// Width of the current tile buffer (number of columns) +-- +2.12.0 + diff --git a/SOURCES/0030-Werror-Wunused-private-field.patch b/SOURCES/0030-Werror-Wunused-private-field.patch new file mode 100644 index 0000000..932fa71 --- /dev/null +++ b/SOURCES/0030-Werror-Wunused-private-field.patch @@ -0,0 +1,82 @@ +From 1241127d63bb91f6c901d32525bce8de0da7108a Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 9 Jun 2015 11:42:41 +0200 +Subject: [PATCH 030/398] -Werror,-Wunused-private-field + +Change-Id: I76cf487c66e048b5e9d0877a1b690cd066b73528 +(cherry picked from commit 3a1a5b9744eb73f82c28ecfaa39b54587ef8206b) +--- + libreofficekit/source/gtk/lokdocview.cxx | 10 +++------- + libreofficekit/source/gtk/tilebuffer.hxx | 4 ---- + 2 files changed, 3 insertions(+), 11 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 0124704d6784..90f033c80fe2 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -274,7 +274,7 @@ LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPaylo + LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView) + : m_pDocView(pDocView), + m_pDrawingArea(gtk_drawing_area_new()), +- m_aTileBuffer(TileBuffer(0,0,0)), ++ m_aTileBuffer(TileBuffer(0,0)), + m_fZoom(1), + m_pOffice(0), + m_pDocument(0), +@@ -1230,13 +1230,11 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, + long nDocumentHeightTwips = pDocView->m_pImpl->m_nDocumentHeightTwips; + long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); + long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); +- // Total number of rows / columns in this document. +- guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); ++ // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + + + pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, +- nRows, + nColumns); + gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, + nDocumentWidthPixels, +@@ -1257,12 +1255,10 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ + pDocView->m_pImpl->m_fZoom = fZoom; + long nDocumentWidthPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips, fZoom); + long nDocumentHeightPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentHeightTwips, fZoom); +- // Total number of rows / columns in this document. +- guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); ++ // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + + pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, +- nRows, + nColumns); + gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, + nDocumentWidthPixels, +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index ea8e52452c8d..b9bf71b950d5 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -83,11 +83,9 @@ class TileBuffer + { + public: + TileBuffer(LibreOfficeKitDocument *document, +- int rows, + int columns) + : m_pLOKDocument(document) + , m_nWidth(columns) +- , m_nHeight(rows) + { } + + ~TileBuffer() {} +@@ -126,8 +124,6 @@ class TileBuffer + std::map m_mTiles; + /// Width of the current tile buffer (number of columns) + int m_nWidth; +- /// Height of the current tile buffer (numbero of rows) +- int m_nHeight; + }; + + #endif // INCLUDED_TILEBUFFER_HXX +-- +2.12.0 + diff --git a/SOURCES/0031-loplugin-literaltoboolconversion.patch b/SOURCES/0031-loplugin-literaltoboolconversion.patch new file mode 100644 index 0000000..97f941b --- /dev/null +++ b/SOURCES/0031-loplugin-literaltoboolconversion.patch @@ -0,0 +1,50 @@ +From d7998a755c226340bfa287bfb5544a61d030f877 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 9 Jun 2015 11:48:12 +0200 +Subject: [PATCH 031/398] loplugin:literaltoboolconversion + +Change-Id: I85fa46de5b864369158d047fd3f7c683f10c822f +(cherry picked from commit 9aa9baa78852dda5c348eb0abdbef98db3e910ed) +--- + libreofficekit/source/gtk/tilebuffer.cxx | 4 ++-- + libreofficekit/source/gtk/tilebuffer.hxx | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 1d6a8b66ec80..2c0ee90e08d4 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -67,7 +67,7 @@ void TileBuffer::setInvalid(int x, int y) + g_info("Setting tile invalid (%d, %d)", x, y); + if (m_mTiles.find(index) != m_mTiles.end()) + { +- m_mTiles[index].valid = 0; ++ m_mTiles[index].valid = false; + m_mTiles[index].release(); + m_mTiles.erase(index); + } +@@ -101,7 +101,7 @@ Tile& TileBuffer::getTile(int x, int y, float aZoom) + + //create a mapping for it + m_mTiles[index].setPixbuf(pPixBuf); +- m_mTiles[index].valid = 1; ++ m_mTiles[index].valid = true; + } + + return m_mTiles[index]; +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index b9bf71b950d5..42c6d35b112b 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -51,7 +51,7 @@ float twipToPixel(float fInput, float zoom); + class Tile + { + public: +- Tile() : valid(0) {} ++ Tile() : valid(false) {} + ~Tile() { } + + /** +-- +2.12.0 + diff --git a/SOURCES/0032-loplugin-unreffun.patch b/SOURCES/0032-loplugin-unreffun.patch new file mode 100644 index 0000000..4ef23d2 --- /dev/null +++ b/SOURCES/0032-loplugin-unreffun.patch @@ -0,0 +1,35 @@ +From c1bffef623d683b311ddbbd78be0fc296d5d2739 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 9 Jun 2015 11:57:56 +0200 +Subject: [PATCH 032/398] loplugin:unreffun + +Change-Id: I2011b491012dfd623ece9fd24a265107ac690cba +(cherry picked from commit 3f0e8bdabed165e09825bc78c55afb968a6d702a) +--- + libreofficekit/source/gtk/lokdocview.cxx | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 90f033c80fe2..137a09b164ce 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -208,9 +208,14 @@ enum + + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + +- ++#ifdef __GNUC__ ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wunused-function" ++#endif + G_DEFINE_TYPE(LOKDocView, lok_doc_view, GTK_TYPE_SCROLLED_WINDOW) +- ++#ifdef __GNUC__ ++#pragma GCC diagnostic pop ++#endif + + namespace { + +-- +2.12.0 + diff --git a/SOURCES/0033-Werror-Wignored-attributes-attribute-declaration-mus.patch b/SOURCES/0033-Werror-Wignored-attributes-attribute-declaration-mus.patch new file mode 100644 index 0000000..02f5504 --- /dev/null +++ b/SOURCES/0033-Werror-Wignored-attributes-attribute-declaration-mus.patch @@ -0,0 +1,36 @@ +From f06969288e43555c5df8da68110c2e2b14b2bfae Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 9 Jun 2015 11:58:24 +0200 +Subject: [PATCH 033/398] -Werror,-Wignored-attributes ("attribute declaration + must precede definition") + +Change-Id: Iee0e9ef3a623706c33f84c34c1fbbf5b173f7f5d +(cherry picked from commit e52bae937032dd5eac14da1d54b045ad9d787b1f) +--- + libreofficekit/source/gtk/lokdocview.cxx | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 137a09b164ce..138c7f82a38f 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -208,6 +208,7 @@ enum + + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + ++SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" +@@ -1196,8 +1197,6 @@ static void lok_doc_view_init (LOKDocView* pDocView) + g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0); + } + +-SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); +- + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new( LibreOfficeKit* pOffice ) + { + LOKDocView* pDocView = LOK_DOC_VIEW(gtk_type_new(lok_doc_view_get_type())); +-- +2.12.0 + diff --git a/SOURCES/0034-loplugin-unreffun-workaround-for-visibility-adding-r.patch b/SOURCES/0034-loplugin-unreffun-workaround-for-visibility-adding-r.patch new file mode 100644 index 0000000..499fc9c --- /dev/null +++ b/SOURCES/0034-loplugin-unreffun-workaround-for-visibility-adding-r.patch @@ -0,0 +1,37 @@ +From daf4c39780b48ee2d9ade4afccd41e3d7efcbeb4 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 9 Jun 2015 12:44:12 +0200 +Subject: [PATCH 034/398] loplugin:unreffun: workaround for visibility-adding + redecls + +Change-Id: Ic18b44942f4fe02083c0e8167e8c8d4205e66abf +(cherry picked from commit 623359af236ab8497d4fac34e112a8b9b7b291f2) +--- + compilerplugins/clang/unreffun.cxx | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/compilerplugins/clang/unreffun.cxx b/compilerplugins/clang/unreffun.cxx +index 3b9c616414b3..5295ca4376b0 100644 +--- a/compilerplugins/clang/unreffun.cxx ++++ b/compilerplugins/clang/unreffun.cxx +@@ -87,6 +87,17 @@ bool UnrefFun::VisitFunctionDecl(FunctionDecl const * decl) { + { + Decl const * prev = getPreviousNonFriendDecl(decl); + if (prev != nullptr/* && prev != decl->getPrimaryTemplate()*/) { ++ // Workaround for redeclarations that introduce visiblity attributes ++ // (as is done with ++ // ++ // SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); ++ // ++ // in libreofficekit/source/gtk/lokdocview.cxx): ++ if (decl->getAttr() != nullptr ++ && prev->getAttr() == nullptr) ++ { ++ return true; ++ } + report( + DiagnosticsEngine::Warning, + "redundant function%0 redeclaration", decl->getLocation()) +-- +2.12.0 + diff --git a/SOURCES/0035-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch b/SOURCES/0035-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch new file mode 100644 index 0000000..1c0bc4a --- /dev/null +++ b/SOURCES/0035-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch @@ -0,0 +1,39 @@ +From 2ef24d89daeea0b549132b6c31606bcda9571d13 Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Tue, 9 Jun 2015 22:19:40 -0400 +Subject: [PATCH 035/398] sw: LOK_CALLBACK_CURSOR_VISIBLE callback. + +Change-Id: Ibf62a9d46df7d56dda737b4671d79b59bd01d35a +(cherry picked from commit 698b344fdf42cc9738d5e91cd27876ce1ff39daf) +--- + sw/source/core/crsr/viscrs.cxx | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx +index 3e92ce5ef4e5..9077a6533625 100644 +--- a/sw/source/core/crsr/viscrs.cxx ++++ b/sw/source/core/crsr/viscrs.cxx +@@ -90,7 +90,10 @@ void SwVisCrsr::Show() + + // display at all? + if( m_pCrsrShell->VisArea().IsOver( m_pCrsrShell->m_aCharRect ) || m_pCrsrShell->isTiledRendering() ) ++ { ++ m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(true).getStr()); + _SetPosAndShow(); ++ } + } + } + +@@ -102,6 +105,9 @@ void SwVisCrsr::Hide() + + if( m_aTextCrsr.IsVisible() ) // Shouldn't the flags be in effect? + m_aTextCrsr.Hide(); ++ ++ if( m_pCrsrShell->isTiledRendering() ) ++ m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(false).getStr()); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0036-sw-tiled-rendering-set-minimal-window-size.patch b/SOURCES/0036-sw-tiled-rendering-set-minimal-window-size.patch new file mode 100644 index 0000000..7acc611 --- /dev/null +++ b/SOURCES/0036-sw-tiled-rendering-set-minimal-window-size.patch @@ -0,0 +1,37 @@ +From 8bc21ff727beb36e68076995cc642ac98296b689 Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Tue, 9 Jun 2015 23:19:40 -0400 +Subject: [PATCH 036/398] sw: tiled rendering, set minimal window size. + +Set minimal window size (1,1), so it can trigger +LOK_CALLBACK_INVALIDATE_TILES + +Change-Id: If6ef9aeec94b396febd41375b3ce96b1aa1d6115 +(cherry picked from commit 2281a4922f2209511f79b961ca2140c112bc41eb) +--- + sw/source/uibase/uno/unotxdoc.cxx | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index c19976c05289..450650d26c13 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3164,6 +3164,15 @@ void SwXTextDocument::initializeForTiledRendering() + SwViewShell* pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell(); + pViewShell->setTiledRendering(true); + ++ if ( pViewShell->GetWin() ) ++ { ++ // Check initial window size and set minimal size (1,1) ++ Size aSize( pViewShell->GetWin()->GetOutputSizePixel() ); ++ if ( aSize.Width() == 0 || aSize.Height() == 0 ) ++ pViewShell->GetWin()->SetOutputSizePixel(Size( std::max( aSize.Width() , long(1)), ++ std::max( aSize.Height(), long(1)) )); ++ } ++ + bool bBookMode = false; + sal_Int16 nColumns = 1; + +-- +2.12.0 + diff --git a/SOURCES/0037-Revert-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch b/SOURCES/0037-Revert-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch new file mode 100644 index 0000000..373177a --- /dev/null +++ b/SOURCES/0037-Revert-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch @@ -0,0 +1,41 @@ +From d21589ed079bae79f24bbaf9dce8a691cdedb47e Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Wed, 10 Jun 2015 14:16:09 -0400 +Subject: [PATCH 037/398] Revert sw: LOK_CALLBACK_CURSOR_VISIBLE callback. + +Already fixed by Miklos Vajna. + +Change-Id: I848f2296c5f5a4d250308ed3a851c46524181340 +(cherry picked from commit 533a5fdad3854b89a252216bb78a38ba3222964b) +--- + sw/source/core/crsr/viscrs.cxx | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx +index 9077a6533625..3e92ce5ef4e5 100644 +--- a/sw/source/core/crsr/viscrs.cxx ++++ b/sw/source/core/crsr/viscrs.cxx +@@ -90,10 +90,7 @@ void SwVisCrsr::Show() + + // display at all? + if( m_pCrsrShell->VisArea().IsOver( m_pCrsrShell->m_aCharRect ) || m_pCrsrShell->isTiledRendering() ) +- { +- m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(true).getStr()); + _SetPosAndShow(); +- } + } + } + +@@ -105,9 +102,6 @@ void SwVisCrsr::Hide() + + if( m_aTextCrsr.IsVisible() ) // Shouldn't the flags be in effect? + m_aTextCrsr.Hide(); +- +- if( m_pCrsrShell->isTiledRendering() ) +- m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(false).getStr()); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0038-CID-1306215-Uninitialized-members.patch b/SOURCES/0038-CID-1306215-Uninitialized-members.patch new file mode 100644 index 0000000..ed2da13 --- /dev/null +++ b/SOURCES/0038-CID-1306215-Uninitialized-members.patch @@ -0,0 +1,27 @@ +From 07cdc487ae95079d11ce314d1416a028f585e5c5 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 12 Jun 2015 11:23:37 +0200 +Subject: [PATCH 038/398] CID#1306215 Uninitialized members + +Change-Id: Ib1ff285d1f8180ecb0be8448ac4c2d1878dff274 +(cherry picked from commit 90f9e09a176d9c9df3d79a057a27c34d441608df) +--- + libreofficekit/source/gtk/tilebuffer.hxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 42c6d35b112b..6e6c0beb48f3 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -51,7 +51,7 @@ float twipToPixel(float fInput, float zoom); + class Tile + { + public: +- Tile() : valid(false) {} ++ Tile() : valid(false), m_pBuffer(0) {} + ~Tile() { } + + /** +-- +2.12.0 + diff --git a/SOURCES/0039-lokdocview-Change-parent-class-to-GtkDrawingArea.patch b/SOURCES/0039-lokdocview-Change-parent-class-to-GtkDrawingArea.patch new file mode 100644 index 0000000..174a343 --- /dev/null +++ b/SOURCES/0039-lokdocview-Change-parent-class-to-GtkDrawingArea.patch @@ -0,0 +1,487 @@ +From bedd656e03b025673473d43d556e11fead29f186 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 9 Jun 2015 16:27:37 +0530 +Subject: [PATCH 039/398] lokdocview: Change parent class to GtkDrawingArea + +It is not the job of the widget to provide the scroll bars. + +Change-Id: Iafc5724ed5b21717d711bb8f7e1a076dd1288b76 +(cherry picked from commit 8d0b34c3a6292ce9c5a081ef95890ae0c5e07ac7) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 22 ++- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 27 ++- + libreofficekit/source/gtk/lokdocview.cxx | 207 +++++++++------------ + 3 files changed, 127 insertions(+), 129 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index e84feee9bd57..24c577e6e003 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -31,21 +31,23 @@ typedef struct _LOKDocViewClass LOKDocViewClass; + + struct _LOKDocView + { +- GtkScrolledWindow aScrollWindow; ++ GtkDrawingArea aDrawingArea; + struct LOKDocView_Impl* m_pImpl; + }; + + struct _LOKDocViewClass + { +- GtkScrolledWindowClass parent_class; +- void (* edit_changed) (LOKDocView* pView, gboolean was_edit); +- void (* command_changed) (LOKDocView* pView, char* new_state); +- void (* search_not_found) (LOKDocView* pView, char* new_state); +- void (* part_changed) (LOKDocView* pView, int new_part); ++ GtkDrawingAreaClass parent_class; ++ void (* edit_changed) (LOKDocView* pView, gboolean was_edit); ++ void (* command_changed) (LOKDocView* pView, char* new_state); ++ void (* search_not_found) (LOKDocView* pView, char* new_state); ++ void (* part_changed) (LOKDocView* pView, int new_part); + }; + + GType lok_doc_view_get_type (void) G_GNUC_CONST; ++ + GtkWidget* lok_doc_view_new (LibreOfficeKit* pOffice ); ++ + gboolean lok_doc_view_open_document (LOKDocView* pDocView, + char* pPath); + +@@ -80,9 +82,11 @@ void lok_doc_view_post_key (GtkWidget* p + GdkEventKey* pEvent, + gpointer pData); + +-/// Get the visible area of the document (in twips). +-void lok_doc_view_get_visarea (LOKDocView* pThis, +- GdkRectangle* pArea); ++float lok_doc_view_pixel_to_twip (LOKDocView* pDocView, ++ float fInput); ++ ++float lok_doc_view_twip_to_pixel (LOKDocView* pDocView, ++ float fInput); + + G_END_DECLS + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 38b29ee40a3b..c8b47f7c7142 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -38,6 +38,7 @@ static GtkToolItem* pBold; + static GtkToolItem* pItalic; + static GtkToolItem* pUnderline; + static GtkToolItem* pStrikethrough; ++static GtkWidget* pScrolledWindow; + std::map g_aToolItemCommandNames; + std::map g_aCommandNameToolItems; + bool g_bToolItemBroadcast = true; +@@ -134,6 +135,23 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + #endif + } + ++/// Get the visible area of the scrolled window ++static void getVisibleAreaTwips(GdkRectangle* pArea) ++{ ++ GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ ++ pArea->x = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_value(pHAdjustment)); ++ pArea->y = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_value(pVAdjustment)); ++ pArea->width = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_page_size(pHAdjustment)); ++ pArea->height = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_page_size(pVAdjustment)); ++} ++ ++ + /// Handles the key-press-event of the window. + static gboolean signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData) + { +@@ -161,7 +179,7 @@ static void doSearch(bool bBackwards) + + LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); + GdkRectangle aArea; +- lok_doc_view_get_visarea(pLOKDocView, &aArea); ++ getVisibleAreaTwips(&aArea); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/type", '/'), "long"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/value", '/'), aArea.x); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/type", '/'), "long"); +@@ -461,7 +479,12 @@ int main( int argc, char* argv[] ) + g_signal_connect(pWindow, "key-press-event", G_CALLBACK(signalKey), pDocView); + g_signal_connect(pWindow, "key-release-event", G_CALLBACK(signalKey), pDocView); + +- gtk_container_add( GTK_CONTAINER(pVBox), pDocView ); ++ // Scrolled window for DocView ++ pScrolledWindow = gtk_scrolled_window_new(0, 0); ++ gtk_container_add(GTK_CONTAINER(pVBox), pScrolledWindow); ++ ++ // DocView doesn't have scrolling capability, so need a viewport ++ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(pScrolledWindow), pDocView); + + gtk_widget_show_all( pWindow ); + // Hide the findbar by default. +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 138c7f82a38f..02b8710e167b 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -41,7 +41,6 @@ + struct LOKDocView_Impl + { + LOKDocView* m_pDocView; +- GtkWidget *m_pDrawingArea; + TileBuffer m_aTileBuffer; + + float m_fZoom; +@@ -119,7 +118,7 @@ struct LOKDocView_Impl + /// Connected to the destroy signal of LOKDocView, deletes its LOKDocView_Impl. + static void destroy(LOKDocView* pDocView, gpointer pData); + /// Connected to the expose-event of the GtkDrawingArea +- static void on_exposed(GtkWidget *widget, GdkEvent *event, gpointer user_data); ++ static void onExposed(GtkWidget *widget, GdkEventExpose *event, gpointer user_data); + /// Receives a key press or release event. + void signalKey(GdkEventKey* pEvent); + /** +@@ -156,16 +155,8 @@ struct LOKDocView_Impl + static gboolean handleTimeout(gpointer pData); + /// Implementation of the timeout handler, invoked by handleTimeout(). + gboolean handleTimeoutImpl(); +- /** +- * Renders the document to a number of visible tiles. +- * +- * This method is invoked only manually, not when some Gtk signal is +- * emitted. +- * +- * @param pPartial if 0, then the full visible document is rendered, otherwise only +- * the tiles that intersect with pPartial. +- */ +- void renderDocument(GdkRectangle* pPartial); ++ /// Implementation of expose event handler, invoked by onExposed(). ++ void onExposedImpl(GdkEventExpose* event); + /// Returns the GdkRectangle of a x,y,width,height string. + GdkRectangle payloadToRectangle(const char* pPayload); + /// Returns the GdkRectangles of a x1,y1,w1,h1;x2,y2,w2,h2;... string. +@@ -213,7 +204,7 @@ SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + #endif +-G_DEFINE_TYPE(LOKDocView, lok_doc_view, GTK_TYPE_SCROLLED_WINDOW) ++G_DEFINE_TYPE(LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA) + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif +@@ -279,7 +270,6 @@ LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPaylo + + LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView) + : m_pDocView(pDocView), +- m_pDrawingArea(gtk_drawing_area_new()), + m_aTileBuffer(TileBuffer(0,0)), + m_fZoom(1), + m_pOffice(0), +@@ -328,10 +318,70 @@ void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/) + delete pDocView->m_pImpl; + } + +-void LOKDocView_Impl::on_exposed(GtkWidget* /*widget*/, GdkEvent* /*event*/, gpointer userdata) ++void LOKDocView_Impl::onExposed(GtkWidget* /*widget*/, GdkEventExpose* event, gpointer userdata) + { + LOKDocView *pDocView = LOK_DOC_VIEW (userdata); +- pDocView->m_pImpl->renderDocument(0); ++ pDocView->m_pImpl->onExposedImpl(event); ++} ++ ++void LOKDocView_Impl::onExposedImpl(GdkEventExpose* event) ++{ ++ long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips, m_fZoom); ++ long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips, m_fZoom); ++ // Total number of rows / columns in this document. ++ guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); ++ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); ++ GdkRectangle aVisibleArea = event->area; ++ cairo_t *pcairo = gdk_cairo_create(GTK_WIDGET(m_pDocView)->window); ++ ++ aVisibleArea.x = pixelToTwip (aVisibleArea.x, m_fZoom); ++ aVisibleArea.y = pixelToTwip (aVisibleArea.y, m_fZoom); ++ aVisibleArea.width = pixelToTwip (aVisibleArea.width, m_fZoom); ++ aVisibleArea.height = pixelToTwip (aVisibleArea.height, m_fZoom); ++ ++ // Render the tiles. ++ for (guint nRow = 0; nRow < nRows; ++nRow) ++ { ++ for (guint nColumn = 0; nColumn < nColumns; ++nColumn) ++ { ++ GdkRectangle aTileRectangleTwips, aTileRectanglePixels; ++ bool bPaint = true; ++ ++ // Determine size of the tile: the rightmost/bottommost tiles may ++ // be smaller, and we need the size to decide if we need to repaint. ++ if (nColumn == nColumns - 1) ++ aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels; ++ else ++ aTileRectanglePixels.width = nTileSizePixels; ++ if (nRow == nRows - 1) ++ aTileRectanglePixels.height = nDocumentHeightPixels - nRow * nTileSizePixels; ++ else ++ aTileRectanglePixels.height = nTileSizePixels; ++ ++ // Determine size and position of the tile in document coordinates, ++ // so we can decide if we can skip painting for partial rendering. ++ aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, m_fZoom) * nColumn; ++ aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, m_fZoom) * nRow; ++ aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, m_fZoom); ++ aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, m_fZoom); ++ ++ if (!gdk_rectangle_intersect(&aVisibleArea, &aTileRectangleTwips, 0)) ++ bPaint = false; ++ ++ if (bPaint) ++ { ++ Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn, m_fZoom); ++ GdkPixbuf* pPixBuf = currentTile.getBuffer(); ++ ++ gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, ++ twipToPixel(aTileRectangleTwips.x, m_fZoom), ++ twipToPixel(aTileRectangleTwips.y, m_fZoom)); ++ cairo_paint(pcairo); ++ } ++ } ++ } ++ ++ cairo_destroy(pcairo); + } + + void LOKDocView_Impl::signalKey(GdkEventKey* pEvent) +@@ -798,75 +848,12 @@ gboolean LOKDocView_Impl::handleTimeoutImpl() + m_bCursorOverlayVisible = false; + else + m_bCursorOverlayVisible = true; +- gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); + } + + return G_SOURCE_CONTINUE; + } + +-void LOKDocView_Impl::renderDocument(GdkRectangle* pPartial) +-{ +- GdkRectangle visibleArea; +- lok_doc_view_get_visarea (m_pDocView, &visibleArea); +- +- long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips, m_fZoom); +- long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips, m_fZoom); +- // Total number of rows / columns in this document. +- guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); +- guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +- +- cairo_t *pcairo = gdk_cairo_create(m_pDrawingArea->window); +- +- // Render the tiles. +- for (guint nRow = 0; nRow < nRows; ++nRow) +- { +- for (guint nColumn = 0; nColumn < nColumns; ++nColumn) +- { +- GdkRectangle aTileRectangleTwips, aTileRectanglePixels; +- bool bPaint = true; +- +- // Determine size of the tile: the rightmost/bottommost tiles may +- // be smaller, and we need the size to decide if we need to repaint. +- if (nColumn == nColumns - 1) +- aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels; +- else +- aTileRectanglePixels.width = nTileSizePixels; +- if (nRow == nRows - 1) +- aTileRectanglePixels.height = nDocumentHeightPixels - nRow * nTileSizePixels; +- else +- aTileRectanglePixels.height = nTileSizePixels; +- +- // Determine size and position of the tile in document coordinates, +- // so we can decide if we can skip painting for partial rendering. +- aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, m_fZoom) * nColumn; +- aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, m_fZoom) * nRow; +- aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, m_fZoom); +- aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, m_fZoom); +- if (pPartial && !gdk_rectangle_intersect(pPartial, &aTileRectangleTwips, 0)) +- bPaint = false; +- +- if (!gdk_rectangle_intersect(&visibleArea, &aTileRectangleTwips, 0)) +- bPaint = false; +- +- if (bPaint) +- { +- //g_info("tile_buffer_get_tile (%d, %d)", nRow, nColumn); +- +- Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn, m_fZoom); +- GdkPixbuf* pPixBuf = currentTile.getBuffer(); +- +- gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, +- twipToPixel(aTileRectangleTwips.x, m_fZoom), +- twipToPixel(aTileRectangleTwips.y, m_fZoom)); +- cairo_paint(pcairo); +- } +- } +- } +- +- cairo_destroy(pcairo); +-} +- +- + GdkRectangle LOKDocView_Impl::payloadToRectangle(const char* pPayload) + { + GdkRectangle aRet; +@@ -978,14 +965,14 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + else + m_aTileBuffer.resetAllTiles(); + +- gtk_widget_queue_draw(m_pDrawingArea); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); + } + break; + case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: + { + m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + m_bCursorOverlayVisible = true; +- gtk_widget_queue_draw(m_pDrawingArea); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); + } + break; + case LOK_CALLBACK_TEXT_SELECTION: +@@ -1025,7 +1012,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + m_aGraphicSelection = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); + else + memset(&m_aGraphicSelection, 0, sizeof(m_aGraphicSelection)); +- gtk_widget_queue_draw(GTK_WIDGET(m_pDrawingArea)); ++ gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); + } + break; + case LOK_CALLBACK_HYPERLINK_CLICKED: +@@ -1049,7 +1036,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + { + payloadToSize(pCallback->m_aPayload.c_str(), m_nDocumentWidthTwips, m_nDocumentHeightTwips); +- gtk_widget_set_size_request(m_pDrawingArea, ++ gtk_widget_set_size_request(GTK_WIDGET(m_pDocView), + twipToPixel(m_nDocumentWidthTwips, m_fZoom), + twipToPixel(m_nDocumentHeightTwips, m_fZoom)); + } +@@ -1113,7 +1100,6 @@ void LOKDocView_Impl::searchNotFound(const std::string& rString) + void LOKDocView_Impl::setPart(const std::string& rString) + { + g_signal_emit(m_pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString)); +- renderDocument(0); + } + + static void lok_doc_view_class_init (LOKDocViewClass* pClass) +@@ -1163,34 +1149,26 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + + static void lok_doc_view_init (LOKDocView* pDocView) + { +- // Gtk ScrolledWindow is apparently not fully initialised yet, we specifically +- // have to set the [hv]adjustment to prevent GTK assertions from firing, see +- // https://bugzilla.gnome.org/show_bug.cgi?id=438114 for more info. +- gtk_scrolled_window_set_hadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL ); +- gtk_scrolled_window_set_vadjustment( GTK_SCROLLED_WINDOW( pDocView ), NULL ); +- + pDocView->m_pImpl = new LOKDocView_Impl(pDocView); +- gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView), +- pDocView->m_pImpl->m_pDrawingArea ); + +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ g_signal_connect(G_OBJECT(pDocView), + "expose-event", +- G_CALLBACK(LOKDocView_Impl::on_exposed), pDocView); +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ G_CALLBACK(LOKDocView_Impl::onExposed), pDocView); ++ g_signal_connect(G_OBJECT(pDocView), + "expose-event", + G_CALLBACK(LOKDocView_Impl::renderOverlay), pDocView); +- gtk_widget_add_events(pDocView->m_pImpl->m_pDrawingArea, ++ gtk_widget_add_events(GTK_WIDGET(pDocView), + GDK_BUTTON_PRESS_MASK + |GDK_BUTTON_RELEASE_MASK + |GDK_BUTTON_MOTION_MASK); + +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ g_signal_connect(G_OBJECT(pDocView), + "button-press-event", + G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ g_signal_connect(G_OBJECT(pDocView), + "button-release-event", + G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); +- g_signal_connect(G_OBJECT(pDocView->m_pImpl->m_pDrawingArea), ++ g_signal_connect(G_OBJECT(pDocView), + "motion-notify-event", + G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView); + +@@ -1240,10 +1218,9 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, + + pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, + nColumns); +- gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, ++ gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +- pDocView->m_pImpl->renderDocument(0); + } + + return TRUE; +@@ -1264,12 +1241,9 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ + + pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, + nColumns); +- gtk_widget_set_size_request(pDocView->m_pImpl->m_pDrawingArea, ++ gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +- +- if ( pDocView->m_pImpl->m_pDocument ) +- pDocView->m_pImpl->renderDocument(0); + } + + SAL_DLLPUBLIC_EXPORT float lok_doc_view_get_zoom ( LOKDocView* pDocView ) +@@ -1301,7 +1275,6 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_partmode( LOKDocView* pDocView, + int nPartMode ) + { + pDocView->m_pImpl->m_pDocument->pClass->setPartMode( pDocView->m_pImpl->m_pDocument, nPartMode ); +- pDocView->m_pImpl->renderDocument(0); + } + + SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView, +@@ -1318,7 +1291,7 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView, + } + pDocView->m_pImpl->m_bEdit = bEdit; + g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit); +- gtk_widget_queue_draw(GTK_WIDGET(pDocView->m_pImpl->m_pDrawingArea)); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + + SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_get_edit(LOKDocView* pDocView) +@@ -1337,17 +1310,15 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEvent + pDocView->m_pImpl->signalKey(pEvent); + } + +-SAL_DLLPUBLIC_EXPORT void lok_doc_view_get_visarea(LOKDocView* pThis, GdkRectangle* pArea) ++SAL_DLLPUBLIC_EXPORT float lok_doc_view_pixel_to_twip(LOKDocView* pDocView, float fInput) + { +-#if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() +- float zoom = pThis->m_pImpl->m_fZoom; +- GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pThis)); +- pArea->x = pixelToTwip(gtk_adjustment_get_value(pHAdjustment),zoom); +- pArea->width = pixelToTwip(gtk_adjustment_get_page_size(pHAdjustment), zoom); +- GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pThis)); +- pArea->y = pixelToTwip(gtk_adjustment_get_value(pVAdjustment), zoom); +- pArea->height = pixelToTwip(gtk_adjustment_get_page_size(pVAdjustment), zoom); +-#endif ++ return pixelToTwip(fInput, pDocView->m_pImpl->m_fZoom); + } + ++SAL_DLLPUBLIC_EXPORT float lok_doc_view_twip_to_pixel(LOKDocView* pDocView, float fInput) ++{ ++ return twipToPixel(fInput, pDocView->m_pImpl->m_fZoom); ++} ++ ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0040-lokdocview-Make-this-GObject-class-introspectable.patch b/SOURCES/0040-lokdocview-Make-this-GObject-class-introspectable.patch new file mode 100644 index 0000000..75fba91 --- /dev/null +++ b/SOURCES/0040-lokdocview-Make-this-GObject-class-introspectable.patch @@ -0,0 +1,160 @@ +From 2f3948b6155b0d3f40269bbacd267c2d01868c41 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 9 Jun 2015 18:08:59 +0530 +Subject: [PATCH 040/398] lokdocview: Make this GObject class introspectable + +... so that this widget can be used from other languages. + +Change-Id: Icd7d6df6aa587ffdb018af0b911300dc81ec6560 +(cherry picked from commit 97c9a87ac88b18e7bbb72ad218e5ed5cf4f4b2ed) +--- + libreofficekit/source/gtk/lokdocview.cxx | 67 +++++++++++++++++++++++++++++++- + 1 file changed, 65 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 02b8710e167b..c035d0dcad55 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -121,7 +121,7 @@ struct LOKDocView_Impl + static void onExposed(GtkWidget *widget, GdkEventExpose *event, gpointer user_data); + /// Receives a key press or release event. + void signalKey(GdkEventKey* pEvent); +- /** ++ /* + * The user drags the handle, which is below the cursor, but wants to move the + * cursor accordingly. + * +@@ -144,7 +144,7 @@ struct LOKDocView_Impl + gboolean renderOverlayImpl(GtkWidget* pEventBox); + /// Is rRectangle empty? + static bool isEmptyRectangle(const GdkRectangle& rRectangle); +- /** ++ /* + * Renders pHandle below an rCursor rectangle on pCairo. + * @param rRectangle output parameter, the rectangle that contains the rendered handle. + */ +@@ -1175,6 +1175,12 @@ static void lok_doc_view_init (LOKDocView* pDocView) + g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0); + } + ++/** ++ * lok_doc_view_new: ++ * @pOffice: The LibreOfficeKit context. ++ * ++ * Returns: The #LOKDocView widget instance. ++ */ + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new( LibreOfficeKit* pOffice ) + { + LOKDocView* pDocView = LOK_DOC_VIEW(gtk_type_new(lok_doc_view_get_type())); +@@ -1182,6 +1188,13 @@ SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new( LibreOfficeKit* pOffice ) + return GTK_WIDGET( pDocView ); + } + ++/** ++ * lok_doc_view_open_document: ++ * @pDocView: The #LOKDocView instance ++ * @pPath: The path of the document that #LOKDocView widget should try to open ++ * ++ * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise ++ */ + SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, char* pPath ) + { + if ( pDocView->m_pImpl->m_pDocument ) +@@ -1226,11 +1239,24 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, + return TRUE; + } + ++/** ++ * lok_doc_view_get_document: ++ * @pDocView: The #LOKDocView instance ++ * ++ * Returns: The #LibreOfficeKitDocument instance the widget is currently showing ++ */ + SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocView* pDocView) + { + return pDocView->m_pImpl->m_pDocument; + } + ++/** ++ * lok_doc_view_set_zoom: ++ * @pDocView: The #LOKDocView instance ++ * @fZoom: The new zoom level that pDocView must set it into. ++ * ++ * Sets the new zoom level for the widget. ++ */ + SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZoom ) + { + pDocView->m_pImpl->m_fZoom = fZoom; +@@ -1246,6 +1272,12 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ + nDocumentHeightPixels); + } + ++/** ++ * lok_doc_view_get_zoom: ++ * @pDocView: The #LOKDocView instance ++ * ++ * Returns: The current zoom factor value in float for pDocView ++ */ + SAL_DLLPUBLIC_EXPORT float lok_doc_view_get_zoom ( LOKDocView* pDocView ) + { + return pDocView->m_pImpl->m_fZoom; +@@ -1277,6 +1309,13 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_partmode( LOKDocView* pDocView, + pDocView->m_pImpl->m_pDocument->pClass->setPartMode( pDocView->m_pImpl->m_pDocument, nPartMode ); + } + ++/** ++ * lok_doc_view_set_edit: ++ * @pDocView: The #LOKDocView instance ++ * @bEdit: %TRUE if the pDocView should go in edit mode, %FALSE otherwise ++ * ++ * Sets the edit-mode for pDocView ++ */ + SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView, + gboolean bEdit ) + { +@@ -1294,6 +1333,12 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView, + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + ++/** ++ * lok_doc_view_get_edit: ++ * @pDocView: The #LOKDocView instance ++ * ++ * Returns: %TRUE if the given pDocView is in edit mode. ++ */ + SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_get_edit(LOKDocView* pDocView) + { + return pDocView->m_pImpl->m_bEdit; +@@ -1310,11 +1355,29 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEvent + pDocView->m_pImpl->signalKey(pEvent); + } + ++/** ++ * lok_doc_view_pixel_to_twip: ++ * @pDocView: The #LOKDocView instance ++ * @fInput: The value in pixels to convert to twips ++ * ++ * Converts the value in pixels to twips according to zoom level. ++ * ++ * Returns: The corresponding value in twips ++ */ + SAL_DLLPUBLIC_EXPORT float lok_doc_view_pixel_to_twip(LOKDocView* pDocView, float fInput) + { + return pixelToTwip(fInput, pDocView->m_pImpl->m_fZoom); + } + ++/** ++ * lok_doc_view_twip_to_pixel: ++ * @pDocView: The #LOKDocView instance ++ * @fInput: The value in twips to convert to pixels ++ * ++ * Converts the value in twips to pixels according to zoom level. ++ * ++ * Returns: The corresponding value in pixels ++ */ + SAL_DLLPUBLIC_EXPORT float lok_doc_view_twip_to_pixel(LOKDocView* pDocView, float fInput) + { + return twipToPixel(fInput, pDocView->m_pImpl->m_fZoom); +-- +2.12.0 + diff --git a/SOURCES/0041-lokdocview-Create-LOK-context-inside-of-lok_doc_view.patch b/SOURCES/0041-lokdocview-Create-LOK-context-inside-of-lok_doc_view.patch new file mode 100644 index 0000000..1f3b762 --- /dev/null +++ b/SOURCES/0041-lokdocview-Create-LOK-context-inside-of-lok_doc_view.patch @@ -0,0 +1,135 @@ +From cb4dc8447179758aa6e8330fdff7c67b72c9b2da Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 10 Jun 2015 16:10:19 +0530 +Subject: [PATCH 041/398] lokdocview: Create LOK context inside of + lok_doc_view_new + +Change-Id: I675192d6bd6d10e6c7974a5de6f488f9a087ac32 +(cherry picked from commit 7a9dc7fd35168e1f44fb0aa23c984f90163db621) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 2 +- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 15 ++++----------- + libreofficekit/source/gtk/lokdocview.cxx | 14 ++++++++++---- + 3 files changed, 15 insertions(+), 16 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 24c577e6e003..bdd2e9ab90e3 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -46,7 +46,7 @@ struct _LOKDocViewClass + + GType lok_doc_view_get_type (void) G_GNUC_CONST; + +-GtkWidget* lok_doc_view_new (LibreOfficeKit* pOffice ); ++GtkWidget* lok_doc_view_new (const char* pPath); + + gboolean lok_doc_view_open_document (LOKDocView* pDocView, + char* pPath); +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index c8b47f7c7142..4f74583f52b3 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -19,7 +19,6 @@ + #include + + #include +-#include + #include + + #ifndef g_info +@@ -53,8 +52,6 @@ GtkWidget* pFindbar; + GtkWidget* pFindbarEntry; + GtkWidget* pFindbarLabel; + +-static LibreOfficeKit* pOffice; +- + static void lcl_registerToolItem(GtkToolItem* pItem, const std::string& rName) + { + g_aToolItemCommandNames[pItem] = rName; +@@ -361,10 +358,6 @@ int main( int argc, char* argv[] ) + return 1; + } + +- pOffice = lok_init( argv[1] ); +- if ( pOffice == NULL ) +- return 1; +- + gtk_init( &argc, &argv ); + + GtkWidget *pWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL ); +@@ -469,7 +462,9 @@ int main( int argc, char* argv[] ) + gtk_box_pack_end(GTK_BOX(pVBox), pFindbar, FALSE, FALSE, 0); + + // Docview +- pDocView = lok_doc_view_new( pOffice ); ++ pDocView = lok_doc_view_new(argv[1]); ++ if (pDocView == NULL) ++ g_error ("Error while creating LOKDocView widget"); + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); +@@ -492,7 +487,7 @@ int main( int argc, char* argv[] ) + + int bOpened = lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2] ); + if (!bOpened) +- g_error("main: lok_doc_view_open_document() failed with '%s'", pOffice->pClass->getError(pOffice)); ++ g_error("main: lok_doc_view_open_document() failed"); + assert(lok_doc_view_get_document(LOK_DOC_VIEW(pDocView))); + + // GtkComboBox requires gtk 2.24 or later +@@ -507,8 +502,6 @@ int main( int argc, char* argv[] ) + + gtk_main(); + +- pOffice->pClass->destroy( pOffice ); +- + return 0; + } + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index c035d0dcad55..d45ab2db4be5 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -18,6 +18,7 @@ + #include + #define LOK_USE_UNSTABLE_API + #include ++#include + #include + #include + #include +@@ -308,7 +309,10 @@ LOKDocView_Impl::~LOKDocView_Impl() + { + if (m_pDocument) + m_pDocument->pClass->destroy(m_pDocument); ++ if (m_pOffice) ++ m_pOffice->pClass->destroy(m_pOffice); + m_pDocument = 0; ++ m_pOffice = 0; + } + + void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/) +@@ -1177,14 +1181,16 @@ static void lok_doc_view_init (LOKDocView* pDocView) + + /** + * lok_doc_view_new: +- * @pOffice: The LibreOfficeKit context. ++ * @pPath: LibreOffice install path. + * + * Returns: The #LOKDocView widget instance. + */ +-SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new( LibreOfficeKit* pOffice ) ++SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new(const char* pPath) + { +- LOKDocView* pDocView = LOK_DOC_VIEW(gtk_type_new(lok_doc_view_get_type())); +- pDocView->m_pImpl->m_pOffice = pOffice; ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_object_new(LOK_TYPE_DOC_VIEW, NULL)); ++ pDocView->m_pImpl->m_pOffice = lok_init (pPath); ++ if (pDocView->m_pImpl->m_pOffice == NULL) ++ return NULL; + return GTK_WIDGET( pDocView ); + } + +-- +2.12.0 + diff --git a/SOURCES/0042-Fix-RHEL5-build.patch b/SOURCES/0042-Fix-RHEL5-build.patch new file mode 100644 index 0000000..bf7f25c --- /dev/null +++ b/SOURCES/0042-Fix-RHEL5-build.patch @@ -0,0 +1,34 @@ +From fb4b7c191098c0fca7255860e5835798b9fed4c3 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 12 Jun 2015 15:45:16 +0200 +Subject: [PATCH 042/398] Fix RHEL5 build + +Change-Id: I9a71ee85d2d28aed5bd3f4d1f6e91261a9228d04 +(cherry picked from commit e6c37fdee5ddd35460aacca401bf581d021384d9) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 4f74583f52b3..2ce541d1ba84 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -135,6 +135,7 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + /// Get the visible area of the scrolled window + static void getVisibleAreaTwips(GdkRectangle* pArea) + { ++#if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); + +@@ -146,6 +147,7 @@ static void getVisibleAreaTwips(GdkRectangle* pArea) + gtk_adjustment_get_page_size(pHAdjustment)); + pArea->height = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), + gtk_adjustment_get_page_size(pVAdjustment)); ++#endif + } + + +-- +2.12.0 + diff --git a/SOURCES/0043-cppcheck-postfixOperator.patch b/SOURCES/0043-cppcheck-postfixOperator.patch new file mode 100644 index 0000000..79ecc27 --- /dev/null +++ b/SOURCES/0043-cppcheck-postfixOperator.patch @@ -0,0 +1,27 @@ +From c454caba0eae7818a243f1aebca85d665cf981c9 Mon Sep 17 00:00:00 2001 +From: Julien Nabet +Date: Sun, 14 Jun 2015 09:09:52 +0200 +Subject: [PATCH 043/398] cppcheck: postfixOperator + +Change-Id: Ia17bdf6e8f871d64add358822ea383236ecd6405 +(cherry picked from commit 01a189abcd9a4ca472a74b3b2c000c9338fc2c91) +--- + libreofficekit/source/gtk/tilebuffer.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 2c0ee90e08d4..3f22f983d2ab 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -54,7 +54,7 @@ void Tile::setPixbuf(GdkPixbuf *buffer) + void TileBuffer::resetAllTiles() + { + std::map::iterator it = m_mTiles.begin(); +- for (; it != m_mTiles.end(); it++) ++ for (; it != m_mTiles.end(); ++it) + { + it->second.release(); + } +-- +2.12.0 + diff --git a/SOURCES/0044-Typo.patch b/SOURCES/0044-Typo.patch new file mode 100644 index 0000000..9caa463 --- /dev/null +++ b/SOURCES/0044-Typo.patch @@ -0,0 +1,27 @@ +From 134a73259bc4d4f7e61921001ec5549f071e6050 Mon Sep 17 00:00:00 2001 +From: Tor Lillqvist +Date: Mon, 15 Jun 2015 12:37:27 +0300 +Subject: [PATCH 044/398] Typo + +Change-Id: Ibecfa73dd1b865edba77caf51f5003d1b18692be +(cherry picked from commit a0e10b1e0863b1967ede25053f8e3f1dacf0fbdf) +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index bdcc2f0c256f..7038e5fc8cc2 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -119,7 +119,7 @@ typedef enum + * document, the status indicator callbacks will arrive to the callback + * registered for the LibreOfficeKit (singleton) object, not a + * LibreOfficeKitDocument one, because we are in the very progress of +- * loading a docuemnt and then constructing a LibreOfficeKitDocument ++ * loading a document and then constructing a LibreOfficeKitDocument + * object. + */ + LOK_CALLBACK_STATUS_INDICATOR_START, +-- +2.12.0 + diff --git a/SOURCES/0045-lokdocview-gtktiledviewer-Port-to-gtk3.patch b/SOURCES/0045-lokdocview-gtktiledviewer-Port-to-gtk3.patch new file mode 100644 index 0000000..e94a996 --- /dev/null +++ b/SOURCES/0045-lokdocview-gtktiledviewer-Port-to-gtk3.patch @@ -0,0 +1,184 @@ +From 29a8e23e7d96689c46299af1ab56c4c3d50d8fb0 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 10 Jun 2015 16:18:06 +0530 +Subject: [PATCH 045/398] lokdocview, gtktiledviewer: Port to gtk3 + +Change-Id: I57f2d7b9383790e5c34fc517a905dd537519598f +(cherry picked from commit 9b3679301fe4ec4c972b68ef2cbbdd23cbc79053) +--- + libreofficekit/Executable_gtktiledviewer.mk | 9 +++++++- + libreofficekit/Library_libreofficekitgtk.mk | 12 +++++++---- + libreofficekit/Module_libreofficekit.mk | 4 ++-- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 6 ++---- + libreofficekit/source/gtk/lokdocview.cxx | 24 ++++++++++------------ + 5 files changed, 31 insertions(+), 24 deletions(-) + +diff --git a/libreofficekit/Executable_gtktiledviewer.mk b/libreofficekit/Executable_gtktiledviewer.mk +index 8a5206854cca..31028a67fafb 100644 +--- a/libreofficekit/Executable_gtktiledviewer.mk ++++ b/libreofficekit/Executable_gtktiledviewer.mk +@@ -16,7 +16,14 @@ $(eval $(call gb_Executable_set_include,gtktiledviewer,\ + + $(eval $(call gb_Executable_use_externals,gtktiledviewer,\ + boost_headers \ +- gtk \ ++)) ++ ++$(eval $(call gb_Executable_add_cxxflags,gtktiledviewer,\ ++ $$(GTK3_CFLAGS) \ ++)) ++ ++$(eval $(call gb_Executable_add_libs,gtktiledviewer,\ ++ $(GTK3_LIBS) \ + )) + + $(eval $(call gb_Executable_use_libraries,gtktiledviewer,\ +diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk +index 92409537f4e8..71a77e9e36a3 100644 +--- a/libreofficekit/Library_libreofficekitgtk.mk ++++ b/libreofficekit/Library_libreofficekitgtk.mk +@@ -11,15 +11,19 @@ $(eval $(call gb_Library_Library,libreofficekitgtk)) + + $(eval $(call gb_Library_use_sdk_api,libreofficekitgtk)) + +-$(eval $(call gb_Library_use_externals,libreofficekitgtk,\ +- gtk \ +-)) +- + $(eval $(call gb_Library_add_exception_objects,libreofficekitgtk,\ + libreofficekit/source/gtk/lokdocview \ + libreofficekit/source/gtk/tilebuffer \ + )) + ++$(eval $(call gb_Library_add_cxxflags,libreofficekitgtk,\ ++ $$(GTK3_CFLAGS) \ ++)) ++ ++$(eval $(call gb_Library_add_libs,libreofficekitgtk,\ ++ $(GTK3_LIBS) \ ++)) ++ + ifeq ($(OS),LINUX) + $(eval $(call gb_Library_add_libs,libreofficekitgtk,\ + -ldl \ +diff --git a/libreofficekit/Module_libreofficekit.mk b/libreofficekit/Module_libreofficekit.mk +index 000c2fe7457b..217ecb22ff33 100644 +--- a/libreofficekit/Module_libreofficekit.mk ++++ b/libreofficekit/Module_libreofficekit.mk +@@ -15,7 +15,7 @@ $(eval $(call gb_Module_add_subsequentcheck_targets,libreofficekit,\ + CppunitTest_libreofficekit_tiledrendering \ + )) + +-ifneq ($(ENABLE_GTK),) ++ifneq ($(ENABLE_GTK3),) + $(eval $(call gb_Module_add_targets,libreofficekit,\ + Library_libreofficekitgtk \ + Executable_gtktiledviewer \ +@@ -24,7 +24,7 @@ $(eval $(call gb_Module_add_targets,libreofficekit,\ + $(eval $(call gb_Module_add_targets,libreofficekit,\ + Executable_tilebench \ + )) +-endif # ($(ENABLE_GTK),) ++endif # ($(ENABLE_GTK3),) + + endif # ($(OS),LINUX) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 2ce541d1ba84..1f77f1be6c4d 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -14,9 +14,7 @@ + #include + + #include +-#include + #include +-#include + + #include + #include +@@ -208,13 +206,13 @@ static gboolean signalFindbar(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpoin + gtk_label_set_text(GTK_LABEL(pFindbarLabel), ""); + switch(pEvent->keyval) + { +- case GDK_Return: ++ case GDK_KEY_Return: + { + // Search forward. + doSearch(/*bBackwards=*/false); + return TRUE; + } +- case GDK_Escape: ++ case GDK_KEY_Escape: + { + // Hide the findbar. + gtk_widget_hide(pFindbar); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d45ab2db4be5..cd05d0ebbdb9 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -13,8 +13,6 @@ + #include + #include + +-#include +- + #include + #define LOK_USE_UNSTABLE_API + #include +@@ -336,7 +334,7 @@ void LOKDocView_Impl::onExposedImpl(GdkEventExpose* event) + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + GdkRectangle aVisibleArea = event->area; +- cairo_t *pcairo = gdk_cairo_create(GTK_WIDGET(m_pDocView)->window); ++ cairo_t *pcairo = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(m_pDocView))); + + aVisibleArea.x = pixelToTwip (aVisibleArea.x, m_fZoom); + aVisibleArea.y = pixelToTwip (aVisibleArea.y, m_fZoom); +@@ -401,33 +399,33 @@ void LOKDocView_Impl::signalKey(GdkEventKey* pEvent) + + switch (pEvent->keyval) + { +- case GDK_BackSpace: ++ case GDK_KEY_BackSpace: + nKeyCode = com::sun::star::awt::Key::BACKSPACE; + break; +- case GDK_Return: ++ case GDK_KEY_Return: + nKeyCode = com::sun::star::awt::Key::RETURN; + break; +- case GDK_Escape: ++ case GDK_KEY_Escape: + nKeyCode = com::sun::star::awt::Key::ESCAPE; + break; +- case GDK_Tab: ++ case GDK_KEY_Tab: + nKeyCode = com::sun::star::awt::Key::TAB; + break; +- case GDK_Down: ++ case GDK_KEY_Down: + nKeyCode = com::sun::star::awt::Key::DOWN; + break; +- case GDK_Up: ++ case GDK_KEY_Up: + nKeyCode = com::sun::star::awt::Key::UP; + break; +- case GDK_Left: ++ case GDK_KEY_Left: + nKeyCode = com::sun::star::awt::Key::LEFT; + break; +- case GDK_Right: ++ case GDK_KEY_Right: + nKeyCode = com::sun::star::awt::Key::RIGHT; + break; + default: +- if (pEvent->keyval >= GDK_F1 && pEvent->keyval <= GDK_F26) +- nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_F1); ++ if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26) ++ nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_KEY_F1); + else + nCharCode = gdk_keyval_to_unicode(pEvent->keyval); + } +-- +2.12.0 + diff --git a/SOURCES/0046-lokdocview-Port-to-gtk3-expose-event-draw.patch b/SOURCES/0046-lokdocview-Port-to-gtk3-expose-event-draw.patch new file mode 100644 index 0000000..c16e344 --- /dev/null +++ b/SOURCES/0046-lokdocview-Port-to-gtk3-expose-event-draw.patch @@ -0,0 +1,157 @@ +From ad5cffbdf99d9a0605ee2e0c1356099478a2a808 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 10 Jun 2015 16:28:45 +0530 +Subject: [PATCH 046/398] lokdocview: Port to gtk3; 'expose-event' -> 'draw' + +Change-Id: I8d2541f5cbd2b908c2b0dc52cccf9b936bbc307a +(cherry picked from commit 256a9cef8bdd89b90f0c371df8f849c567f84213) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 2 + + libreofficekit/source/gtk/lokdocview.cxx | 47 ++++++++++------------ + 2 files changed, 24 insertions(+), 25 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 1f77f1be6c4d..dc5783b807ad 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -476,6 +476,8 @@ int main( int argc, char* argv[] ) + + // Scrolled window for DocView + pScrolledWindow = gtk_scrolled_window_new(0, 0); ++ gtk_widget_set_hexpand (pScrolledWindow, TRUE); ++ gtk_widget_set_vexpand (pScrolledWindow, TRUE); + gtk_container_add(GTK_CONTAINER(pVBox), pScrolledWindow); + + // DocView doesn't have scrolling capability, so need a viewport +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index cd05d0ebbdb9..d79390e6e5ef 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -116,8 +116,10 @@ struct LOKDocView_Impl + ~LOKDocView_Impl(); + /// Connected to the destroy signal of LOKDocView, deletes its LOKDocView_Impl. + static void destroy(LOKDocView* pDocView, gpointer pData); +- /// Connected to the expose-event of the GtkDrawingArea +- static void onExposed(GtkWidget *widget, GdkEventExpose *event, gpointer user_data); ++ /// Connected to the draw of the GtkDrawingArea ++ static gboolean renderDocument(GtkWidget *widget, cairo_t *cr, gpointer user_data); ++ /// Implementation of draw event handler, invoked by renderDocument(). ++ gboolean renderDocumentImpl(cairo_t* cr); + /// Receives a key press or release event. + void signalKey(GdkEventKey* pEvent); + /* +@@ -138,9 +140,9 @@ struct LOKDocView_Impl + /// Implementation of motion event handler, invoked by signalMotion(). + gboolean signalMotionImpl(GdkEventButton* pEvent); + /// Receives an expose event. +- static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, LOKDocView* pDocView); ++ static gboolean renderOverlay(GtkWidget* pWidget, cairo_t* cr, gpointer userdata); + /// Implementation of expose event handler (renders cursor and selection overlay), invoked by renderOverlay(). +- gboolean renderOverlayImpl(GtkWidget* pEventBox); ++ gboolean renderOverlayImpl(cairo_t *cr); + /// Is rRectangle empty? + static bool isEmptyRectangle(const GdkRectangle& rRectangle); + /* +@@ -154,8 +156,6 @@ struct LOKDocView_Impl + static gboolean handleTimeout(gpointer pData); + /// Implementation of the timeout handler, invoked by handleTimeout(). + gboolean handleTimeoutImpl(); +- /// Implementation of expose event handler, invoked by onExposed(). +- void onExposedImpl(GdkEventExpose* event); + /// Returns the GdkRectangle of a x,y,width,height string. + GdkRectangle payloadToRectangle(const char* pPayload); + /// Returns the GdkRectangles of a x1,y1,w1,h1;x2,y2,w2,h2;... string. +@@ -320,21 +320,22 @@ void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/) + delete pDocView->m_pImpl; + } + +-void LOKDocView_Impl::onExposed(GtkWidget* /*widget*/, GdkEventExpose* event, gpointer userdata) ++gboolean LOKDocView_Impl::renderDocument(GtkWidget* /*widget*/, cairo_t *cr, gpointer userdata) + { + LOKDocView *pDocView = LOK_DOC_VIEW (userdata); +- pDocView->m_pImpl->onExposedImpl(event); ++ return pDocView->m_pImpl->renderDocumentImpl(cr); + } + +-void LOKDocView_Impl::onExposedImpl(GdkEventExpose* event) ++gboolean LOKDocView_Impl::renderDocumentImpl(cairo_t *pCairo) + { + long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips, m_fZoom); + long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips, m_fZoom); + // Total number of rows / columns in this document. + guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +- GdkRectangle aVisibleArea = event->area; +- cairo_t *pcairo = gdk_cairo_create(gtk_widget_get_window(GTK_WIDGET(m_pDocView))); ++ GdkRectangle aVisibleArea; ++ ++ gdk_cairo_get_clip_rectangle (pCairo, &aVisibleArea); + + aVisibleArea.x = pixelToTwip (aVisibleArea.x, m_fZoom); + aVisibleArea.y = pixelToTwip (aVisibleArea.y, m_fZoom); +@@ -374,16 +375,14 @@ void LOKDocView_Impl::onExposedImpl(GdkEventExpose* event) + { + Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn, m_fZoom); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); +- +- gdk_cairo_set_source_pixbuf (pcairo, pPixBuf, ++ gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, + twipToPixel(aTileRectangleTwips.x, m_fZoom), + twipToPixel(aTileRectangleTwips.y, m_fZoom)); +- cairo_paint(pcairo); ++ cairo_paint(pCairo); + } + } + } +- +- cairo_destroy(pcairo); ++ return FALSE; + } + + void LOKDocView_Impl::signalKey(GdkEventKey* pEvent) +@@ -644,16 +643,15 @@ gboolean LOKDocView_Impl::signalMotionImpl(GdkEventButton* pEvent) + return FALSE; + } + +-gboolean LOKDocView_Impl::renderOverlay(GtkWidget* pEventBox, GdkEventExpose* /*pEvent*/, LOKDocView* pDocView) ++gboolean LOKDocView_Impl::renderOverlay(GtkWidget* /*widget*/, cairo_t *cr, gpointer userdata) + { +- return pDocView->m_pImpl->renderOverlayImpl(pEventBox); ++ LOKDocView *pDocView = LOK_DOC_VIEW (userdata); ++ return pDocView->m_pImpl->renderOverlayImpl(cr); + } + +-gboolean LOKDocView_Impl::renderOverlayImpl(GtkWidget* pWidget) ++gboolean LOKDocView_Impl::renderOverlayImpl(cairo_t *pCairo) + { + #if GTK_CHECK_VERSION(2,14,0) // we need gtk_widget_get_window() +- cairo_t* pCairo = gdk_cairo_create(gtk_widget_get_window(pWidget)); +- + if (m_bEdit && m_bCursorVisible && m_bCursorOverlayVisible && !isEmptyRectangle(m_aVisibleCursor)) + { + if (m_aVisibleCursor.width < 30) +@@ -715,7 +713,6 @@ gboolean LOKDocView_Impl::renderOverlayImpl(GtkWidget* pWidget) + renderGraphicHandle(pCairo, m_aGraphicSelection, m_pGraphicHandle); + } + +- cairo_destroy(pCairo); + #endif + return FALSE; + } +@@ -1154,10 +1151,10 @@ static void lok_doc_view_init (LOKDocView* pDocView) + pDocView->m_pImpl = new LOKDocView_Impl(pDocView); + + g_signal_connect(G_OBJECT(pDocView), +- "expose-event", +- G_CALLBACK(LOKDocView_Impl::onExposed), pDocView); ++ "draw", ++ G_CALLBACK(LOKDocView_Impl::renderDocument), pDocView); + g_signal_connect(G_OBJECT(pDocView), +- "expose-event", ++ "draw", + G_CALLBACK(LOKDocView_Impl::renderOverlay), pDocView); + gtk_widget_add_events(GTK_WIDGET(pDocView), + GDK_BUTTON_PRESS_MASK +-- +2.12.0 + diff --git a/SOURCES/0047-lokdocview-gtktiledviewer-Remove-gtk-version-checks.patch b/SOURCES/0047-lokdocview-gtktiledviewer-Remove-gtk-version-checks.patch new file mode 100644 index 0000000..c56138b --- /dev/null +++ b/SOURCES/0047-lokdocview-gtktiledviewer-Remove-gtk-version-checks.patch @@ -0,0 +1,179 @@ +From 0ceaaec7edbf24d65819afc976f6654dd08e8f12 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 10 Jun 2015 16:57:19 +0530 +Subject: [PATCH 047/398] lokdocview, gtktiledviewer: Remove gtk version checks + +We already have the global ENABLE_GTK3 guard for RHEL5 baseline. + +Change-Id: Id814a4063861a1e750952b44686ed24864c0394f +(cherry picked from commit 0bb2ae2d00a280cef4cc0c148c7c3c0050709219) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 19 ------------------- + libreofficekit/source/gtk/lokdocview.cxx | 10 ---------- + 2 files changed, 29 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index dc5783b807ad..22d8775981d0 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -40,12 +40,9 @@ std::map g_aToolItemCommandNames; + std::map g_aCommandNameToolItems; + bool g_bToolItemBroadcast = true; + static GtkWidget* pVBox; +-// GtkComboBox requires gtk 2.24 or later +-#if ( GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 24 ) || GTK_MAJOR_VERSION > 2 + static GtkComboBoxText* pPartSelector; + /// Should the part selector avoid calling lok::Document::setPart()? + static bool g_bPartSelectorBroadcast = true; +-#endif + GtkWidget* pFindbar; + GtkWidget* pFindbarEntry; + GtkWidget* pFindbarLabel; +@@ -117,7 +114,6 @@ static void toggleEditing(GtkWidget* /*pButton*/, gpointer /*pItem*/) + /// Toggle the visibility of the findbar. + static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + { +-#if GTK_CHECK_VERSION(2,18,0) // we need gtk_widget_get_visible() + if (gtk_widget_get_visible(pFindbar)) + { + gtk_widget_hide(pFindbar); +@@ -127,7 +123,6 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + gtk_widget_show_all(pFindbar); + gtk_widget_grab_focus(pFindbarEntry); + } +-#endif + } + + /// Get the visible area of the scrolled window +@@ -153,13 +148,11 @@ static void getVisibleAreaTwips(GdkRectangle* pArea) + static gboolean signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData) + { + LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); +-#if GTK_CHECK_VERSION(2,18,0) // we need gtk_widget_get_visible() + if (!gtk_widget_get_visible(pFindbar) && bool(lok_doc_view_get_edit(pLOKDocView))) + { + lok_doc_view_post_key(pWidget, pEvent, pData); + return TRUE; + } +-#endif + return FALSE; + } + +@@ -265,11 +258,9 @@ static void signalSearch(LOKDocView* /*pLOKDocView*/, char* /*pPayload*/, gpoint + + static void signalPart(LOKDocView* /*pLOKDocView*/, int nPart, gpointer /*pData*/) + { +-#if GTK_CHECK_VERSION(2,24,0) + g_bPartSelectorBroadcast = false; + gtk_combo_box_set_active(GTK_COMBO_BOX(pPartSelector), nPart); + g_bPartSelectorBroadcast = true; +-#endif + } + + /// User clicked on a cmmand button -> inform LOKDocView. +@@ -285,8 +276,6 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + } + } + +-// GtkComboBox requires gtk 2.24 or later +-#if ( GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 24 ) || GTK_MAJOR_VERSION > 2 + static void populatePartSelector() + { + gtk_list_store_clear( GTK_LIST_STORE( +@@ -344,7 +333,6 @@ static void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ ) + lok_doc_view_set_partmode( LOK_DOC_VIEW(pDocView), ePartMode ); + } + } +-#endif + + int main( int argc, char* argv[] ) + { +@@ -387,8 +375,6 @@ int main( int argc, char* argv[] ) + GtkToolItem* pSeparator1 = gtk_separator_tool_item_new(); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pSeparator1, -1); + +-// GtkComboBox requires gtk 2.24 or later +-#if ( GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 24 ) || GTK_MAJOR_VERSION > 2 + GtkToolItem* pPartSelectorToolItem = gtk_tool_item_new(); + GtkWidget* pComboBox = gtk_combo_box_text_new(); + gtk_container_add( GTK_CONTAINER(pPartSelectorToolItem), pComboBox ); +@@ -403,7 +389,6 @@ int main( int argc, char* argv[] ) + GtkWidget* pPartModeComboBox = gtk_combo_box_text_new(); + gtk_container_add( GTK_CONTAINER(pPartModeSelectorToolItem), pPartModeComboBox ); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1 ); +-#endif + + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + pEnableEditing = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_EDIT); +@@ -492,15 +477,11 @@ int main( int argc, char* argv[] ) + g_error("main: lok_doc_view_open_document() failed"); + assert(lok_doc_view_get_document(LOK_DOC_VIEW(pDocView))); + +- // GtkComboBox requires gtk 2.24 or later +-#if ( GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 24 ) || GTK_MAJOR_VERSION > 2 + populatePartSelector(); + populatePartModeSelector( GTK_COMBO_BOX_TEXT(pPartModeComboBox) ); + // Connect these signals after populating the selectors, to avoid re-rendering on setting the default part/partmode. + g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0); +- + g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0); +-#endif + + gtk_main(); + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d79390e6e5ef..b00556620288 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -651,7 +651,6 @@ gboolean LOKDocView_Impl::renderOverlay(GtkWidget* /*widget*/, cairo_t *cr, gpoi + + gboolean LOKDocView_Impl::renderOverlayImpl(cairo_t *pCairo) + { +-#if GTK_CHECK_VERSION(2,14,0) // we need gtk_widget_get_window() + if (m_bEdit && m_bCursorVisible && m_bCursorOverlayVisible && !isEmptyRectangle(m_aVisibleCursor)) + { + if (m_aVisibleCursor.width < 30) +@@ -713,7 +712,6 @@ gboolean LOKDocView_Impl::renderOverlayImpl(cairo_t *pCairo) + renderGraphicHandle(pCairo, m_aGraphicSelection, m_pGraphicHandle); + } + +-#endif + return FALSE; + } + +@@ -1017,9 +1015,7 @@ gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) + case LOK_CALLBACK_HYPERLINK_CLICKED: + { + GError* pError = NULL; +-#if GTK_CHECK_VERSION(2,14,0) + gtk_show_uri(NULL, pCallback->m_aPayload.c_str(), GDK_CURRENT_TIME, &pError); +-#endif + } + break; + case LOK_CALLBACK_STATE_CHANGED: +@@ -1070,22 +1066,16 @@ void LOKDocView_Impl::callbackWorkerImpl(int nType, const char* pPayload) + { + LOKDocView_Impl::CallbackData* pCallback = new LOKDocView_Impl::CallbackData(nType, pPayload ? pPayload : "(nil)", m_pDocView); + g_info("lok_doc_view_callback_worker: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload); +-#if GTK_CHECK_VERSION(2,12,0) + gdk_threads_add_idle(LOKDocView_Impl::callback, pCallback); +-#endif + } + + void LOKDocView_Impl::globalCallbackWorkerImpl(int nType, const char* pPayload) + { + LOKDocView_Impl::CallbackData* pCallback = new LOKDocView_Impl::CallbackData(nType, pPayload ? pPayload : "(nil)", m_pDocView); + g_info("LOKDocView_Impl::globalCallbackWorkerImpl: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload); +-#if GTK_CHECK_VERSION(2,12,0) + gdk_threads_add_idle(LOKDocView_Impl::globalCallback, pCallback); +-#endif + } + +- +- + void LOKDocView_Impl::commandChanged(const std::string& rString) + { + g_signal_emit(m_pDocView, doc_view_signals[COMMAND_CHANGED], 0, rString.c_str()); +-- +2.12.0 + diff --git a/SOURCES/0048-gtktiledviewer-Replace-deprecated-Gtk-functions.patch b/SOURCES/0048-gtktiledviewer-Replace-deprecated-Gtk-functions.patch new file mode 100644 index 0000000..003c3df --- /dev/null +++ b/SOURCES/0048-gtktiledviewer-Replace-deprecated-Gtk-functions.patch @@ -0,0 +1,161 @@ +From f652ef0d80d59c3b7223cc0679403f3e42dda044 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 10 Jun 2015 20:59:18 +0530 +Subject: [PATCH 048/398] gtktiledviewer: Replace deprecated Gtk functions + +Change-Id: I354aa987f8e732945fb552d855a3416c782bb508 +(cherry picked from commit 101b616c7a2ee90b6d09eedd7a7543a63f237c97) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 55 ++++++++++++++-------- + 1 file changed, 36 insertions(+), 19 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 22d8775981d0..580d5f66f683 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -57,7 +57,7 @@ const float fZooms[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 5.0 }; + + static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + { +- const char *sName = gtk_tool_button_get_stock_id( GTK_TOOL_BUTTON(pButton) ); ++ const char *sName = gtk_tool_button_get_icon_name( GTK_TOOL_BUTTON(pButton) ); + + float fZoom = 0; + float fCurrentZoom = 0; +@@ -67,7 +67,7 @@ static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + fCurrentZoom = lok_doc_view_get_zoom( LOK_DOC_VIEW(pDocView) ); + } + +- if ( strcmp(sName, "gtk-zoom-in") == 0) ++ if ( strcmp(sName, "zoom-in-symbolic") == 0) + { + for ( unsigned int i = 0; i < sizeof( fZooms ) / sizeof( fZooms[0] ); i++ ) + { +@@ -78,11 +78,11 @@ static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + } + } + } +- else if ( strcmp(sName, "gtk-zoom-100") == 0) ++ else if ( strcmp(sName, "zoom-original-symbolic") == 0) + { + fZoom = 1; + } +- else if ( strcmp(sName, "gtk-zoom-out") == 0) ++ else if ( strcmp(sName, "zoom-out-symbolic") == 0) + { + for ( unsigned int i = 0; i < sizeof( fZooms ) / sizeof( fZooms[0] ); i++ ) + { +@@ -353,22 +353,25 @@ int main( int argc, char* argv[] ) + gtk_window_set_default_size(GTK_WINDOW(pWindow), 1024, 768); + g_signal_connect( pWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL ); + +- pVBox = gtk_vbox_new( FALSE, 0 ); ++ pVBox = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 ); + gtk_container_add( GTK_CONTAINER(pWindow), pVBox ); + + // Toolbar + GtkWidget* pToolbar = gtk_toolbar_new(); + gtk_toolbar_set_style( GTK_TOOLBAR(pToolbar), GTK_TOOLBAR_ICONS ); + +- GtkToolItem* pZoomIn = gtk_tool_button_new_from_stock( GTK_STOCK_ZOOM_IN ); ++ GtkToolItem* pZoomIn = gtk_tool_button_new( NULL, NULL ); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomIn), "zoom-in-symbolic"); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoomIn, 0); + g_signal_connect( G_OBJECT(pZoomIn), "clicked", G_CALLBACK(changeZoom), NULL ); + +- GtkToolItem* pZoom1 = gtk_tool_button_new_from_stock( GTK_STOCK_ZOOM_100 ); ++ GtkToolItem* pZoom1 = gtk_tool_button_new( NULL, NULL ); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoom1), "zoom-original-symbolic"); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoom1, -1); + g_signal_connect( G_OBJECT(pZoom1), "clicked", G_CALLBACK(changeZoom), NULL ); + +- GtkToolItem* pZoomOut = gtk_tool_button_new_from_stock( GTK_STOCK_ZOOM_OUT ); ++ GtkToolItem* pZoomOut = gtk_tool_button_new( NULL, NULL ); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomOut), "zoom-out-symbolic"); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoomOut, -1); + g_signal_connect( G_OBJECT(pZoomOut), "clicked", G_CALLBACK(changeZoom), NULL ); + +@@ -391,27 +394,38 @@ int main( int argc, char* argv[] ) + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1 ); + + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); +- pEnableEditing = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_EDIT); ++ pEnableEditing = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pEnableEditing), "insert-text-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pEnableEditing, -1); + g_signal_connect(G_OBJECT(pEnableEditing), "toggled", G_CALLBACK(toggleEditing), NULL); +- GtkToolItem* pFindButton = gtk_tool_button_new_from_stock(GTK_STOCK_FIND); ++ ++ GtkToolItem* pFindButton = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindButton), "edit-find-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pFindButton, -1); + g_signal_connect(G_OBJECT(pFindButton), "clicked", G_CALLBACK(toggleFindbar), NULL); + + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); +- pBold = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_BOLD); ++ ++ pBold = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pBold), "format-text-bold-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pBold, -1); + g_signal_connect(G_OBJECT(pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pBold, ".uno:Bold"); +- pItalic = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_ITALIC); ++ ++ pItalic = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pItalic), "format-text-italic-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pItalic, -1); + g_signal_connect(G_OBJECT(pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pItalic, ".uno:Italic"); +- pUnderline = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_UNDERLINE); ++ ++ pUnderline = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pUnderline), "format-text-underline-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pUnderline, -1); + g_signal_connect(G_OBJECT(pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pUnderline, ".uno:Underline"); +- pStrikethrough = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_STRIKETHROUGH); ++ ++ pStrikethrough = gtk_toggle_tool_button_new (); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pStrikethrough), "format-text-strikethrough-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pStrikethrough, -1); + g_signal_connect(G_OBJECT(pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pStrikethrough, ".uno:Strikeout"); +@@ -422,7 +436,8 @@ int main( int argc, char* argv[] ) + pFindbar = gtk_toolbar_new(); + gtk_toolbar_set_style(GTK_TOOLBAR(pFindbar), GTK_TOOLBAR_ICONS); + +- GtkToolItem* pFindbarClose = gtk_tool_button_new_from_stock(GTK_STOCK_CLOSE); ++ GtkToolItem* pFindbarClose = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarClose), "window-close-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarClose, -1); + g_signal_connect(G_OBJECT(pFindbarClose), "clicked", G_CALLBACK(toggleFindbar), NULL); + +@@ -432,10 +447,13 @@ int main( int argc, char* argv[] ) + g_signal_connect(pFindbarEntry, "key-press-event", G_CALLBACK(signalFindbar), 0); + gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pEntryContainer, -1); + +- GtkToolItem* pFindbarNext = gtk_tool_button_new_from_stock(GTK_STOCK_GO_DOWN); ++ GtkToolItem* pFindbarNext = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarNext), "go-down-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarNext, -1); + g_signal_connect(G_OBJECT(pFindbarNext), "clicked", G_CALLBACK(signalSearchNext), NULL); +- GtkToolItem* pFindbarPrev = gtk_tool_button_new_from_stock(GTK_STOCK_GO_UP); ++ ++ GtkToolItem* pFindbarPrev = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarPrev), "go-up-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarPrev, -1); + g_signal_connect(G_OBJECT(pFindbarPrev), "clicked", G_CALLBACK(signalSearchPrev), NULL); + +@@ -465,8 +483,7 @@ int main( int argc, char* argv[] ) + gtk_widget_set_vexpand (pScrolledWindow, TRUE); + gtk_container_add(GTK_CONTAINER(pVBox), pScrolledWindow); + +- // DocView doesn't have scrolling capability, so need a viewport +- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(pScrolledWindow), pDocView); ++ gtk_container_add(GTK_CONTAINER(pScrolledWindow), pDocView); + + gtk_widget_show_all( pWindow ); + // Hide the findbar by default. +-- +2.12.0 + diff --git a/SOURCES/0049-Repository.mk-libreofficekitgtk-is-conditional-on-EN.patch b/SOURCES/0049-Repository.mk-libreofficekitgtk-is-conditional-on-EN.patch new file mode 100644 index 0000000..1cd3258 --- /dev/null +++ b/SOURCES/0049-Repository.mk-libreofficekitgtk-is-conditional-on-EN.patch @@ -0,0 +1,28 @@ +From 89f0ed26b0afeff20d8d40138a2254b399e54a9c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 16 Jun 2015 09:10:02 +0200 +Subject: [PATCH 049/398] Repository.mk: libreofficekitgtk is conditional on + ENABLE_GTK3 + +Change-Id: I97f859e33a510f626787cce335f652dc03546ab6 +(cherry picked from commit 7ffd7c4fd7bdc63098ec6ac746b9885f92964465) +--- + Repository.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Repository.mk b/Repository.mk +index f7c89c0057a0..a84dc9a12211 100644 +--- a/Repository.mk ++++ b/Repository.mk +@@ -582,7 +582,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,PLAINLIBS_OOO,ooo, \ + i18nlangtag \ + i18nutil \ + index_data \ +- $(if $(and $(ENABLE_GTK), $(filter LINUX,$(OS))), libreofficekitgtk) \ ++ $(if $(and $(ENABLE_GTK3), $(filter LINUX,$(OS))), libreofficekitgtk) \ + localedata_en \ + localedata_es \ + localedata_euro \ +-- +2.12.0 + diff --git a/SOURCES/0050-lokdocview-Restructure-this-GObject-class.patch b/SOURCES/0050-lokdocview-Restructure-this-GObject-class.patch new file mode 100644 index 0000000..e3344be --- /dev/null +++ b/SOURCES/0050-lokdocview-Restructure-this-GObject-class.patch @@ -0,0 +1,2380 @@ +From 90cd5fdf14031c259ddc4f9ecf9ada7c37fcf421 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 11 Jun 2015 22:00:11 +0530 +Subject: [PATCH 050/398] lokdocview: Restructure this GObject class + +This is a big messy commit restructuring the whole class to follow most +common practices followed by standard GObject classes, so that it can +keep gobject-introspection happy; hence, allowing this widget to be used +from other languages. + +(cherry picked from commit 3061e486f9f9313c15cba6782edfaee96fe4f83d) + +Change-Id: I10c34dad402d1ec586958b2db21ff44412c36cea +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 17 +- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 4 +- + libreofficekit/source/gtk/lokdocview.cxx | 1856 +++++++++++--------- + 3 files changed, 1041 insertions(+), 836 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index bdd2e9ab90e3..7048dbefc0a1 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -25,23 +25,19 @@ G_BEGIN_DECLS + #define LOK_IS_DOC_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), LOK_TYPE_DOC_VIEW)) + #define LOK_DOC_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), LOK_TYPE_DOC_VIEW, LOKDocViewClass)) + +- +-typedef struct _LOKDocView LOKDocView; +-typedef struct _LOKDocViewClass LOKDocViewClass; ++typedef struct _LOKDocView LOKDocView; ++typedef struct _LOKDocViewClass LOKDocViewClass; ++typedef struct _LOKDocViewPrivate LOKDocViewPrivate; + + struct _LOKDocView + { + GtkDrawingArea aDrawingArea; +- struct LOKDocView_Impl* m_pImpl; ++ LOKDocViewPrivate* priv; + }; + + struct _LOKDocViewClass + { + GtkDrawingAreaClass parent_class; +- void (* edit_changed) (LOKDocView* pView, gboolean was_edit); +- void (* command_changed) (LOKDocView* pView, char* new_state); +- void (* search_not_found) (LOKDocView* pView, char* new_state); +- void (* part_changed) (LOKDocView* pView, int new_part); + }; + + GType lok_doc_view_get_type (void) G_GNUC_CONST; +@@ -78,9 +74,8 @@ void lok_doc_view_post_command (LOKDocView* + const char* pArguments); + + /// Posts a keyboard event to LibreOfficeKit. +-void lok_doc_view_post_key (GtkWidget* pWidget, +- GdkEventKey* pEvent, +- gpointer pData); ++void lok_doc_view_post_key (LOKDocView* pDocView, ++ GdkEvent* pEvent); + + float lok_doc_view_pixel_to_twip (LOKDocView* pDocView, + float fInput); +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 580d5f66f683..8b006797c226 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -145,12 +145,12 @@ static void getVisibleAreaTwips(GdkRectangle* pArea) + + + /// Handles the key-press-event of the window. +-static gboolean signalKey(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer pData) ++static gboolean signalKey(GtkWidget* /*pWidget*/, GdkEvent* pEvent, gpointer/* pData*/) + { + LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); + if (!gtk_widget_get_visible(pFindbar) && bool(lok_doc_view_get_edit(pLOKDocView))) + { +- lok_doc_view_post_key(pWidget, pEvent, pData); ++ lok_doc_view_post_key(pLOKDocView, pEvent); + return TRUE; + } + return FALSE; +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index b00556620288..7031be9b6536 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -36,26 +36,30 @@ + // Number of handles around a graphic selection. + #define GRAPHIC_HANDLE_COUNT 8 + +-/// Holds data used by LOKDocView only. +-struct LOKDocView_Impl ++struct _LOKDocViewPrivate + { +- LOKDocView* m_pDocView; +- TileBuffer m_aTileBuffer; +- +- float m_fZoom; +- ++ gchar* m_aLOPath; ++ gchar* m_aDocPath; ++ guint m_nLoadProgress; ++ gboolean m_bIsLoading; ++ gboolean m_bCanZoomIn; ++ gboolean m_bCanZoomOut; + LibreOfficeKit* m_pOffice; + LibreOfficeKitDocument* m_pDocument; +- long m_nDocumentWidthTwips; +- long m_nDocumentHeightTwips; ++ ++ TileBuffer m_aTileBuffer; ++ ++ gfloat m_fZoom; ++ glong m_nDocumentWidthTwips; ++ glong m_nDocumentHeightTwips; + /// View or edit mode. +- bool m_bEdit; ++ gboolean m_bEdit; + /// Position and size of the visible cursor. + GdkRectangle m_aVisibleCursor; + /// Cursor overlay is visible or hidden (for blinking). +- bool m_bCursorOverlayVisible; ++ gboolean m_bCursorOverlayVisible; + /// Cursor is visible or hidden (e.g. for graphic selection). +- bool m_bCursorVisible; ++ gboolean m_bCursorVisible; + /// Time of the last button press. + guint32 m_nLastButtonPressTime; + /// Time of the last button release. +@@ -67,7 +71,7 @@ struct LOKDocView_Impl + /// Position and size of the selection end. + GdkRectangle m_aTextSelectionEnd; + GdkRectangle m_aGraphicSelection; +- bool m_bInDragGraphicSelection; ++ gboolean m_bInDragGraphicSelection; + + /// @name Start/middle/end handle. + ///@{ +@@ -76,19 +80,19 @@ struct LOKDocView_Impl + /// Rectangle of the text selection start handle, to know if the user clicked on it or not + GdkRectangle m_aHandleStartRect; + /// If we are in the middle of a drag of the text selection end handle. +- bool m_bInDragStartHandle; ++ gboolean m_bInDragStartHandle; + /// Bitmap of the text selection middle handle. + cairo_surface_t* m_pHandleMiddle; + /// Rectangle of the text selection middle handle, to know if the user clicked on it or not + GdkRectangle m_aHandleMiddleRect; + /// If we are in the middle of a drag of the text selection middle handle. +- bool m_bInDragMiddleHandle; ++ gboolean m_bInDragMiddleHandle; + /// Bitmap of the text selection end handle. + cairo_surface_t* m_pHandleEnd; + /// Rectangle of the text selection end handle, to know if the user clicked on it or not + GdkRectangle m_aHandleEndRect; + /// If we are in the middle of a drag of the text selection end handle. +- bool m_bInDragEndHandle; ++ gboolean m_bInDragEndHandle; + ///@} + + /// @name Graphic handles. +@@ -98,103 +102,38 @@ struct LOKDocView_Impl + /// Rectangle of a graphic selection handle, to know if the user clicked on it or not. + GdkRectangle m_aGraphicHandleRects[8]; + /// If we are in the middle of a drag of a graphic selection handle. +- bool m_bInDragGraphicHandles[8]; ++ gboolean m_bInDragGraphicHandles[8]; + ///@} +- +- /// Callback data, allocated in lok_doc_view_callback_worker(), released in lok_doc_view_callback(). +- struct CallbackData +- { +- int m_nType; +- std::string m_aPayload; +- LOKDocView* m_pDocView; +- +- CallbackData(int nType, const std::string& rPayload, LOKDocView* pDocView); +- }; +- +- +- LOKDocView_Impl(LOKDocView* pDocView); +- ~LOKDocView_Impl(); +- /// Connected to the destroy signal of LOKDocView, deletes its LOKDocView_Impl. +- static void destroy(LOKDocView* pDocView, gpointer pData); +- /// Connected to the draw of the GtkDrawingArea +- static gboolean renderDocument(GtkWidget *widget, cairo_t *cr, gpointer user_data); +- /// Implementation of draw event handler, invoked by renderDocument(). +- gboolean renderDocumentImpl(cairo_t* cr); +- /// Receives a key press or release event. +- void signalKey(GdkEventKey* pEvent); +- /* +- * The user drags the handle, which is below the cursor, but wants to move the +- * cursor accordingly. +- * +- * @param pHandle the rectangle of the handle +- * @param pEvent the motion event +- * @param pPoint the computed point (output parameter) +- */ +- static void getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* pPoint); +- /// Receives a button press event. +- static gboolean signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView); +- /// Implementation of button press event handler, invoked by signalButton(). +- gboolean signalButtonImpl(GdkEventButton* pEvent); +- /// Receives a motion event. +- static gboolean signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView); +- /// Implementation of motion event handler, invoked by signalMotion(). +- gboolean signalMotionImpl(GdkEventButton* pEvent); +- /// Receives an expose event. +- static gboolean renderOverlay(GtkWidget* pWidget, cairo_t* cr, gpointer userdata); +- /// Implementation of expose event handler (renders cursor and selection overlay), invoked by renderOverlay(). +- gboolean renderOverlayImpl(cairo_t *cr); +- /// Is rRectangle empty? +- static bool isEmptyRectangle(const GdkRectangle& rRectangle); +- /* +- * Renders pHandle below an rCursor rectangle on pCairo. +- * @param rRectangle output parameter, the rectangle that contains the rendered handle. +- */ +- void renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle); +- /// Renders pHandle around an rSelection rectangle on pCairo. +- void renderGraphicHandle(cairo_t* pCairo, const GdkRectangle& rSelection, cairo_surface_t* pHandle); +- /// Takes care of the blinking cursor. +- static gboolean handleTimeout(gpointer pData); +- /// Implementation of the timeout handler, invoked by handleTimeout(). +- gboolean handleTimeoutImpl(); +- /// Returns the GdkRectangle of a x,y,width,height string. +- GdkRectangle payloadToRectangle(const char* pPayload); +- /// Returns the GdkRectangles of a x1,y1,w1,h1;x2,y2,w2,h2;... string. +- std::vector payloadToRectangles(const char* pPayload); +- /// Returns the string representation of a LibreOfficeKitCallbackType enumeration element. +- static const char* callbackTypeToString(int nType); +- /// Invoked on the main thread if callbackWorker() requests so. +- static gboolean callback(gpointer pData); +- /// Invoked on the main thread if globalCallbackWorker() requests so. +- static gboolean globalCallback(gpointer pData); +- /// Implementation of the callback handler, invoked by callback(); +- gboolean callbackImpl(CallbackData* pCallbackData); +- /// Our LOK callback, runs on the LO thread. +- static void callbackWorker(int nType, const char* pPayload, void* pData); +- /// Implementation of the callback worder handler, invoked by callbackWorker(). +- void callbackWorkerImpl(int nType, const char* pPayload); +- /// Our global LOK callback, runs on the LO thread. +- static void globalCallbackWorker(int nType, const char* pPayload, void* pData); +- /// Implementation of the global callback worder handler, invoked by globalCallbackWorker(). +- void globalCallbackWorkerImpl(int nType, const char* pPayload); +- /// Command state (various buttons like bold are toggled or not) is changed. +- void commandChanged(const std::string& rPayload); +- /// Search did not find any matches. +- void searchNotFound(const std::string& rPayload); +- /// LOK decided to change parts, need to update UI. +- void setPart(const std::string& rPayload); +- /// Sets the tiles enclosed by rRectangle as invalid in m_aTileBuffer +- void setTilesInvalid(const GdkRectangle& rRectangle); + }; + + enum + { ++ LOAD_CHANGED, ++ LOAD_FAILED, + EDIT_CHANGED, + COMMAND_CHANGED, + SEARCH_NOT_FOUND, + PART_CHANGED, ++ HYPERLINK_CLICKED, ++ + LAST_SIGNAL + }; + ++enum ++{ ++ PROP_0, ++ ++ PROP_LO_PATH, ++ PROP_DOC_PATH, ++ PROP_EDITABLE, ++ PROP_LOAD_PROGRESS, ++ PROP_ZOOM, ++ PROP_IS_LOADING, ++ PROP_DOC_WIDTH, ++ PROP_DOC_HEIGHT, ++ PROP_CAN_ZOOM_IN, ++ PROP_CAN_ZOOM_OUT ++}; + + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + +@@ -203,15 +142,26 @@ SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + #endif +-G_DEFINE_TYPE(LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA) ++G_DEFINE_TYPE_WITH_PRIVATE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA) + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif + +-namespace { + +-/// Sets rWidth and rHeight from a "width, height" string. +-void payloadToSize(const char* pPayload, long& rWidth, long& rHeight) ++struct CallbackData ++{ ++ int m_nType; ++ std::string m_aPayload; ++ LOKDocView* m_pDocView; ++ ++ CallbackData(int nType, const std::string& rPayload, LOKDocView* pDocView) ++ : m_nType(nType), ++ m_aPayload(rPayload), ++ m_pDocView(pDocView) {} ++}; ++ ++static void ++payloadToSize(const char* pPayload, long& rWidth, long& rHeight) + { + rWidth = rHeight = 0; + gchar** ppCoordinates = g_strsplit(pPayload, ", ", 2); +@@ -226,177 +176,70 @@ void payloadToSize(const char* pPayload, long& rWidth, long& rHeight) + g_strfreev(ppCoordinates); + } + +-} +- +- +- +-namespace { +- +-/// Implementation of the global callback handler, invoked by globalCallback(); +-gboolean globalCallbackImpl(LOKDocView_Impl::CallbackData* pCallback) ++/// Returns the string representation of a LibreOfficeKitCallbackType enumeration element. ++static const char* ++callbackTypeToString (int nType) + { +- switch (pCallback->m_nType) ++ switch (nType) + { ++ case LOK_CALLBACK_INVALIDATE_TILES: ++ return "LOK_CALLBACK_INVALIDATE_TILES"; ++ case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: ++ return "LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR"; ++ case LOK_CALLBACK_TEXT_SELECTION: ++ return "LOK_CALLBACK_TEXT_SELECTION"; ++ case LOK_CALLBACK_TEXT_SELECTION_START: ++ return "LOK_CALLBACK_TEXT_SELECTION_START"; ++ case LOK_CALLBACK_TEXT_SELECTION_END: ++ return "LOK_CALLBACK_TEXT_SELECTION_END"; ++ case LOK_CALLBACK_CURSOR_VISIBLE: ++ return "LOK_CALLBACK_CURSOR_VISIBLE"; ++ case LOK_CALLBACK_GRAPHIC_SELECTION: ++ return "LOK_CALLBACK_GRAPHIC_SELECTION"; ++ case LOK_CALLBACK_HYPERLINK_CLICKED: ++ return "LOK_CALLBACK_HYPERLINK_CLICKED"; ++ case LOK_CALLBACK_STATE_CHANGED: ++ return "LOK_CALLBACK_STATE_CHANGED"; + case LOK_CALLBACK_STATUS_INDICATOR_START: +- { +- } +- break; ++ return "LOK_CALLBACK_STATUS_INDICATOR_START"; + case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE: +- { +- } +- break; ++ return "LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE"; + case LOK_CALLBACK_STATUS_INDICATOR_FINISH: +- { +- } +- break; +- default: +- g_assert(false); +- break; ++ return "LOK_CALLBACK_STATUS_INDICATOR_FINISH"; ++ case LOK_CALLBACK_SEARCH_NOT_FOUND: ++ return "LOK_CALLBACK_SEARCH_NOT_FOUND"; ++ case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: ++ return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED"; ++ case LOK_CALLBACK_SET_PART: ++ return "LOK_CALLBACK_SET_PART"; + } +- delete pCallback; +- +- return G_SOURCE_REMOVE; +-} +- +-} +- +-LOKDocView_Impl::CallbackData::CallbackData(int nType, const std::string& rPayload, LOKDocView* pDocView) +- : m_nType(nType), +- m_aPayload(rPayload), +- m_pDocView(pDocView) +-{ +-} +- +-LOKDocView_Impl::LOKDocView_Impl(LOKDocView* pDocView) +- : m_pDocView(pDocView), +- m_aTileBuffer(TileBuffer(0,0)), +- m_fZoom(1), +- m_pOffice(0), +- m_pDocument(0), +- m_nDocumentWidthTwips(0), +- m_nDocumentHeightTwips(0), +- m_bEdit(false), +- m_aVisibleCursor({0, 0, 0, 0}), +- m_bCursorOverlayVisible(false), +- m_bCursorVisible(true), +- m_nLastButtonPressTime(0), +- m_nLastButtonReleaseTime(0), +- m_aTextSelectionStart({0, 0, 0, 0}), +- m_aTextSelectionEnd({0, 0, 0, 0}), +- m_aGraphicSelection({0, 0, 0, 0}), +- m_bInDragGraphicSelection(false), +- +- // Start/middle/end handle. +- m_pHandleStart(0), +- m_aHandleStartRect({0, 0, 0, 0}), +- m_bInDragStartHandle(false), +- m_pHandleMiddle(0), +- m_aHandleMiddleRect({0, 0, 0, 0}), +- m_bInDragMiddleHandle(false), +- m_pHandleEnd(0), +- m_aHandleEndRect({0, 0, 0, 0}), +- m_bInDragEndHandle(false), +- +- m_pGraphicHandle(0) +-{ +- memset(&m_aGraphicHandleRects, 0, sizeof(m_aGraphicHandleRects)); +- memset(&m_bInDragGraphicHandles, 0, sizeof(m_bInDragGraphicHandles)); +-} +- +-LOKDocView_Impl::~LOKDocView_Impl() +-{ +- if (m_pDocument) +- m_pDocument->pClass->destroy(m_pDocument); +- if (m_pOffice) +- m_pOffice->pClass->destroy(m_pOffice); +- m_pDocument = 0; +- m_pOffice = 0; +-} +- +-void LOKDocView_Impl::destroy(LOKDocView* pDocView, gpointer /*pData*/) +-{ +- // We specifically need to destroy the document when closing in order to ensure +- // that lock files etc. are cleaned up. +- delete pDocView->m_pImpl; +-} +- +-gboolean LOKDocView_Impl::renderDocument(GtkWidget* /*widget*/, cairo_t *cr, gpointer userdata) +-{ +- LOKDocView *pDocView = LOK_DOC_VIEW (userdata); +- return pDocView->m_pImpl->renderDocumentImpl(cr); ++ return 0; + } + +-gboolean LOKDocView_Impl::renderDocumentImpl(cairo_t *pCairo) ++static bool ++isEmptyRectangle(const GdkRectangle& rRectangle) + { +- long nDocumentWidthPixels = twipToPixel(m_nDocumentWidthTwips, m_fZoom); +- long nDocumentHeightPixels = twipToPixel(m_nDocumentHeightTwips, m_fZoom); +- // Total number of rows / columns in this document. +- guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); +- guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +- GdkRectangle aVisibleArea; +- +- gdk_cairo_get_clip_rectangle (pCairo, &aVisibleArea); +- +- aVisibleArea.x = pixelToTwip (aVisibleArea.x, m_fZoom); +- aVisibleArea.y = pixelToTwip (aVisibleArea.y, m_fZoom); +- aVisibleArea.width = pixelToTwip (aVisibleArea.width, m_fZoom); +- aVisibleArea.height = pixelToTwip (aVisibleArea.height, m_fZoom); +- +- // Render the tiles. +- for (guint nRow = 0; nRow < nRows; ++nRow) +- { +- for (guint nColumn = 0; nColumn < nColumns; ++nColumn) +- { +- GdkRectangle aTileRectangleTwips, aTileRectanglePixels; +- bool bPaint = true; +- +- // Determine size of the tile: the rightmost/bottommost tiles may +- // be smaller, and we need the size to decide if we need to repaint. +- if (nColumn == nColumns - 1) +- aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels; +- else +- aTileRectanglePixels.width = nTileSizePixels; +- if (nRow == nRows - 1) +- aTileRectanglePixels.height = nDocumentHeightPixels - nRow * nTileSizePixels; +- else +- aTileRectanglePixels.height = nTileSizePixels; +- +- // Determine size and position of the tile in document coordinates, +- // so we can decide if we can skip painting for partial rendering. +- aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, m_fZoom) * nColumn; +- aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, m_fZoom) * nRow; +- aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, m_fZoom); +- aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, m_fZoom); +- +- if (!gdk_rectangle_intersect(&aVisibleArea, &aTileRectangleTwips, 0)) +- bPaint = false; +- +- if (bPaint) +- { +- Tile& currentTile = m_aTileBuffer.getTile(nRow, nColumn, m_fZoom); +- GdkPixbuf* pPixBuf = currentTile.getBuffer(); +- gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, +- twipToPixel(aTileRectangleTwips.x, m_fZoom), +- twipToPixel(aTileRectangleTwips.y, m_fZoom)); +- cairo_paint(pCairo); +- } +- } +- } +- return FALSE; ++ return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0; + } + +-void LOKDocView_Impl::signalKey(GdkEventKey* pEvent) ++static void ++signalKey (LOKDocView* pDocView, const GdkEvent* pEvent) + { ++ LOKDocViewPrivate* priv = pDocView->priv; + int nCharCode = 0; + int nKeyCode = 0; ++ guint keyval; ++ GdkModifierType state; ++ gdk_event_get_keyval (pEvent, &keyval); ++ gdk_event_get_state (pEvent, &state); + +- if (!m_bEdit) ++ if (!priv->m_bEdit) + { + g_info("signalKey: not in edit mode, ignore"); + return; + } + +- switch (pEvent->keyval) ++ switch (keyval) + { + case GDK_KEY_BackSpace: + nKeyCode = com::sun::star::awt::Key::BACKSPACE; +@@ -423,325 +266,300 @@ void LOKDocView_Impl::signalKey(GdkEventKey* pEvent) + nKeyCode = com::sun::star::awt::Key::RIGHT; + break; + default: +- if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26) +- nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_KEY_F1); ++ if (keyval >= GDK_KEY_F1 && keyval <= GDK_KEY_F26) ++ nKeyCode = com::sun::star::awt::Key::F1 + (keyval - GDK_KEY_F1); + else +- nCharCode = gdk_keyval_to_unicode(pEvent->keyval); ++ nCharCode = gdk_keyval_to_unicode(keyval); + } + + // rsc is not public API, but should be good enough for debugging purposes. + // If this is needed for real, then probably a new param of type + // css::awt::KeyModifier is needed in postKeyEvent(). +- if (pEvent->state & GDK_SHIFT_MASK) ++ if (state & GDK_SHIFT_MASK) + nKeyCode |= KEY_SHIFT; + + if (pEvent->type == GDK_KEY_RELEASE) +- m_pDocument->pClass->postKeyEvent(m_pDocument, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode); ++ priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode); + else +- m_pDocument->pClass->postKeyEvent(m_pDocument, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode); +-} +- +-gboolean LOKDocView_Impl::signalButton(GtkWidget* /*pEventBox*/, GdkEventButton* pEvent, LOKDocView* pDocView) +-{ +- return pDocView->m_pImpl->signalButtonImpl(pEvent); ++ priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode); + } + +-/// Receives a button press event. +-gboolean LOKDocView_Impl::signalButtonImpl(GdkEventButton* pEvent) ++static gboolean ++handleTimeout (gpointer pData) + { +- g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", (int)pEvent->x, (int)pEvent->y, (int)pixelToTwip(pEvent->x, m_fZoom), (int)pixelToTwip(pEvent->y, m_fZoom)); ++ LOKDocView* pDocView = LOK_DOC_VIEW (pData); ++ LOKDocViewPrivate* priv = pDocView->priv; + +- if (pEvent->type == GDK_BUTTON_RELEASE) ++ if (priv->m_bEdit) + { +- if (m_bInDragStartHandle) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag start handle"); +- m_bInDragStartHandle = false; +- return FALSE; +- } +- else if (m_bInDragMiddleHandle) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag middle handle"); +- m_bInDragMiddleHandle = false; +- return FALSE; +- } +- else if (m_bInDragEndHandle) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag end handle"); +- m_bInDragEndHandle = false; +- return FALSE; +- } ++ if (priv->m_bCursorOverlayVisible) ++ priv->m_bCursorOverlayVisible = false; ++ else ++ priv->m_bCursorOverlayVisible = true; ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ } + +- for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) +- { +- if (m_bInDragGraphicHandles[i]) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i); +- m_bInDragGraphicHandles[i] = false; +- m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom)); +- return FALSE; +- } +- } ++ return G_SOURCE_CONTINUE; ++} + +- if (m_bInDragGraphicSelection) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag graphic selection"); +- m_bInDragGraphicSelection = false; +- m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom)); +- return FALSE; +- } +- } ++static void ++commandChanged(LOKDocView* pDocView, const std::string& rString) ++{ ++ g_signal_emit(pDocView, doc_view_signals[COMMAND_CHANGED], 0, rString.c_str()); ++} + +- if (m_bEdit) +- { +- GdkRectangle aClick; +- aClick.x = pEvent->x; +- aClick.y = pEvent->y; +- aClick.width = 1; +- aClick.height = 1; +- if (pEvent->type == GDK_BUTTON_PRESS) +- { +- if (gdk_rectangle_intersect(&aClick, &m_aHandleStartRect, NULL)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag start handle"); +- m_bInDragStartHandle = true; +- return FALSE; +- } +- else if (gdk_rectangle_intersect(&aClick, &m_aHandleMiddleRect, NULL)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag middle handle"); +- m_bInDragMiddleHandle = true; +- return FALSE; +- } +- else if (gdk_rectangle_intersect(&aClick, &m_aHandleEndRect, NULL)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag end handle"); +- m_bInDragEndHandle = true; +- return FALSE; +- } ++static void ++searchNotFound(LOKDocView* pDocView, const std::string& rString) ++{ ++ g_signal_emit(pDocView, doc_view_signals[SEARCH_NOT_FOUND], 0, rString.c_str()); ++} + +- for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) +- { +- if (gdk_rectangle_intersect(&aClick, &m_aGraphicHandleRects[i], NULL)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i); +- m_bInDragGraphicHandles[i] = true; +- m_pDocument->pClass->setGraphicSelection(m_pDocument, +- LOK_SETGRAPHICSELECTION_START, +- pixelToTwip(m_aGraphicHandleRects[i].x + m_aGraphicHandleRects[i].width / 2, m_fZoom), +- pixelToTwip(m_aGraphicHandleRects[i].y + m_aGraphicHandleRects[i].height / 2, m_fZoom)); +- return FALSE; +- } +- } +- } +- } ++static void ++setPart(LOKDocView* pDocView, const std::string& rString) ++{ ++ g_signal_emit(pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString)); ++} + +- if (!m_bEdit) +- lok_doc_view_set_edit(m_pDocView, TRUE); ++/// Implementation of the global callback handler, invoked by globalCallback(); ++static gboolean ++globalCallback (gpointer pData) ++{ ++ CallbackData* pCallback = static_cast(pData); + +- switch (pEvent->type) ++ switch (pCallback->m_nType) + { +- case GDK_BUTTON_PRESS: ++ case LOK_CALLBACK_STATUS_INDICATOR_START: + { +- int nCount = 1; +- if ((pEvent->time - m_nLastButtonPressTime) < 250) +- nCount++; +- m_nLastButtonPressTime = pEvent->time; +- m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), nCount); +- break; + } +- case GDK_BUTTON_RELEASE: ++ break; ++ case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE: + { +- int nCount = 1; +- if ((pEvent->time - m_nLastButtonReleaseTime) < 250) +- nCount++; +- m_nLastButtonReleaseTime = pEvent->time; +- m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), nCount); +- break; + } ++ break; ++ case LOK_CALLBACK_STATUS_INDICATOR_FINISH: ++ { ++ } ++ break; + default: ++ g_assert(false); + break; + } +- return FALSE; ++ delete pCallback; ++ ++ return G_SOURCE_REMOVE; + } + +-void LOKDocView_Impl::getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* pPoint) ++static void ++globalCallbackWorker(int nType, const char* pPayload, void* pData) + { +- GdkPoint aCursor, aHandle; ++ LOKDocView* pDocView = LOK_DOC_VIEW (pData); + +- // Center of the cursor rectangle: we know that it's above the handle. +- aCursor.x = pHandle->x + pHandle->width / 2; +- aCursor.y = pHandle->y - pHandle->height / 2; +- // Center of the handle rectangle. +- aHandle.x = pHandle->x + pHandle->width / 2; +- aHandle.y = pHandle->y + pHandle->height / 2; +- // Our target is the original cursor position + the dragged offset. +- pPoint->x = aCursor.x + (pEvent->x - aHandle.x); +- pPoint->y = aCursor.y + (pEvent->y - aHandle.y); ++ CallbackData* pCallback = new CallbackData(nType, pPayload ? pPayload : "(nil)", pDocView); ++ g_info("LOKDocView_Impl::globalCallbackWorkerImpl: %s, '%s'", callbackTypeToString(nType), pPayload); ++ gdk_threads_add_idle(globalCallback, pCallback); + } + +-gboolean LOKDocView_Impl::signalMotion(GtkWidget* /*pEventBox*/, GdkEventButton* pEvent, LOKDocView* pDocView) ++static GdkRectangle ++payloadToRectangle (LOKDocView* pDocView, const char* pPayload) + { +- return pDocView->m_pImpl->signalMotionImpl(pEvent); +-} ++ LOKDocViewPrivate* priv = pDocView->priv; ++ GdkRectangle aRet; ++ gchar** ppCoordinates = g_strsplit(pPayload, ", ", 4); ++ gchar** ppCoordinate = ppCoordinates; + +-gboolean LOKDocView_Impl::signalMotionImpl(GdkEventButton* pEvent) +-{ +- GdkPoint aPoint; ++ aRet.width = aRet.height = aRet.x = aRet.y = 0; + +- if (m_bInDragMiddleHandle) +- { +- g_info("lcl_signalMotion: dragging the middle handle"); +- LOKDocView_Impl::getDragPoint(&m_aHandleMiddleRect, pEvent, &aPoint); +- m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_RESET, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom)); +- return FALSE; +- } +- if (m_bInDragStartHandle) +- { +- g_info("lcl_signalMotion: dragging the start handle"); +- LOKDocView_Impl::getDragPoint(&m_aHandleStartRect, pEvent, &aPoint); +- m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom)); +- return FALSE; +- } +- if (m_bInDragEndHandle) +- { +- g_info("lcl_signalMotion: dragging the end handle"); +- LOKDocView_Impl::getDragPoint(&m_aHandleEndRect, pEvent, &aPoint); +- m_pDocument->pClass->setTextSelection(m_pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x, m_fZoom), pixelToTwip(aPoint.y, m_fZoom)); +- return FALSE; +- } +- for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) +- { +- if (m_bInDragGraphicHandles[i]) +- { +- g_info("lcl_signalMotion: dragging the graphic handle #%d", i); +- return FALSE; +- } +- } +- if (m_bInDragGraphicSelection) +- { +- g_info("lcl_signalMotion: dragging the graphic selection"); +- return FALSE; +- } ++ if (!*ppCoordinate) ++ return aRet; ++ aRet.x = atoi(*ppCoordinate); ++ if (aRet.x < 0) ++ aRet.x = 0; ++ ++ppCoordinate; ++ if (!*ppCoordinate) ++ return aRet; ++ aRet.y = atoi(*ppCoordinate); ++ if (aRet.y < 0) ++ aRet.y = 0; ++ ++ppCoordinate; ++ if (!*ppCoordinate) ++ return aRet; ++ aRet.width = atoi(*ppCoordinate); ++ if (aRet.x + aRet.width > priv->m_nDocumentWidthTwips) ++ aRet.width = priv->m_nDocumentWidthTwips - aRet.x; ++ ++ppCoordinate; ++ if (!*ppCoordinate) ++ return aRet; ++ aRet.height = atoi(*ppCoordinate); ++ if (aRet.y + aRet.height > priv->m_nDocumentHeightTwips) ++ aRet.height = priv->m_nDocumentHeightTwips - aRet.y; ++ g_strfreev(ppCoordinates); + +- GdkRectangle aMotionInTwipsInTwips; +- aMotionInTwipsInTwips.x = pixelToTwip(pEvent->x, m_fZoom); +- aMotionInTwipsInTwips.y = pixelToTwip(pEvent->y, m_fZoom); +- aMotionInTwipsInTwips.width = 1; +- aMotionInTwipsInTwips.height = 1; +- if (gdk_rectangle_intersect(&aMotionInTwipsInTwips, &m_aGraphicSelection, 0)) +- { +- g_info("lcl_signalMotion: start of drag graphic selection"); +- m_bInDragGraphicSelection = true; +- m_pDocument->pClass->setGraphicSelection(m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom)); +- return FALSE; +- } ++ return aRet; ++} + +- // Otherwise a mouse move, as on the desktop. +- m_pDocument->pClass->postMouseEvent(m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x, m_fZoom), pixelToTwip(pEvent->y, m_fZoom), 1); ++static const std::vector ++payloadToRectangles(LOKDocView* pDocView, const char* pPayload) ++{ ++ std::vector aRet; + +- return FALSE; ++ gchar** ppRectangles = g_strsplit(pPayload, "; ", 0); ++ for (gchar** ppRectangle = ppRectangles; *ppRectangle; ++ppRectangle) ++ aRet.push_back(payloadToRectangle(pDocView, *ppRectangle)); ++ g_strfreev(ppRectangles); ++ ++ return aRet; + } + +-gboolean LOKDocView_Impl::renderOverlay(GtkWidget* /*widget*/, cairo_t *cr, gpointer userdata) ++ ++static void ++setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + { +- LOKDocView *pDocView = LOK_DOC_VIEW (userdata); +- return pDocView->m_pImpl->renderOverlayImpl(cr); ++ LOKDocViewPrivate* priv = pDocView->priv; ++ GdkRectangle aRectanglePixels; ++ GdkPoint aStart, aEnd; ++ ++ aRectanglePixels.x = twipToPixel(rRectangle.x, priv->m_fZoom); ++ aRectanglePixels.y = twipToPixel(rRectangle.y, priv->m_fZoom); ++ aRectanglePixels.width = twipToPixel(rRectangle.width, priv->m_fZoom); ++ aRectanglePixels.height = twipToPixel(rRectangle.height, priv->m_fZoom); ++ ++ aStart.x = aRectanglePixels.y / nTileSizePixels; ++ aStart.y = aRectanglePixels.x / nTileSizePixels; ++ aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; ++ aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; ++ ++ for (int i = aStart.x; i < aEnd.x; i++) ++ for (int j = aStart.y; j < aEnd.y; j++) ++ priv->m_aTileBuffer.setInvalid(i, j); + } + +-gboolean LOKDocView_Impl::renderOverlayImpl(cairo_t *pCairo) ++static gboolean ++callback (gpointer pData) + { +- if (m_bEdit && m_bCursorVisible && m_bCursorOverlayVisible && !isEmptyRectangle(m_aVisibleCursor)) +- { +- if (m_aVisibleCursor.width < 30) +- // Set a minimal width if it would be 0. +- m_aVisibleCursor.width = 30; ++ CallbackData* pCallback = static_cast(pData); ++ LOKDocView* pDocView = LOK_DOC_VIEW (pCallback->m_pDocView); ++ LOKDocViewPrivate* priv = pDocView->priv; + +- cairo_set_source_rgb(pCairo, 0, 0, 0); +- cairo_rectangle(pCairo, +- twipToPixel(m_aVisibleCursor.x, m_fZoom), +- twipToPixel(m_aVisibleCursor.y, m_fZoom), +- twipToPixel(m_aVisibleCursor.width, m_fZoom), +- twipToPixel(m_aVisibleCursor.height, m_fZoom)); +- cairo_fill(pCairo); +- } +- +- if (m_bEdit && m_bCursorVisible && !isEmptyRectangle(m_aVisibleCursor) && m_aTextSelectionRectangles.empty()) ++ switch (pCallback->m_nType) + { +- // Have a cursor, but no selection: we need the middle handle. +- if (!m_pHandleMiddle) +- m_pHandleMiddle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_middle.png"); +- renderHandle(pCairo, m_aVisibleCursor, m_pHandleMiddle, m_aHandleMiddleRect); +- } +- +- if (!m_aTextSelectionRectangles.empty()) ++ case LOK_CALLBACK_INVALIDATE_TILES: + { +- for (GdkRectangle& rRectangle : m_aTextSelectionRectangles) ++ if (pCallback->m_aPayload != "EMPTY") + { +- // Blue with 75% transparency. +- cairo_set_source_rgba(pCairo, ((double)0x43)/255, ((double)0xac)/255, ((double)0xe8)/255, 0.25); +- cairo_rectangle(pCairo, +- twipToPixel(rRectangle.x, m_fZoom), +- twipToPixel(rRectangle.y, m_fZoom), +- twipToPixel(rRectangle.width, m_fZoom), +- twipToPixel(rRectangle.height, m_fZoom)); +- cairo_fill(pCairo); ++ GdkRectangle aRectangle = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); ++ setTilesInvalid(pDocView, aRectangle); + } ++ else ++ priv->m_aTileBuffer.resetAllTiles(); + +- // Handles +- if (!isEmptyRectangle(m_aTextSelectionStart)) +- { +- // Have a start position: we need a start handle. +- if (!m_pHandleStart) +- m_pHandleStart = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_start.png"); +- renderHandle(pCairo, m_aTextSelectionStart, m_pHandleStart, m_aHandleStartRect); +- } +- if (!isEmptyRectangle(m_aTextSelectionEnd)) ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ } ++ break; ++ case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: ++ { ++ priv->m_aVisibleCursor = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); ++ priv->m_bCursorOverlayVisible = true; ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ } ++ break; ++ case LOK_CALLBACK_TEXT_SELECTION: ++ { ++ priv->m_aTextSelectionRectangles = payloadToRectangles(pDocView, pCallback->m_aPayload.c_str()); ++ // In case the selection is empty, then we get no LOK_CALLBACK_TEXT_SELECTION_START/END events. ++ if (priv->m_aTextSelectionRectangles.empty()) + { +- // Have a start position: we need an end handle. +- if (!m_pHandleEnd) +- m_pHandleEnd = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_end.png"); +- renderHandle(pCairo, m_aTextSelectionEnd, m_pHandleEnd, m_aHandleEndRect); ++ memset(&priv->m_aTextSelectionStart, 0, sizeof(priv->m_aTextSelectionStart)); ++ memset(&priv->m_aHandleStartRect, 0, sizeof(priv->m_aHandleStartRect)); ++ memset(&priv->m_aTextSelectionEnd, 0, sizeof(priv->m_aTextSelectionEnd)); ++ memset(&priv->m_aHandleEndRect, 0, sizeof(priv->m_aHandleEndRect)); + } ++ else ++ memset(&priv->m_aHandleMiddleRect, 0, sizeof(priv->m_aHandleMiddleRect)); + } +- +- if (!isEmptyRectangle(m_aGraphicSelection)) ++ break; ++ case LOK_CALLBACK_TEXT_SELECTION_START: + { +- if (!m_pGraphicHandle) +- m_pGraphicHandle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_graphic.png"); +- renderGraphicHandle(pCairo, m_aGraphicSelection, m_pGraphicHandle); ++ priv->m_aTextSelectionStart = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); + } ++ break; ++ case LOK_CALLBACK_TEXT_SELECTION_END: ++ { ++ priv->m_aTextSelectionEnd = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); ++ } ++ break; ++ case LOK_CALLBACK_CURSOR_VISIBLE: ++ { ++ priv->m_bCursorVisible = pCallback->m_aPayload == "true"; ++ } ++ break; ++ case LOK_CALLBACK_GRAPHIC_SELECTION: ++ { ++ if (pCallback->m_aPayload != "EMPTY") ++ priv->m_aGraphicSelection = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); ++ else ++ memset(&priv->m_aGraphicSelection, 0, sizeof(priv->m_aGraphicSelection)); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ } ++ break; ++ case LOK_CALLBACK_HYPERLINK_CLICKED: ++ { ++ GError* pError = NULL; ++ gtk_show_uri(NULL, pCallback->m_aPayload.c_str(), GDK_CURRENT_TIME, &pError); ++ } ++ break; ++ case LOK_CALLBACK_STATE_CHANGED: ++ { ++ commandChanged(pDocView, pCallback->m_aPayload); ++ } ++ break; ++ case LOK_CALLBACK_SEARCH_NOT_FOUND: ++ { ++ searchNotFound(pDocView, pCallback->m_aPayload); ++ } ++ break; ++ case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: ++ { ++ g_info ("%d %d", priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); ++ g_info ("startin"); ++ payloadToSize(pCallback->m_aPayload.c_str(), priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); ++ g_info ("%d %d", priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); ++ gtk_widget_set_size_request(GTK_WIDGET(pDocView), ++ twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom), ++ twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom)); ++ } ++ break; ++ case LOK_CALLBACK_SET_PART: ++ { ++ setPart(pDocView, pCallback->m_aPayload); ++ } ++ break; ++ default: ++ g_assert(false); ++ break; ++ } ++ delete pCallback; + +- return FALSE; +-} +- +-bool LOKDocView_Impl::isEmptyRectangle(const GdkRectangle& rRectangle) +-{ +- return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0; ++ return G_SOURCE_REMOVE; + } + +-void LOKDocView_Impl::setTilesInvalid(const GdkRectangle& rRectangle) ++static void ++callbackWorker (int nType, const char* pPayload, void* pData) + { +- GdkRectangle aRectanglePixels; +- GdkPoint aStart, aEnd; +- +- aRectanglePixels.x = twipToPixel(rRectangle.x, m_fZoom); +- aRectanglePixels.y = twipToPixel(rRectangle.y, m_fZoom); +- aRectanglePixels.width = twipToPixel(rRectangle.width, m_fZoom); +- aRectanglePixels.height = twipToPixel(rRectangle.height, m_fZoom); +- +- aStart.x = aRectanglePixels.y / nTileSizePixels; +- aStart.y = aRectanglePixels.x / nTileSizePixels; +- aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; +- aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; ++ LOKDocView* pDocView = LOK_DOC_VIEW (pData); + +- for (int i = aStart.x; i < aEnd.x; i++) +- for (int j = aStart.y; j < aEnd.y; j++) +- m_aTileBuffer.setInvalid(i, j); ++ CallbackData* pCallback = new CallbackData(nType, pPayload ? pPayload : "(nil)", pDocView); ++ g_info("lok_doc_view_callbackWorker: %s, '%s'", callbackTypeToString(nType), pPayload); ++ gdk_threads_add_idle(callback, pCallback); + } + +-void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, cairo_surface_t* pHandle, GdkRectangle& rRectangle) ++static void ++renderHandle(LOKDocView* pDocView, ++ cairo_t* pCairo, ++ const GdkRectangle& rCursor, ++ cairo_surface_t* pHandle, ++ GdkRectangle& rRectangle) + { ++ LOKDocViewPrivate* priv = pDocView->priv; + GdkPoint aCursorBottom; + int nHandleWidth, nHandleHeight; + double fHandleScale; +@@ -749,16 +567,17 @@ void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, + nHandleWidth = cairo_image_surface_get_width(pHandle); + nHandleHeight = cairo_image_surface_get_height(pHandle); + // We want to scale down the handle, so that its height is the same as the cursor caret. +- fHandleScale = twipToPixel(rCursor.height, m_fZoom) / nHandleHeight; ++ fHandleScale = twipToPixel(rCursor.height, priv->m_fZoom) / nHandleHeight; + // We want the top center of the handle bitmap to be at the bottom center of the cursor rectangle. +- aCursorBottom.x = twipToPixel(rCursor.x, m_fZoom) + twipToPixel(rCursor.width, m_fZoom) / 2 - (nHandleWidth * fHandleScale) / 2; +- aCursorBottom.y = twipToPixel(rCursor.y, m_fZoom) + twipToPixel(rCursor.height, m_fZoom); +- cairo_save(pCairo); ++ aCursorBottom.x = twipToPixel(rCursor.x, priv->m_fZoom) + twipToPixel(rCursor.width, priv->m_fZoom) / 2 - (nHandleWidth * fHandleScale) / 2; ++ aCursorBottom.y = twipToPixel(rCursor.y, priv->m_fZoom) + twipToPixel(rCursor.height, priv->m_fZoom); ++ ++ cairo_save (pCairo); + cairo_translate(pCairo, aCursorBottom.x, aCursorBottom.y); + cairo_scale(pCairo, fHandleScale, fHandleScale); + cairo_set_source_surface(pCairo, pHandle, 0, 0); + cairo_paint(pCairo); +- cairo_restore(pCairo); ++ cairo_restore (pCairo); + + rRectangle.x = aCursorBottom.x; + rRectangle.y = aCursorBottom.y; +@@ -767,23 +586,27 @@ void LOKDocView_Impl::renderHandle(cairo_t* pCairo, const GdkRectangle& rCursor, + } + + /// Renders pHandle around an rSelection rectangle on pCairo. +-void LOKDocView_Impl::renderGraphicHandle(cairo_t* pCairo, const GdkRectangle& rSelection, cairo_surface_t* pHandle) ++static void ++renderGraphicHandle(LOKDocView* pDocView, ++ cairo_t* pCairo, ++ const GdkRectangle& rSelection, ++ cairo_surface_t* pHandle) + { ++ LOKDocViewPrivate* priv = pDocView->priv; + int nHandleWidth, nHandleHeight; + GdkRectangle aSelection; + + nHandleWidth = cairo_image_surface_get_width(pHandle); + nHandleHeight = cairo_image_surface_get_height(pHandle); + +- aSelection.x = twipToPixel(rSelection.x, m_fZoom); +- aSelection.y = twipToPixel(rSelection.y, m_fZoom); +- aSelection.width = twipToPixel(rSelection.width, m_fZoom); +- aSelection.height = twipToPixel(rSelection.height, m_fZoom); ++ aSelection.x = twipToPixel(rSelection.x, priv->m_fZoom); ++ aSelection.y = twipToPixel(rSelection.y, priv->m_fZoom); ++ aSelection.width = twipToPixel(rSelection.width, priv->m_fZoom); ++ aSelection.height = twipToPixel(rSelection.height, priv->m_fZoom); + + for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) + { + int x = aSelection.x, y = aSelection.y; +- cairo_save(pCairo); + + switch (i) + { +@@ -819,364 +642,722 @@ void LOKDocView_Impl::renderGraphicHandle(cairo_t* pCairo, const GdkRectangle& r + x -= nHandleWidth / 2; + y -= nHandleHeight / 2; + +- m_aGraphicHandleRects[i].x = x; +- m_aGraphicHandleRects[i].y = y; +- m_aGraphicHandleRects[i].width = nHandleWidth; +- m_aGraphicHandleRects[i].height = nHandleHeight; ++ priv->m_aGraphicHandleRects[i].x = x; ++ priv->m_aGraphicHandleRects[i].y = y; ++ priv->m_aGraphicHandleRects[i].width = nHandleWidth; ++ priv->m_aGraphicHandleRects[i].height = nHandleHeight; + ++ cairo_save (pCairo); + cairo_translate(pCairo, x, y); + cairo_set_source_surface(pCairo, pHandle, 0, 0); + cairo_paint(pCairo); +- cairo_restore(pCairo); ++ cairo_restore (pCairo); + } + } + +-gboolean LOKDocView_Impl::handleTimeout(gpointer pData) +-{ +- LOKDocView* pDocView = static_cast(pData); +- return pDocView->m_pImpl->handleTimeoutImpl(); +-} + +-gboolean LOKDocView_Impl::handleTimeoutImpl() ++static gboolean ++renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + { +- if (m_bEdit) ++ LOKDocViewPrivate *priv = pDocView->priv; ++ GdkRectangle aVisibleArea; ++ long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom); ++ long nDocumentHeightPixels = twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom); ++ // Total number of rows / columns in this document. ++ guint nRows = ceil((double)nDocumentHeightPixels / nTileSizePixels); ++ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); ++ ++ gdk_cairo_get_clip_rectangle (pCairo, &aVisibleArea); ++ aVisibleArea.x = pixelToTwip (aVisibleArea.x, priv->m_fZoom); ++ aVisibleArea.y = pixelToTwip (aVisibleArea.y, priv->m_fZoom); ++ aVisibleArea.width = pixelToTwip (aVisibleArea.width, priv->m_fZoom); ++ aVisibleArea.height = pixelToTwip (aVisibleArea.height, priv->m_fZoom); ++ ++ // Render the tiles. ++ for (guint nRow = 0; nRow < nRows; ++nRow) + { +- if (m_bCursorOverlayVisible) +- m_bCursorOverlayVisible = false; +- else +- m_bCursorOverlayVisible = true; +- gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); +- } ++ for (guint nColumn = 0; nColumn < nColumns; ++nColumn) ++ { ++ GdkRectangle aTileRectangleTwips, aTileRectanglePixels; ++ bool bPaint = true; + +- return G_SOURCE_CONTINUE; +-} ++ // Determine size of the tile: the rightmost/bottommost tiles may ++ // be smaller, and we need the size to decide if we need to repaint. ++ if (nColumn == nColumns - 1) ++ aTileRectanglePixels.width = nDocumentWidthPixels - nColumn * nTileSizePixels; ++ else ++ aTileRectanglePixels.width = nTileSizePixels; ++ if (nRow == nRows - 1) ++ aTileRectanglePixels.height = nDocumentHeightPixels - nRow * nTileSizePixels; ++ else ++ aTileRectanglePixels.height = nTileSizePixels; + +-GdkRectangle LOKDocView_Impl::payloadToRectangle(const char* pPayload) +-{ +- GdkRectangle aRet; ++ // Determine size and position of the tile in document coordinates, ++ // so we can decide if we can skip painting for partial rendering. ++ aTileRectangleTwips.x = pixelToTwip(nTileSizePixels, priv->m_fZoom) * nColumn; ++ aTileRectangleTwips.y = pixelToTwip(nTileSizePixels, priv->m_fZoom) * nRow; ++ aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, priv->m_fZoom); ++ aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, priv->m_fZoom); + +- aRet.width = aRet.height = aRet.x = aRet.y = 0; +- gchar** ppCoordinates = g_strsplit(pPayload, ", ", 4); +- gchar** ppCoordinate = ppCoordinates; +- if (!*ppCoordinate) +- return aRet; +- aRet.x = atoi(*ppCoordinate); +- if (aRet.x < 0) +- aRet.x = 0; +- ++ppCoordinate; +- if (!*ppCoordinate) +- return aRet; +- aRet.y = atoi(*ppCoordinate); +- if (aRet.y < 0) +- aRet.y = 0; +- ++ppCoordinate; +- if (!*ppCoordinate) +- return aRet; +- aRet.width = atoi(*ppCoordinate); +- if (aRet.x + aRet.width > m_nDocumentWidthTwips) +- aRet.width = m_nDocumentWidthTwips - aRet.x; +- ++ppCoordinate; +- if (!*ppCoordinate) +- return aRet; +- aRet.height = atoi(*ppCoordinate); +- if (aRet.y + aRet.height > m_nDocumentHeightTwips) +- aRet.height = m_nDocumentHeightTwips - aRet.y; +- g_strfreev(ppCoordinates); +- return aRet; ++ if (!gdk_rectangle_intersect(&aVisibleArea, &aTileRectangleTwips, 0)) ++ bPaint = false; ++ ++ if (bPaint) ++ { ++ Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom); ++ GdkPixbuf* pPixBuf = currentTile.getBuffer(); ++ gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, ++ twipToPixel(aTileRectangleTwips.x, priv->m_fZoom), ++ twipToPixel(aTileRectangleTwips.y, priv->m_fZoom)); ++ cairo_paint(pCairo); ++ } ++ } ++ } ++ ++ return FALSE; + } + +-std::vector LOKDocView_Impl::payloadToRectangles(const char* pPayload) ++static gboolean ++renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + { +- std::vector aRet; ++ LOKDocViewPrivate *priv = pDocView->priv; + +- gchar** ppRectangles = g_strsplit(pPayload, "; ", 0); +- for (gchar** ppRectangle = ppRectangles; *ppRectangle; ++ppRectangle) +- aRet.push_back(payloadToRectangle(*ppRectangle)); +- g_strfreev(ppRectangles); ++ if (priv->m_bEdit && priv->m_bCursorVisible && priv->m_bCursorOverlayVisible && !isEmptyRectangle(priv->m_aVisibleCursor)) ++ { ++ if (priv->m_aVisibleCursor.width < 30) ++ // Set a minimal width if it would be 0. ++ priv->m_aVisibleCursor.width = 30; + +- return aRet; +-} ++ cairo_set_source_rgb(pCairo, 0, 0, 0); ++ cairo_rectangle(pCairo, ++ twipToPixel(priv->m_aVisibleCursor.x, priv->m_fZoom), ++ twipToPixel(priv->m_aVisibleCursor.y, priv->m_fZoom), ++ twipToPixel(priv->m_aVisibleCursor.width, priv->m_fZoom), ++ twipToPixel(priv->m_aVisibleCursor.height, priv->m_fZoom)); ++ cairo_fill(pCairo); ++ } + +-/// Returns the string representation of a LibreOfficeKitCallbackType enumeration element. +-const char* LOKDocView_Impl::callbackTypeToString(int nType) +-{ +- switch (nType) ++ if (priv->m_bEdit && priv->m_bCursorVisible && !isEmptyRectangle(priv->m_aVisibleCursor) && priv->m_aTextSelectionRectangles.empty()) + { +- case LOK_CALLBACK_INVALIDATE_TILES: +- return "LOK_CALLBACK_INVALIDATE_TILES"; +- case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: +- return "LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR"; +- case LOK_CALLBACK_TEXT_SELECTION: +- return "LOK_CALLBACK_TEXT_SELECTION"; +- case LOK_CALLBACK_TEXT_SELECTION_START: +- return "LOK_CALLBACK_TEXT_SELECTION_START"; +- case LOK_CALLBACK_TEXT_SELECTION_END: +- return "LOK_CALLBACK_TEXT_SELECTION_END"; +- case LOK_CALLBACK_CURSOR_VISIBLE: +- return "LOK_CALLBACK_CURSOR_VISIBLE"; +- case LOK_CALLBACK_GRAPHIC_SELECTION: +- return "LOK_CALLBACK_GRAPHIC_SELECTION"; +- case LOK_CALLBACK_HYPERLINK_CLICKED: +- return "LOK_CALLBACK_HYPERLINK_CLICKED"; +- case LOK_CALLBACK_STATE_CHANGED: +- return "LOK_CALLBACK_STATE_CHANGED"; +- case LOK_CALLBACK_STATUS_INDICATOR_START: +- return "LOK_CALLBACK_STATUS_INDICATOR_START"; +- case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE: +- return "LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE"; +- case LOK_CALLBACK_STATUS_INDICATOR_FINISH: +- return "LOK_CALLBACK_STATUS_INDICATOR_FINISH"; +- case LOK_CALLBACK_SEARCH_NOT_FOUND: +- return "LOK_CALLBACK_SEARCH_NOT_FOUND"; +- case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: +- return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED"; +- case LOK_CALLBACK_SET_PART: +- return "LOK_CALLBACK_SET_PART"; ++ // Have a cursor, but no selection: we need the middle handle. ++ gchar* handleMiddlePath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_middle.png", NULL); ++ if (!priv->m_pHandleMiddle) ++ priv->m_pHandleMiddle = cairo_image_surface_create_from_png(handleMiddlePath); ++ g_free (handleMiddlePath); ++ renderHandle(pDocView, pCairo, priv->m_aVisibleCursor, priv->m_pHandleMiddle, priv->m_aHandleMiddleRect); ++ } ++ ++ if (!priv->m_aTextSelectionRectangles.empty()) ++ { ++ for (GdkRectangle& rRectangle : priv->m_aTextSelectionRectangles) ++ { ++ // Blue with 75% transparency. ++ cairo_set_source_rgba(pCairo, ((double)0x43)/255, ((double)0xac)/255, ((double)0xe8)/255, 0.25); ++ cairo_rectangle(pCairo, ++ twipToPixel(rRectangle.x, priv->m_fZoom), ++ twipToPixel(rRectangle.y, priv->m_fZoom), ++ twipToPixel(rRectangle.width, priv->m_fZoom), ++ twipToPixel(rRectangle.height, priv->m_fZoom)); ++ cairo_fill(pCairo); ++ } ++ ++ // Handles ++ if (!isEmptyRectangle(priv->m_aTextSelectionStart)) ++ { ++ // Have a start position: we need a start handle. ++ gchar* handleStartPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_start.png", NULL); ++ if (!priv->m_pHandleStart) ++ priv->m_pHandleStart = cairo_image_surface_create_from_png(handleStartPath); ++ renderHandle(pDocView, pCairo, priv->m_aTextSelectionStart, priv->m_pHandleStart, priv->m_aHandleStartRect); ++ g_free (handleStartPath); ++ } ++ if (!isEmptyRectangle(priv->m_aTextSelectionEnd)) ++ { ++ // Have a start position: we need an end handle. ++ gchar* handleEndPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_end.png", NULL); ++ if (!priv->m_pHandleEnd) ++ priv->m_pHandleEnd = cairo_image_surface_create_from_png(handleEndPath); ++ renderHandle(pDocView, pCairo, priv->m_aTextSelectionEnd, priv->m_pHandleEnd, priv->m_aHandleEndRect); ++ g_free (handleEndPath); ++ } + } +- return 0; +-} + +-gboolean LOKDocView_Impl::callback(gpointer pData) +-{ +- LOKDocView_Impl::CallbackData* pCallback = static_cast(pData); +- return pCallback->m_pDocView->m_pImpl->callbackImpl(pCallback); +-} ++ if (!isEmptyRectangle(priv->m_aGraphicSelection)) ++ { ++ gchar* handleGraphicPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_graphic.png", NULL); ++ if (!priv->m_pGraphicHandle) ++ priv->m_pGraphicHandle = cairo_image_surface_create_from_png(handleGraphicPath); ++ renderGraphicHandle(pDocView, pCairo, priv->m_aGraphicSelection, priv->m_pGraphicHandle); ++ g_free (handleGraphicPath); ++ } + +-gboolean LOKDocView_Impl::globalCallback(gpointer pData) +-{ +- LOKDocView_Impl::CallbackData* pCallback = static_cast(pData); +- return globalCallbackImpl(pCallback); ++ return FALSE; + } + +-gboolean LOKDocView_Impl::callbackImpl(CallbackData* pCallback) ++static gboolean ++lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { +- switch (pCallback->m_nType) +- { +- case LOK_CALLBACK_INVALIDATE_TILES: ++ LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); ++ LOKDocViewPrivate *priv = pDocView->priv; ++ ++ g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", ++ (int)pEvent->x, (int)pEvent->y, ++ (int)pixelToTwip(pEvent->x, priv->m_fZoom), ++ (int)pixelToTwip(pEvent->y, priv->m_fZoom)); ++ ++ if (pEvent->type == GDK_BUTTON_RELEASE) + { +- if (pCallback->m_aPayload != "EMPTY") ++ if (priv->m_bInDragStartHandle) + { +- GdkRectangle aRectangle = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); +- setTilesInvalid(aRectangle); ++ g_info("LOKDocView_Impl::signalButton: end of drag start handle"); ++ priv->m_bInDragStartHandle = false; ++ return FALSE; ++ } ++ else if (priv->m_bInDragMiddleHandle) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag middle handle"); ++ priv->m_bInDragMiddleHandle = false; ++ return FALSE; ++ } ++ else if (priv->m_bInDragEndHandle) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag end handle"); ++ priv->m_bInDragEndHandle = false; ++ return FALSE; + } +- else +- m_aTileBuffer.resetAllTiles(); + +- gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); +- } +- break; +- case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR: +- { +- m_aVisibleCursor = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); +- m_bCursorOverlayVisible = true; +- gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); +- } +- break; +- case LOK_CALLBACK_TEXT_SELECTION: +- { +- m_aTextSelectionRectangles = LOKDocView_Impl::payloadToRectangles(pCallback->m_aPayload.c_str()); ++ for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) ++ { ++ if (priv->m_bInDragGraphicHandles[i]) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i); ++ priv->m_bInDragGraphicHandles[i] = false; ++ priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom)); ++ return FALSE; ++ } ++ } + +- // In case the selection is empty, then we get no LOK_CALLBACK_TEXT_SELECTION_START/END events. +- if (m_aTextSelectionRectangles.empty()) ++ if (priv->m_bInDragGraphicSelection) + { +- memset(&m_aTextSelectionStart, 0, sizeof(m_aTextSelectionStart)); +- memset(&m_aHandleStartRect, 0, sizeof(m_aHandleStartRect)); +- memset(&m_aTextSelectionEnd, 0, sizeof(m_aTextSelectionEnd)); +- memset(&m_aHandleEndRect, 0, sizeof(m_aHandleEndRect)); ++ g_info("LOKDocView_Impl::signalButton: end of drag graphic selection"); ++ priv->m_bInDragGraphicSelection = false; ++ priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom)); ++ return FALSE; + } +- else +- memset(&m_aHandleMiddleRect, 0, sizeof(m_aHandleMiddleRect)); + } +- break; +- case LOK_CALLBACK_TEXT_SELECTION_START: ++ ++ if (priv->m_bEdit) + { +- m_aTextSelectionStart = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); ++ GdkRectangle aClick; ++ aClick.x = pEvent->x; ++ aClick.y = pEvent->y; ++ aClick.width = 1; ++ aClick.height = 1; ++ if (pEvent->type == GDK_BUTTON_PRESS) ++ { ++ if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, NULL)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag start handle"); ++ priv->m_bInDragStartHandle = true; ++ return FALSE; ++ } ++ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, NULL)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag middle handle"); ++ priv->m_bInDragMiddleHandle = true; ++ return FALSE; ++ } ++ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, NULL)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag end handle"); ++ priv->m_bInDragEndHandle = true; ++ return FALSE; ++ } ++ ++ for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) ++ { ++ if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], NULL)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i); ++ priv->m_bInDragGraphicHandles[i] = true; ++ priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, ++ LOK_SETGRAPHICSELECTION_START, ++ pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom), ++ pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom)); ++ return FALSE; ++ } ++ } ++ } + } +- break; +- case LOK_CALLBACK_TEXT_SELECTION_END: ++ ++ if (!priv->m_bEdit) ++ lok_doc_view_set_edit(pDocView, TRUE); ++ ++ switch (pEvent->type) + { +- m_aTextSelectionEnd = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); +- } +- break; +- case LOK_CALLBACK_CURSOR_VISIBLE: ++ case GDK_BUTTON_PRESS: + { +- m_bCursorVisible = pCallback->m_aPayload == "true"; ++ int nCount = 1; ++ if ((pEvent->time - priv->m_nLastButtonPressTime) < 250) ++ nCount++; ++ priv->m_nLastButtonPressTime = pEvent->time; ++ priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount); ++ break; + } +- break; +- case LOK_CALLBACK_GRAPHIC_SELECTION: ++ case GDK_BUTTON_RELEASE: + { +- if (pCallback->m_aPayload != "EMPTY") +- m_aGraphicSelection = LOKDocView_Impl::payloadToRectangle(pCallback->m_aPayload.c_str()); +- else +- memset(&m_aGraphicSelection, 0, sizeof(m_aGraphicSelection)); +- gtk_widget_queue_draw(GTK_WIDGET(m_pDocView)); ++ int nCount = 1; ++ if ((pEvent->time - priv->m_nLastButtonReleaseTime) < 250) ++ nCount++; ++ priv->m_nLastButtonReleaseTime = pEvent->time; ++ priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount); ++ break; + } +- break; +- case LOK_CALLBACK_HYPERLINK_CLICKED: ++ default: ++ break; ++ } ++ return FALSE; ++} ++ ++static void ++getDragPoint(GdkRectangle* pHandle, ++ GdkEventMotion* pEvent, ++ GdkPoint* pPoint) ++{ ++ GdkPoint aCursor, aHandle; ++ ++ // Center of the cursor rectangle: we know that it's above the handle. ++ aCursor.x = pHandle->x + pHandle->width / 2; ++ aCursor.y = pHandle->y - pHandle->height / 2; ++ // Center of the handle rectangle. ++ aHandle.x = pHandle->x + pHandle->width / 2; ++ aHandle.y = pHandle->y + pHandle->height / 2; ++ // Our target is the original cursor position + the dragged offset. ++ pPoint->x = aCursor.x + (pEvent->x - aHandle.x); ++ pPoint->y = aCursor.y + (pEvent->y - aHandle.y); ++} ++ ++static gboolean ++lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) ++{ ++ LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); ++ LOKDocViewPrivate *priv = pDocView->priv; ++ GdkPoint aPoint; ++ ++ if (priv->m_bInDragMiddleHandle) + { +- GError* pError = NULL; +- gtk_show_uri(NULL, pCallback->m_aPayload.c_str(), GDK_CURRENT_TIME, &pError); ++ g_info("lcl_signalMotion: dragging the middle handle"); ++ getDragPoint(&priv->m_aHandleMiddleRect, pEvent, &aPoint); ++ priv->m_pDocument->pClass->setTextSelection(priv->m_pDocument, LOK_SETTEXTSELECTION_RESET, pixelToTwip(aPoint.x, priv->m_fZoom), pixelToTwip(aPoint.y, priv->m_fZoom)); ++ return FALSE; + } +- break; +- case LOK_CALLBACK_STATE_CHANGED: ++ if (priv->m_bInDragStartHandle) + { +- commandChanged(pCallback->m_aPayload); ++ g_info("lcl_signalMotion: dragging the start handle"); ++ getDragPoint(&priv->m_aHandleStartRect, pEvent, &aPoint); ++ priv->m_pDocument->pClass->setTextSelection(priv->m_pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x, priv->m_fZoom), pixelToTwip(aPoint.y, priv->m_fZoom)); ++ return FALSE; + } +- break; +- case LOK_CALLBACK_SEARCH_NOT_FOUND: ++ if (priv->m_bInDragEndHandle) + { +- searchNotFound(pCallback->m_aPayload); ++ g_info("lcl_signalMotion: dragging the end handle"); ++ getDragPoint(&priv->m_aHandleEndRect, pEvent, &aPoint); ++ priv->m_pDocument->pClass->setTextSelection(priv->m_pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x, priv->m_fZoom), pixelToTwip(aPoint.y, priv->m_fZoom)); ++ return FALSE; + } +- break; +- case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: ++ for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) + { +- payloadToSize(pCallback->m_aPayload.c_str(), m_nDocumentWidthTwips, m_nDocumentHeightTwips); +- gtk_widget_set_size_request(GTK_WIDGET(m_pDocView), +- twipToPixel(m_nDocumentWidthTwips, m_fZoom), +- twipToPixel(m_nDocumentHeightTwips, m_fZoom)); ++ if (priv->m_bInDragGraphicHandles[i]) ++ { ++ g_info("lcl_signalMotion: dragging the graphic handle #%d", i); ++ return FALSE; ++ } + } +- break; +- case LOK_CALLBACK_SET_PART: ++ if (priv->m_bInDragGraphicSelection) + { +- setPart(pCallback->m_aPayload); ++ g_info("lcl_signalMotion: dragging the graphic selection"); ++ return FALSE; + } +- break; +- default: +- g_assert(false); +- break; ++ ++ GdkRectangle aMotionInTwipsInTwips; ++ aMotionInTwipsInTwips.x = pixelToTwip(pEvent->x, priv->m_fZoom); ++ aMotionInTwipsInTwips.y = pixelToTwip(pEvent->y, priv->m_fZoom); ++ aMotionInTwipsInTwips.width = 1; ++ aMotionInTwipsInTwips.height = 1; ++ if (gdk_rectangle_intersect(&aMotionInTwipsInTwips, &priv->m_aGraphicSelection, 0)) ++ { ++ g_info("lcl_signalMotion: start of drag graphic selection"); ++ priv->m_bInDragGraphicSelection = true; ++ priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom)); ++ return FALSE; + } +- delete pCallback; + +- return G_SOURCE_REMOVE; +-} ++ // Otherwise a mouse move, as on the desktop. ++ priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), 1); + +-void LOKDocView_Impl::callbackWorker(int nType, const char* pPayload, void* pData) +-{ +- LOKDocView* pDocView = static_cast(pData); +- pDocView->m_pImpl->callbackWorkerImpl(nType, pPayload); ++ return FALSE; + } + +-void LOKDocView_Impl::globalCallbackWorker(int nType, const char* pPayload, void* pData) ++static void lok_doc_view_init (LOKDocView* pDocView) + { +- LOKDocView* pDocView = static_cast(pData); +- pDocView->m_pImpl->globalCallbackWorkerImpl(nType, pPayload); ++ pDocView->priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ pDocView->priv->m_bCursorVisible = true; ++ ++ gtk_widget_add_events(GTK_WIDGET(pDocView), ++ GDK_BUTTON_PRESS_MASK ++ |GDK_BUTTON_RELEASE_MASK ++ |GDK_BUTTON_MOTION_MASK ++ |GDK_KEY_PRESS_MASK ++ |GDK_KEY_RELEASE_MASK); + } + +-void LOKDocView_Impl::callbackWorkerImpl(int nType, const char* pPayload) ++static void lok_doc_view_set_property (GObject* object, guint propId, const GValue *value, GParamSpec *pspec) + { +- LOKDocView_Impl::CallbackData* pCallback = new LOKDocView_Impl::CallbackData(nType, pPayload ? pPayload : "(nil)", m_pDocView); +- g_info("lok_doc_view_callback_worker: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload); +- gdk_threads_add_idle(LOKDocView_Impl::callback, pCallback); ++ LOKDocView* pDocView = LOK_DOC_VIEW (object); ++ LOKDocViewPrivate* priv = pDocView->priv; ++ ++ switch (propId) ++ { ++ case PROP_LO_PATH: ++ priv->m_aLOPath = g_value_dup_string (value); ++ break; ++ case PROP_DOC_PATH: ++ priv->m_aDocPath = g_value_dup_string (value); ++ break; ++ case PROP_EDITABLE: ++ lok_doc_view_set_edit (pDocView, g_value_get_boolean (value)); ++ break; ++ case PROP_ZOOM: ++ lok_doc_view_set_zoom (pDocView, g_value_get_float (value)); ++ break; ++ case PROP_DOC_WIDTH: ++ priv->m_nDocumentWidthTwips = g_value_get_long (value); ++ break; ++ case PROP_DOC_HEIGHT: ++ priv->m_nDocumentHeightTwips = g_value_get_long (value); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec); ++ } + } + +-void LOKDocView_Impl::globalCallbackWorkerImpl(int nType, const char* pPayload) ++static void lok_doc_view_get_property (GObject* object, guint propId, GValue *value, GParamSpec *pspec) + { +- LOKDocView_Impl::CallbackData* pCallback = new LOKDocView_Impl::CallbackData(nType, pPayload ? pPayload : "(nil)", m_pDocView); +- g_info("LOKDocView_Impl::globalCallbackWorkerImpl: %s, '%s'", LOKDocView_Impl::callbackTypeToString(nType), pPayload); +- gdk_threads_add_idle(LOKDocView_Impl::globalCallback, pCallback); ++ LOKDocView* pDocView = LOK_DOC_VIEW (object); ++ LOKDocViewPrivate* priv = pDocView->priv; ++ ++ switch (propId) ++ { ++ case PROP_LO_PATH: ++ g_value_set_string (value, priv->m_aLOPath); ++ break; ++ case PROP_DOC_PATH: ++ g_value_set_string (value, priv->m_aDocPath); ++ break; ++ case PROP_EDITABLE: ++ g_value_set_boolean (value, priv->m_bEdit); ++ break; ++ case PROP_LOAD_PROGRESS: ++ g_value_set_uint (value, priv->m_nLoadProgress); ++ break; ++ case PROP_ZOOM: ++ g_value_set_float (value, priv->m_fZoom); ++ break; ++ case PROP_IS_LOADING: ++ g_value_set_boolean (value, priv->m_bIsLoading); ++ break; ++ case PROP_DOC_WIDTH: ++ g_value_set_long (value, priv->m_nDocumentWidthTwips); ++ break; ++ case PROP_DOC_HEIGHT: ++ g_value_set_long (value, priv->m_nDocumentHeightTwips); ++ break; ++ case PROP_CAN_ZOOM_IN: ++ g_value_set_boolean (value, priv->m_bCanZoomIn); ++ break; ++ case PROP_CAN_ZOOM_OUT: ++ g_value_set_boolean (value, priv->m_bCanZoomOut); ++ break; ++ default: ++ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec); ++ } + } + +-void LOKDocView_Impl::commandChanged(const std::string& rString) ++static gboolean lok_doc_view_draw (GtkWidget* pWidget, cairo_t* pCairo) + { +- g_signal_emit(m_pDocView, doc_view_signals[COMMAND_CHANGED], 0, rString.c_str()); ++ LOKDocView *pDocView = LOK_DOC_VIEW (pWidget); ++ ++ renderDocument (pDocView, pCairo); ++ renderOverlay (pDocView, pCairo); ++ ++ return FALSE; + } + +-void LOKDocView_Impl::searchNotFound(const std::string& rString) ++static void lok_doc_view_finalize (GObject* object) + { +- g_signal_emit(m_pDocView, doc_view_signals[SEARCH_NOT_FOUND], 0, rString.c_str()); ++ LOKDocView* pDocView = LOK_DOC_VIEW (object); ++ LOKDocViewPrivate* priv = pDocView->priv; ++ ++ if (priv->m_pDocument) ++ priv->m_pDocument->pClass->destroy (priv->m_pDocument); ++ if (priv->m_pOffice) ++ priv->m_pOffice->pClass->destroy (priv->m_pOffice); ++ ++ G_OBJECT_CLASS (lok_doc_view_parent_class)->finalize (object); + } + +-void LOKDocView_Impl::setPart(const std::string& rString) ++static void lok_doc_view_constructed (GObject* object) + { +- g_signal_emit(m_pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString)); ++ LOKDocView* pDocView = LOK_DOC_VIEW (object); ++ LOKDocViewPrivate* priv = pDocView->priv; ++ ++ G_OBJECT_CLASS (lok_doc_view_parent_class)->constructed (object); ++ ++ pDocView->priv->m_pOffice = lok_init (priv->m_aLOPath); + } + + static void lok_doc_view_class_init (LOKDocViewClass* pClass) + { +- GObjectClass *gobject_class = G_OBJECT_CLASS(pClass); +- pClass->edit_changed = NULL; ++ GObjectClass *pGObjectClass = G_OBJECT_CLASS(pClass); ++ GtkWidgetClass *pWidgetClass = GTK_WIDGET_CLASS(pClass); ++ ++ pGObjectClass->get_property = lok_doc_view_get_property; ++ pGObjectClass->set_property = lok_doc_view_set_property; ++ pGObjectClass->finalize = lok_doc_view_finalize; ++ pGObjectClass->constructed = lok_doc_view_constructed; ++ ++ pWidgetClass->draw = lok_doc_view_draw; ++ pWidgetClass->button_press_event = lok_doc_view_signal_button; ++ pWidgetClass->button_release_event = lok_doc_view_signal_button; ++ pWidgetClass->motion_notify_event = lok_doc_view_signal_motion; ++ ++ /** ++ * LOKDocView:lopath: ++ * ++ * The absolute path of the LibreOffice install. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_LO_PATH, ++ g_param_spec_string("lopath", ++ "LO Path", ++ "LibreOffice Install Path", ++ 0, ++ static_cast(G_PARAM_READWRITE ++ | G_PARAM_CONSTRUCT_ONLY))); ++ ++ /** ++ * LOKDocView:docpath: ++ * ++ * The path of the document that is currently being viewed. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_DOC_PATH, ++ g_param_spec_string("docpath", ++ "Document Path", ++ "The URI of the document to open", ++ 0, ++ G_PARAM_READWRITE)); ++ ++ /** ++ * LOKDocView:editable: ++ * ++ * Whether the document loaded inside of #LOKDocView is editable or not. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_EDITABLE, ++ g_param_spec_boolean("editable", ++ "Editable", ++ "Whether the content is in edit mode or not", ++ FALSE, ++ G_PARAM_READWRITE)); ++ ++ /** ++ * LOKDocView:load-progress: ++ * ++ * The percent completion of the current loading operation of the ++ * document. This can be used for progress bars. Note that this is not a ++ * very accurate progress indicator, and its value might reset it couple of ++ * times to 0 and start again. You should not rely on its numbers. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_LOAD_PROGRESS, ++ g_param_spec_int("load-progress", ++ "Estimated Load Progress", ++ "Whether the content is in edit mode or not", ++ 0, 100, 0, ++ G_PARAM_READABLE)); ++ ++ /** ++ * LOKDocView:zoom-level: ++ * ++ * The current zoom level of the document loaded inside #LOKDocView. The ++ * default value is 1.0. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_ZOOM, ++ g_param_spec_float("zoom-level", ++ "Zoom Level", ++ "The current zoom level of the content", ++ 0, 5.0, 1.0, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT))); ++ ++ /** ++ * LOKDocView:is-loading: ++ * ++ * Whether the requested document is being loaded or not. %TRUE if it is ++ * being loaded, otherwise %FALSE. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_IS_LOADING, ++ g_param_spec_boolean("is-loading", ++ "Is Loading", ++ "Whether the view is loading a document", ++ FALSE, ++ G_PARAM_READABLE)); ++ ++ /** ++ * LOKDocView:doc-width: ++ * ++ * The width of the currently loaded document in #LOKDocView in twips. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_DOC_WIDTH, ++ g_param_spec_long("doc-width", ++ "Document Width", ++ "Width of the document in twips", ++ 0, G_MAXLONG, 0, ++ G_PARAM_READWRITE)); ++ ++ /** ++ * LOKDocView:doc-height: ++ * ++ * The height of the currently loaded document in #LOKDocView in twips. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_DOC_HEIGHT, ++ g_param_spec_long("doc-height", ++ "Document Height", ++ "Height of the document in twips", ++ 0, G_MAXLONG, 0, ++ G_PARAM_READWRITE)); ++ ++ /** ++ * LOKDocView:can-zoom-in: ++ * ++ * It tells whether the view can further be zoomed in or not. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_CAN_ZOOM_IN, ++ g_param_spec_boolean("can-zoom-in", ++ "Can Zoom In", ++ "Whether the view can be zoomed in further", ++ TRUE, ++ static_cast(G_PARAM_READABLE ++ | G_PARAM_STATIC_STRINGS))); ++ ++ /** ++ * LOKDocView:can-zoom-out: ++ * ++ * It tells whether the view can further be zoomed out or not. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_CAN_ZOOM_OUT, ++ g_param_spec_boolean("can-zoom-out", ++ "Can Zoom Out", ++ "Whether the view can be zoomed out further", ++ TRUE, ++ static_cast(G_PARAM_READABLE ++ | G_PARAM_STATIC_STRINGS))); ++ ++ /** ++ * LOKDocView::edit-changed: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @bEdit: the new edit value of the view ++ */ + doc_view_signals[EDIT_CHANGED] = + g_signal_new("edit-changed", +- G_TYPE_FROM_CLASS (gobject_class), ++ G_TYPE_FROM_CLASS (pGObjectClass), + G_SIGNAL_RUN_FIRST, +- G_STRUCT_OFFSET (LOKDocViewClass, edit_changed), ++ 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); +- pClass->command_changed = NULL; ++ ++ /** ++ * LOKDocView::command-changed: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aCommand: the command that was changed ++ */ + doc_view_signals[COMMAND_CHANGED] = + g_signal_new("command-changed", +- G_TYPE_FROM_CLASS(gobject_class), ++ G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, +- G_STRUCT_OFFSET(LOKDocViewClass, command_changed), ++ 0, + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +- pClass->search_not_found = 0; ++ ++ /** ++ * LOKDocView::search-not-found: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aCommand: the string for which the search was not found. ++ */ + doc_view_signals[SEARCH_NOT_FOUND] = + g_signal_new("search-not-found", +- G_TYPE_FROM_CLASS(gobject_class), ++ G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, +- G_STRUCT_OFFSET(LOKDocViewClass, search_not_found), ++ 0, + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +- pClass->part_changed = 0; ++ ++ /** ++ * LOKDocView::part-changed: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aCommand: the part number which the view changed to ++ */ + doc_view_signals[PART_CHANGED] = + g_signal_new("part-changed", +- G_TYPE_FROM_CLASS(gobject_class), ++ G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, +- G_STRUCT_OFFSET(LOKDocViewClass, part_changed), ++ 0, + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); +-} + +-static void lok_doc_view_init (LOKDocView* pDocView) +-{ +- pDocView->m_pImpl = new LOKDocView_Impl(pDocView); +- +- g_signal_connect(G_OBJECT(pDocView), +- "draw", +- G_CALLBACK(LOKDocView_Impl::renderDocument), pDocView); +- g_signal_connect(G_OBJECT(pDocView), +- "draw", +- G_CALLBACK(LOKDocView_Impl::renderOverlay), pDocView); +- gtk_widget_add_events(GTK_WIDGET(pDocView), +- GDK_BUTTON_PRESS_MASK +- |GDK_BUTTON_RELEASE_MASK +- |GDK_BUTTON_MOTION_MASK); +- +- g_signal_connect(G_OBJECT(pDocView), +- "button-press-event", +- G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); +- g_signal_connect(G_OBJECT(pDocView), +- "button-release-event", +- G_CALLBACK(LOKDocView_Impl::signalButton), pDocView); +- g_signal_connect(G_OBJECT(pDocView), +- "motion-notify-event", +- G_CALLBACK(LOKDocView_Impl::signalMotion), pDocView); +- +- g_signal_connect(G_OBJECT(pDocView), "destroy", G_CALLBACK(LOKDocView_Impl::destroy), 0); ++ /** ++ * LOKDocView::hyperlinked-clicked: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aHyperlink: the URI which the application should handle ++ */ ++ doc_view_signals[PART_CHANGED] = ++ g_signal_new("hyperlinked-clicked", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, NULL, ++ g_cclosure_marshal_VOID__STRING, ++ G_TYPE_NONE, 1, ++ G_TYPE_STRING); + } + ++ ++ + /** + * lok_doc_view_new: + * @pPath: LibreOffice install path. + * + * Returns: The #LOKDocView widget instance. + */ +-SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new(const char* pPath) ++SAL_DLLPUBLIC_EXPORT GtkWidget* ++lok_doc_view_new (const char* pPath) + { +- LOKDocView* pDocView = LOK_DOC_VIEW(g_object_new(LOK_TYPE_DOC_VIEW, NULL)); +- pDocView->m_pImpl->m_pOffice = lok_init (pPath); +- if (pDocView->m_pImpl->m_pOffice == NULL) +- return NULL; +- return GTK_WIDGET( pDocView ); ++ return GTK_WIDGET (g_object_new(LOK_TYPE_DOC_VIEW, "lopath", pPath, NULL)); + } + + /** +@@ -1186,47 +1367,47 @@ SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new(const char* pPath) + * + * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise + */ +-SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, char* pPath ) ++SAL_DLLPUBLIC_EXPORT gboolean ++lok_doc_view_open_document (LOKDocView* pDocView, char* pPath) + { +- if ( pDocView->m_pImpl->m_pDocument ) ++ if ( pDocView->priv->m_pDocument ) + { +- pDocView->m_pImpl->m_pDocument->pClass->destroy( pDocView->m_pImpl->m_pDocument ); +- pDocView->m_pImpl->m_pDocument = 0; ++ pDocView->priv->m_pDocument->pClass->destroy( pDocView->priv->m_pDocument ); ++ pDocView->priv->m_pDocument = 0; + } + +- pDocView->m_pImpl->m_pOffice->pClass->registerCallback(pDocView->m_pImpl->m_pOffice, &LOKDocView_Impl::globalCallbackWorker, pDocView); +- pDocView->m_pImpl->m_pDocument = pDocView->m_pImpl->m_pOffice->pClass->documentLoad( pDocView->m_pImpl->m_pOffice, ++ pDocView->priv->m_pOffice->pClass->registerCallback(pDocView->priv->m_pOffice, globalCallbackWorker, pDocView); ++ pDocView->priv->m_pDocument = pDocView->priv->m_pOffice->pClass->documentLoad( pDocView->priv->m_pOffice, + pPath ); +- if ( !pDocView->m_pImpl->m_pDocument ) ++ if ( !pDocView->priv->m_pDocument ) + { + // FIXME: should have a GError parameter and populate it. +- char *pError = pDocView->m_pImpl->m_pOffice->pClass->getError( pDocView->m_pImpl->m_pOffice ); ++ char *pError = pDocView->priv->m_pOffice->pClass->getError( pDocView->priv->m_pOffice ); + fprintf( stderr, "Error opening document '%s'\n", pError ); + return FALSE; + } + else + { +- pDocView->m_pImpl->m_pDocument->pClass->initializeForRendering(pDocView->m_pImpl->m_pDocument); +- pDocView->m_pImpl->m_pDocument->pClass->registerCallback(pDocView->m_pImpl->m_pDocument, &LOKDocView_Impl::callbackWorker, pDocView); +- pDocView->m_pImpl->m_pDocument->pClass->getDocumentSize(pDocView->m_pImpl->m_pDocument, &pDocView->m_pImpl->m_nDocumentWidthTwips, &pDocView->m_pImpl->m_nDocumentHeightTwips); +- g_timeout_add(600, &LOKDocView_Impl::handleTimeout, pDocView); +- +- float zoom = pDocView->m_pImpl->m_fZoom; +- long nDocumentWidthTwips = pDocView->m_pImpl->m_nDocumentWidthTwips; +- long nDocumentHeightTwips = pDocView->m_pImpl->m_nDocumentHeightTwips; ++ pDocView->priv->m_pDocument->pClass->initializeForRendering(pDocView->priv->m_pDocument); ++ pDocView->priv->m_pDocument->pClass->registerCallback(pDocView->priv->m_pDocument, callbackWorker, pDocView); ++ pDocView->priv->m_pDocument->pClass->getDocumentSize(pDocView->priv->m_pDocument, &pDocView->priv->m_nDocumentWidthTwips, &pDocView->priv->m_nDocumentHeightTwips); ++ g_timeout_add(600, handleTimeout, pDocView); ++ ++ float zoom = pDocView->priv->m_fZoom; ++ long nDocumentWidthTwips = pDocView->priv->m_nDocumentWidthTwips; ++ long nDocumentHeightTwips = pDocView->priv->m_nDocumentHeightTwips; + long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); + long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); + // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + + +- pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, +- nColumns); ++ pDocView->priv->m_aTileBuffer = TileBuffer(pDocView->priv->m_pDocument, ++ nColumns); + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); + } +- + return TRUE; + } + +@@ -1236,9 +1417,10 @@ SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_open_document( LOKDocView* pDocView, + * + * Returns: The #LibreOfficeKitDocument instance the widget is currently showing + */ +-SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocView* pDocView) ++SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* ++lok_doc_view_get_document (LOKDocView* pDocView) + { +- return pDocView->m_pImpl->m_pDocument; ++ return pDocView->priv->m_pDocument; + } + + /** +@@ -1248,16 +1430,17 @@ SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* lok_doc_view_get_document(LOKDocVie + * + * Sets the new zoom level for the widget. + */ +-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZoom ) ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + { +- pDocView->m_pImpl->m_fZoom = fZoom; +- long nDocumentWidthPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentWidthTwips, fZoom); +- long nDocumentHeightPixels = twipToPixel(pDocView->m_pImpl->m_nDocumentHeightTwips, fZoom); ++ pDocView->priv->m_fZoom = fZoom; ++ long nDocumentWidthPixels = twipToPixel(pDocView->priv->m_nDocumentWidthTwips, fZoom); ++ long nDocumentHeightPixels = twipToPixel(pDocView->priv->m_nDocumentHeightTwips, fZoom); + // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- pDocView->m_pImpl->m_aTileBuffer = TileBuffer(pDocView->m_pImpl->m_pDocument, +- nColumns); ++ pDocView->priv->m_aTileBuffer = TileBuffer(pDocView->priv->m_pDocument, ++ nColumns); + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +@@ -1269,35 +1452,41 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_zoom ( LOKDocView* pDocView, float fZ + * + * Returns: The current zoom factor value in float for pDocView + */ +-SAL_DLLPUBLIC_EXPORT float lok_doc_view_get_zoom ( LOKDocView* pDocView ) ++SAL_DLLPUBLIC_EXPORT float ++lok_doc_view_get_zoom (LOKDocView* pDocView) + { +- return pDocView->m_pImpl->m_fZoom; ++ return pDocView->priv->m_fZoom; + } + +-SAL_DLLPUBLIC_EXPORT int lok_doc_view_get_parts( LOKDocView* pDocView ) ++SAL_DLLPUBLIC_EXPORT int ++lok_doc_view_get_parts (LOKDocView* pDocView) + { +- return pDocView->m_pImpl->m_pDocument->pClass->getParts( pDocView->m_pImpl->m_pDocument ); ++ return pDocView->priv->m_pDocument->pClass->getParts( pDocView->priv->m_pDocument ); + } + +-SAL_DLLPUBLIC_EXPORT int lok_doc_view_get_part( LOKDocView* pDocView ) ++SAL_DLLPUBLIC_EXPORT int ++lok_doc_view_get_part (LOKDocView* pDocView) + { +- return pDocView->m_pImpl->m_pDocument->pClass->getPart( pDocView->m_pImpl->m_pDocument ); ++ return pDocView->priv->m_pDocument->pClass->getPart( pDocView->priv->m_pDocument ); + } + +-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_part( LOKDocView* pDocView, int nPart) ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + { +- pDocView->m_pImpl->m_pDocument->pClass->setPart( pDocView->m_pImpl->m_pDocument, nPart ); ++ pDocView->priv->m_pDocument->pClass->setPart( pDocView->priv->m_pDocument, nPart ); + } + +-SAL_DLLPUBLIC_EXPORT char* lok_doc_view_get_part_name( LOKDocView* pDocView, int nPart ) ++SAL_DLLPUBLIC_EXPORT char* ++lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart) + { +- return pDocView->m_pImpl->m_pDocument->pClass->getPartName( pDocView->m_pImpl->m_pDocument, nPart ); ++ return pDocView->priv->m_pDocument->pClass->getPartName( pDocView->priv->m_pDocument, nPart ); + } + +-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_partmode( LOKDocView* pDocView, +- int nPartMode ) ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_set_partmode(LOKDocView* pDocView, ++ int nPartMode) + { +- pDocView->m_pImpl->m_pDocument->pClass->setPartMode( pDocView->m_pImpl->m_pDocument, nPartMode ); ++ pDocView->priv->m_pDocument->pClass->setPartMode( pDocView->priv->m_pDocument, nPartMode ); + } + + /** +@@ -1307,19 +1496,20 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_partmode( LOKDocView* pDocView, + * + * Sets the edit-mode for pDocView + */ +-SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView, +- gboolean bEdit ) ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_set_edit(LOKDocView* pDocView, ++ gboolean bEdit) + { +- gboolean bWasEdit = pDocView->m_pImpl->m_bEdit; ++ gboolean bWasEdit = pDocView->priv->m_bEdit; + +- if (!pDocView->m_pImpl->m_bEdit && bEdit) ++ if (!pDocView->priv->m_bEdit && bEdit) + g_info("lok_doc_view_set_edit: entering edit mode"); +- else if (pDocView->m_pImpl->m_bEdit && !bEdit) ++ else if (pDocView->priv->m_bEdit && !bEdit) + { + g_info("lok_doc_view_set_edit: leaving edit mode"); +- pDocView->m_pImpl->m_pDocument->pClass->resetSelection(pDocView->m_pImpl->m_pDocument); ++ pDocView->priv->m_pDocument->pClass->resetSelection(pDocView->priv->m_pDocument); + } +- pDocView->m_pImpl->m_bEdit = bEdit; ++ pDocView->priv->m_bEdit = bEdit; + g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit); + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } +@@ -1330,20 +1520,39 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_set_edit( LOKDocView* pDocView, + * + * Returns: %TRUE if the given pDocView is in edit mode. + */ +-SAL_DLLPUBLIC_EXPORT gboolean lok_doc_view_get_edit(LOKDocView* pDocView) ++SAL_DLLPUBLIC_EXPORT gboolean ++lok_doc_view_get_edit (LOKDocView* pDocView) + { +- return pDocView->m_pImpl->m_bEdit; ++ return pDocView->priv->m_bEdit; + } + +-SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_command(LOKDocView* pDocView, const char* pCommand, const char* pArguments) ++/** ++ * lok_doc_view_post_command: ++ * @pDocView: the #LOKDocView instance ++ * @pCommand: the command to issue to LO core ++ * @pArguments: the arguments to the given command ++ * ++ * This methods forwards your command to LO core. ++*/ ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_post_command (LOKDocView* pDocView, ++ const char* pCommand, ++ const char* pArguments) + { +- pDocView->m_pImpl->m_pDocument->pClass->postUnoCommand(pDocView->m_pImpl->m_pDocument, pCommand, pArguments); ++ pDocView->priv->m_pDocument->pClass->postUnoCommand(pDocView->priv->m_pDocument, pCommand, pArguments); + } + +-SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer pData) ++/** ++ * lok_doc_view_post_key: ++ * @pDocView: the #LOKDocView instance ++ * @pEvent: the #GdkEventKey containing information about the event ++ * ++ * This methods forwards your key events to the LO core. ++*/ ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_post_key (LOKDocView* pDocView, GdkEvent* pEvent) + { +- LOKDocView* pDocView = static_cast(pData); +- pDocView->m_pImpl->signalKey(pEvent); ++ signalKey(pDocView, pEvent); + } + + /** +@@ -1355,9 +1564,10 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_post_key(GtkWidget* /*pWidget*/, GdkEvent + * + * Returns: The corresponding value in twips + */ +-SAL_DLLPUBLIC_EXPORT float lok_doc_view_pixel_to_twip(LOKDocView* pDocView, float fInput) ++SAL_DLLPUBLIC_EXPORT float ++lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + { +- return pixelToTwip(fInput, pDocView->m_pImpl->m_fZoom); ++ return pixelToTwip(fInput, pDocView->priv->m_fZoom); + } + + /** +@@ -1369,10 +1579,10 @@ SAL_DLLPUBLIC_EXPORT float lok_doc_view_pixel_to_twip(LOKDocView* pDocView, floa + * + * Returns: The corresponding value in pixels + */ +-SAL_DLLPUBLIC_EXPORT float lok_doc_view_twip_to_pixel(LOKDocView* pDocView, float fInput) ++SAL_DLLPUBLIC_EXPORT float ++lok_doc_view_twip_to_pixel (LOKDocView* pDocView, float fInput) + { +- return twipToPixel(fInput, pDocView->m_pImpl->m_fZoom); ++ return twipToPixel(fInput, pDocView->priv->m_fZoom); + } + +- + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0051-Superfluous-block-lets-merge-into-one.patch b/SOURCES/0051-Superfluous-block-lets-merge-into-one.patch new file mode 100644 index 0000000..919c815 --- /dev/null +++ b/SOURCES/0051-Superfluous-block-lets-merge-into-one.patch @@ -0,0 +1,28 @@ +From 823b947a6c3b526f4a8a4773371ab22c140c366c Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 12 Jun 2015 19:48:37 +0530 +Subject: [PATCH 051/398] Superfluous block; lets merge into one + +Change-Id: I2f49394c53deece8e86a7f290250c4f52918c5d8 +(cherry picked from commit 23ca7d8a81df74d7195d2d8916f77c6305fc8a94) +--- + libreofficekit/Module_libreofficekit.mk | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/libreofficekit/Module_libreofficekit.mk b/libreofficekit/Module_libreofficekit.mk +index 217ecb22ff33..0b2fd4ae103d 100644 +--- a/libreofficekit/Module_libreofficekit.mk ++++ b/libreofficekit/Module_libreofficekit.mk +@@ -19,9 +19,6 @@ ifneq ($(ENABLE_GTK3),) + $(eval $(call gb_Module_add_targets,libreofficekit,\ + Library_libreofficekitgtk \ + Executable_gtktiledviewer \ +-)) +- +-$(eval $(call gb_Module_add_targets,libreofficekit,\ + Executable_tilebench \ + )) + endif # ($(ENABLE_GTK3),) +-- +2.12.0 + diff --git a/SOURCES/0052-lokdocview-couple-for-missing-static_cast-GParamFlag.patch b/SOURCES/0052-lokdocview-couple-for-missing-static_cast-GParamFlag.patch new file mode 100644 index 0000000..637d839 --- /dev/null +++ b/SOURCES/0052-lokdocview-couple-for-missing-static_cast-GParamFlag.patch @@ -0,0 +1,75 @@ +From c59de3973a3910b949528806dab6756f7ed92199 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 16 Jun 2015 11:34:36 +0200 +Subject: [PATCH 052/398] lokdocview: couple for missing + static_cast() + +Change-Id: I038c05c0d081f52e4ac90688f73397565413632d +(cherry picked from commit 9dcd2d119ab67bde9de588c42db3805525d5f06a) +--- + libreofficekit/source/gtk/lokdocview.cxx | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 7031be9b6536..20b1aa6b837e 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -519,10 +519,7 @@ callback (gpointer pData) + break; + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + { +- g_info ("%d %d", priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); +- g_info ("startin"); + payloadToSize(pCallback->m_aPayload.c_str(), priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); +- g_info ("%d %d", priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom), + twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom)); +@@ -1156,7 +1153,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Document Path", + "The URI of the document to open", + 0, +- G_PARAM_READWRITE)); ++ static_cast(G_PARAM_READWRITE))); + + /** + * LOKDocView:editable: +@@ -1169,7 +1166,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Editable", + "Whether the content is in edit mode or not", + FALSE, +- G_PARAM_READWRITE)); ++ static_cast(G_PARAM_READWRITE))); + + /** + * LOKDocView:load-progress: +@@ -1214,7 +1211,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Is Loading", + "Whether the view is loading a document", + FALSE, +- G_PARAM_READABLE)); ++ static_cast(G_PARAM_READABLE))); + + /** + * LOKDocView:doc-width: +@@ -1227,7 +1224,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Document Width", + "Width of the document in twips", + 0, G_MAXLONG, 0, +- G_PARAM_READWRITE)); ++ static_cast(G_PARAM_READWRITE))); + + /** + * LOKDocView:doc-height: +@@ -1240,7 +1237,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Document Height", + "Height of the document in twips", + 0, G_MAXLONG, 0, +- G_PARAM_READWRITE)); ++ static_cast(G_PARAM_READWRITE))); + + /** + * LOKDocView:can-zoom-in: +-- +2.12.0 + diff --git a/SOURCES/0053-gtktiledviewer-add-copy-button.patch b/SOURCES/0053-gtktiledviewer-add-copy-button.patch new file mode 100644 index 0000000..a7b4469 --- /dev/null +++ b/SOURCES/0053-gtktiledviewer-add-copy-button.patch @@ -0,0 +1,53 @@ +From 82c4891ec0e285b1cdf767dea54b877a16177374 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 18 Jun 2015 09:18:18 +0200 +Subject: [PATCH 053/398] gtktiledviewer: add copy button + +Change-Id: I56ed5047da118eac01d7dea150597133215278e2 +(cherry picked from commit 437210d58f32177ef1829d704f7f4d2f1bbfbfdd) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 8b006797c226..9496ba5ea180 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -125,6 +125,19 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + } + } + ++/// Handler for the copy button: write clipboard. ++static void doCopy(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++{ ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); ++ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); ++ char* pSelection = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8"); ++ ++ GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(pDocView), GDK_SELECTION_CLIPBOARD); ++ gtk_clipboard_set_text(pClipboard, pSelection, -1); ++ ++ free(pSelection); ++} ++ + /// Get the visible area of the scrolled window + static void getVisibleAreaTwips(GdkRectangle* pArea) + { +@@ -394,6 +407,14 @@ int main( int argc, char* argv[] ) + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1 ); + + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); ++ ++ // Cut, copy & paste. ++ GtkToolItem* pCopyButton = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pCopyButton), "edit-copy-symbolic"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pCopyButton, -1); ++ g_signal_connect(G_OBJECT(pCopyButton), "clicked", G_CALLBACK(doCopy), NULL); ++ gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); ++ + pEnableEditing = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pEnableEditing), "insert-text-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pEnableEditing, -1); +-- +2.12.0 + diff --git a/SOURCES/0054-gtktiledviewer-do-HTML-copying-if-possible.patch b/SOURCES/0054-gtktiledviewer-do-HTML-copying-if-possible.patch new file mode 100644 index 0000000..e33fc03 --- /dev/null +++ b/SOURCES/0054-gtktiledviewer-do-HTML-copying-if-possible.patch @@ -0,0 +1,71 @@ +From 25bb8e0fa54097cc0197e5883b0b95b648d75452 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 22 Jun 2015 09:06:31 +0200 +Subject: [PATCH 054/398] gtktiledviewer: do HTML copying if possible + +(cherry picked from commit f403cecdaedf263f11081c91bed62640362a3a3e) + +Change-Id: I24e7b18442cb08814a73dd33b368b368039a11e4 +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 38 ++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 9496ba5ea180..57556616d803 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -125,15 +125,49 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + } + } + ++/// Our GtkClipboardGetFunc implementation for HTML. ++static void htmlGetFunc(GtkClipboard* /*pClipboard*/, GtkSelectionData* pSelectionData, guint /*info*/, gpointer pUserData) ++{ ++ GdkAtom aAtom(gdk_atom_intern("text/html", false)); ++ const gchar* pSelection = static_cast(pUserData); ++ gtk_selection_data_set(pSelectionData, aAtom, 8, reinterpret_cast(pSelection), strlen(pSelection)); ++} ++ ++/// Our GtkClipboardClearFunc implementation for HTML. ++static void htmlClearFunc(GtkClipboard* /*pClipboard*/, gpointer pData) ++{ ++ g_free(pData); ++} ++ ++/// Same as gtk_clipboard_set_text(), but sets HTML. ++static void clipboardSetHtml(GtkClipboard* pClipboard, const char* pSelection) ++{ ++ GtkTargetList* pList = gtk_target_list_new(0, 0); ++ GdkAtom aAtom(gdk_atom_intern("text/html", false)); ++ gtk_target_list_add(pList, aAtom, 0, 0); ++ gint nTargets = 0; ++ GtkTargetEntry* pTargets = gtk_target_table_new_from_list(pList, &nTargets); ++ ++ gtk_clipboard_set_with_data(pClipboard, pTargets, nTargets, htmlGetFunc, htmlClearFunc, g_strdup(pSelection)); ++ ++ gtk_target_table_free(pTargets, nTargets); ++ gtk_target_list_unref(pList); ++} ++ + /// Handler for the copy button: write clipboard. + static void doCopy(GtkWidget* /*pButton*/, gpointer /*pItem*/) + { + LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); +- char* pSelection = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8"); ++ char* pUsedFormat = 0; ++ char* pSelection = pDocument->pClass->getTextSelection(pDocument, "text/html", &pUsedFormat); + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(pDocView), GDK_SELECTION_CLIPBOARD); +- gtk_clipboard_set_text(pClipboard, pSelection, -1); ++ std::string aUsedFormat(pUsedFormat); ++ if (aUsedFormat == "text/plain;charset=utf-8") ++ gtk_clipboard_set_text(pClipboard, pSelection, -1); ++ else ++ clipboardSetHtml(pClipboard, pSelection); + + free(pSelection); + } +-- +2.12.0 + diff --git a/SOURCES/0055-lokdocview-Use-GInitable.patch b/SOURCES/0055-lokdocview-Use-GInitable.patch new file mode 100644 index 0000000..4643bb3 --- /dev/null +++ b/SOURCES/0055-lokdocview-Use-GInitable.patch @@ -0,0 +1,166 @@ +From 9a1d485f937bf92ae860078b94a5372b3a4ce718 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 18 Jun 2015 21:52:22 +0530 +Subject: [PATCH 055/398] lokdocview: Use GInitable + +The construction of LokDocView widget can fail because it +involves initializing the lok context via lok_init. + +Having lok_init calls in constructed virtual method is a bad idea +since it assumes that construction will never fail. So, implement +GInitable for this class, and move the object initialization from +constructed to initable. + +Change-Id: Idf18a054cf8ef2e946392458ec52cb0107bd7454 +(cherry picked from commit a2aaf911e2e7b63af920186acb2a5e03bc58bd54) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 6 ++- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 2 +- + libreofficekit/source/gtk/lokdocview.cxx | 49 +++++++++++++++------- + 3 files changed, 39 insertions(+), 18 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 7048dbefc0a1..3eaf28352a11 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -42,10 +42,12 @@ struct _LOKDocViewClass + + GType lok_doc_view_get_type (void) G_GNUC_CONST; + +-GtkWidget* lok_doc_view_new (const char* pPath); ++GtkWidget* lok_doc_view_new (const gchar* pPath, ++ GCancellable *cancellable, ++ GError **error); + + gboolean lok_doc_view_open_document (LOKDocView* pDocView, +- char* pPath); ++ const gchar* pPath); + + /// Gets the document the viewer displays. + LibreOfficeKitDocument* lok_doc_view_get_document (LOKDocView* pDocView); +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 57556616d803..fedd6c9fdf13 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -520,7 +520,7 @@ int main( int argc, char* argv[] ) + gtk_box_pack_end(GTK_BOX(pVBox), pFindbar, FALSE, FALSE, 0); + + // Docview +- pDocView = lok_doc_view_new(argv[1]); ++ pDocView = lok_doc_view_new (argv[1], NULL, NULL); + if (pDocView == NULL) + g_error ("Error while creating LOKDocView widget"); + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 20b1aa6b837e..144f17efba94 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -137,12 +137,16 @@ enum + + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + ++static void lok_doc_view_initable_iface_init (GInitableIface *iface); ++ + SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-function" + #endif +-G_DEFINE_TYPE_WITH_PRIVATE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA) ++G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA, ++ G_ADD_PRIVATE (LOKDocView) ++ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, lok_doc_view_initable_iface_init)); + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif +@@ -1103,14 +1107,30 @@ static void lok_doc_view_finalize (GObject* object) + G_OBJECT_CLASS (lok_doc_view_parent_class)->finalize (object); + } + +-static void lok_doc_view_constructed (GObject* object) ++static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* /*cancellable*/, GError **error) + { +- LOKDocView* pDocView = LOK_DOC_VIEW (object); +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocView *pDocView = LOK_DOC_VIEW (initable); ++ ++ if (pDocView->priv->m_pOffice != NULL) ++ return TRUE; ++ ++ pDocView->priv->m_pOffice = lok_init (pDocView->priv->m_aLOPath); ++ ++ if (pDocView->priv->m_pOffice == NULL) ++ { ++ g_set_error (error, ++ g_quark_from_static_string ("LOK initialization error"), 0, ++ "Failed to get LibreOfficeKit context. Make sure path (%s) is correct", ++ pDocView->priv->m_aLOPath); ++ return FALSE; ++ } + +- G_OBJECT_CLASS (lok_doc_view_parent_class)->constructed (object); ++ return TRUE; ++} + +- pDocView->priv->m_pOffice = lok_init (priv->m_aLOPath); ++static void lok_doc_view_initable_iface_init (GInitableIface *iface) ++{ ++ iface->init = lok_doc_view_initable_init; + } + + static void lok_doc_view_class_init (LOKDocViewClass* pClass) +@@ -1121,7 +1141,6 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + pGObjectClass->get_property = lok_doc_view_get_property; + pGObjectClass->set_property = lok_doc_view_set_property; + pGObjectClass->finalize = lok_doc_view_finalize; +- pGObjectClass->constructed = lok_doc_view_constructed; + + pWidgetClass->draw = lok_doc_view_draw; + pWidgetClass->button_press_event = lok_doc_view_signal_button; +@@ -1343,18 +1362,19 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_STRING); + } + +- +- + /** + * lok_doc_view_new: + * @pPath: LibreOffice install path. ++ * @cancellable: The cancellable object that you can use to cancel this ++ * operation. ++ * @error: The error that will be set if the object fails to initialize. + * +- * Returns: The #LOKDocView widget instance. ++ * Returns: (transfer none): The #LOKDocView widget instance. + */ + SAL_DLLPUBLIC_EXPORT GtkWidget* +-lok_doc_view_new (const char* pPath) ++lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + { +- return GTK_WIDGET (g_object_new(LOK_TYPE_DOC_VIEW, "lopath", pPath, NULL)); ++ return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath, NULL)); + } + + /** +@@ -1365,7 +1385,7 @@ lok_doc_view_new (const char* pPath) + * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise + */ + SAL_DLLPUBLIC_EXPORT gboolean +-lok_doc_view_open_document (LOKDocView* pDocView, char* pPath) ++lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath) + { + if ( pDocView->priv->m_pDocument ) + { +@@ -1374,8 +1394,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, char* pPath) + } + + pDocView->priv->m_pOffice->pClass->registerCallback(pDocView->priv->m_pOffice, globalCallbackWorker, pDocView); +- pDocView->priv->m_pDocument = pDocView->priv->m_pOffice->pClass->documentLoad( pDocView->priv->m_pOffice, +- pPath ); ++ pDocView->priv->m_pDocument = pDocView->priv->m_pOffice->pClass->documentLoad( pDocView->priv->m_pOffice, pPath ); + if ( !pDocView->priv->m_pDocument ) + { + // FIXME: should have a GError parameter and populate it. +-- +2.12.0 + diff --git a/SOURCES/0056-lokdocview-Use-get_instance_private-to-get-private-s.patch b/SOURCES/0056-lokdocview-Use-get_instance_private-to-get-private-s.patch new file mode 100644 index 0000000..30870cd --- /dev/null +++ b/SOURCES/0056-lokdocview-Use-get_instance_private-to-get-private-s.patch @@ -0,0 +1,400 @@ +From c4715537a91d397e73721b2c63ac4c51e21415a4 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 19 Jun 2015 01:06:50 +0530 +Subject: [PATCH 056/398] lokdocview: Use *get_instance_private () to get + private structure + +Let lok_doc_view_get_instance_private () do the pointer +arithmatic. Additionally, we are saving sizeof (void*) already in +the _LOKDocView struct with this approach. + +Change-Id: I6d991d5834ef15dad24acb14a1d4bbf7d03df762 +(cherry picked from commit cf14391bc25e977bf70870004d8df79926a99e0c) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 1 - + libreofficekit/source/gtk/lokdocview.cxx | 129 ++++++++++++++++------------- + 2 files changed, 73 insertions(+), 57 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 3eaf28352a11..3a1628b60e86 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -32,7 +32,6 @@ typedef struct _LOKDocViewPrivate LOKDocViewPrivate; + struct _LOKDocView + { + GtkDrawingArea aDrawingArea; +- LOKDocViewPrivate* priv; + }; + + struct _LOKDocViewClass +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 144f17efba94..916c9f7cf60c 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -229,7 +229,7 @@ isEmptyRectangle(const GdkRectangle& rRectangle) + static void + signalKey (LOKDocView* pDocView, const GdkEvent* pEvent) + { +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + int nCharCode = 0; + int nKeyCode = 0; + guint keyval; +@@ -292,7 +292,7 @@ static gboolean + handleTimeout (gpointer pData) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pData); +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + if (priv->m_bEdit) + { +@@ -366,7 +366,7 @@ globalCallbackWorker(int nType, const char* pPayload, void* pData) + static GdkRectangle + payloadToRectangle (LOKDocView* pDocView, const char* pPayload) + { +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GdkRectangle aRet; + gchar** ppCoordinates = g_strsplit(pPayload, ", ", 4); + gchar** ppCoordinate = ppCoordinates; +@@ -418,7 +418,7 @@ payloadToRectangles(LOKDocView* pDocView, const char* pPayload) + static void + setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + { +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GdkRectangle aRectanglePixels; + GdkPoint aStart, aEnd; + +@@ -442,7 +442,7 @@ callback (gpointer pData) + { + CallbackData* pCallback = static_cast(pData); + LOKDocView* pDocView = LOK_DOC_VIEW (pCallback->m_pDocView); +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + switch (pCallback->m_nType) + { +@@ -560,7 +560,7 @@ renderHandle(LOKDocView* pDocView, + cairo_surface_t* pHandle, + GdkRectangle& rRectangle) + { +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GdkPoint aCursorBottom; + int nHandleWidth, nHandleHeight; + double fHandleScale; +@@ -593,7 +593,7 @@ renderGraphicHandle(LOKDocView* pDocView, + const GdkRectangle& rSelection, + cairo_surface_t* pHandle) + { +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + int nHandleWidth, nHandleHeight; + GdkRectangle aSelection; + +@@ -660,7 +660,7 @@ renderGraphicHandle(LOKDocView* pDocView, + static gboolean + renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + { +- LOKDocViewPrivate *priv = pDocView->priv; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GdkRectangle aVisibleArea; + long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom); + long nDocumentHeightPixels = twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom); +@@ -721,7 +721,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + static gboolean + renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + { +- LOKDocViewPrivate *priv = pDocView->priv; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + if (priv->m_bEdit && priv->m_bCursorVisible && priv->m_bCursorOverlayVisible && !isEmptyRectangle(priv->m_aVisibleCursor)) + { +@@ -799,7 +799,7 @@ static gboolean + lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); +- LOKDocViewPrivate *priv = pDocView->priv; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", + (int)pEvent->x, (int)pEvent->y, +@@ -942,7 +942,7 @@ static gboolean + lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); +- LOKDocViewPrivate *priv = pDocView->priv; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GdkPoint aPoint; + + if (priv->m_bInDragMiddleHandle) +@@ -1001,8 +1001,8 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + + static void lok_doc_view_init (LOKDocView* pDocView) + { +- pDocView->priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- pDocView->priv->m_bCursorVisible = true; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_bCursorVisible = true; + + gtk_widget_add_events(GTK_WIDGET(pDocView), + GDK_BUTTON_PRESS_MASK +@@ -1015,7 +1015,7 @@ static void lok_doc_view_init (LOKDocView* pDocView) + static void lok_doc_view_set_property (GObject* object, guint propId, const GValue *value, GParamSpec *pspec) + { + LOKDocView* pDocView = LOK_DOC_VIEW (object); +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + switch (propId) + { +@@ -1045,7 +1045,7 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal + static void lok_doc_view_get_property (GObject* object, guint propId, GValue *value, GParamSpec *pspec) + { + LOKDocView* pDocView = LOK_DOC_VIEW (object); +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + switch (propId) + { +@@ -1097,7 +1097,7 @@ static gboolean lok_doc_view_draw (GtkWidget* pWidget, cairo_t* pCairo) + static void lok_doc_view_finalize (GObject* object) + { + LOKDocView* pDocView = LOK_DOC_VIEW (object); +- LOKDocViewPrivate* priv = pDocView->priv; ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + if (priv->m_pDocument) + priv->m_pDocument->pClass->destroy (priv->m_pDocument); +@@ -1110,18 +1110,19 @@ static void lok_doc_view_finalize (GObject* object) + static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* /*cancellable*/, GError **error) + { + LOKDocView *pDocView = LOK_DOC_VIEW (initable); ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + +- if (pDocView->priv->m_pOffice != NULL) ++ if (priv->m_pOffice != NULL) + return TRUE; + +- pDocView->priv->m_pOffice = lok_init (pDocView->priv->m_aLOPath); ++ priv->m_pOffice = lok_init (priv->m_aLOPath); + +- if (pDocView->priv->m_pOffice == NULL) ++ if (priv->m_pOffice == NULL) + { + g_set_error (error, + g_quark_from_static_string ("LOK initialization error"), 0, + "Failed to get LibreOfficeKit context. Make sure path (%s) is correct", +- pDocView->priv->m_aLOPath); ++ priv->m_aLOPath); + return FALSE; + } + +@@ -1387,39 +1388,41 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + SAL_DLLPUBLIC_EXPORT gboolean + lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath) + { +- if ( pDocView->priv->m_pDocument ) ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ ++ if ( priv->m_pDocument ) + { +- pDocView->priv->m_pDocument->pClass->destroy( pDocView->priv->m_pDocument ); +- pDocView->priv->m_pDocument = 0; ++ priv->m_pDocument->pClass->destroy( priv->m_pDocument ); ++ priv->m_pDocument = 0; + } + +- pDocView->priv->m_pOffice->pClass->registerCallback(pDocView->priv->m_pOffice, globalCallbackWorker, pDocView); +- pDocView->priv->m_pDocument = pDocView->priv->m_pOffice->pClass->documentLoad( pDocView->priv->m_pOffice, pPath ); +- if ( !pDocView->priv->m_pDocument ) ++ priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView); ++ priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, pPath ); ++ if ( !priv->m_pDocument ) + { + // FIXME: should have a GError parameter and populate it. +- char *pError = pDocView->priv->m_pOffice->pClass->getError( pDocView->priv->m_pOffice ); ++ char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice ); + fprintf( stderr, "Error opening document '%s'\n", pError ); + return FALSE; + } + else + { +- pDocView->priv->m_pDocument->pClass->initializeForRendering(pDocView->priv->m_pDocument); +- pDocView->priv->m_pDocument->pClass->registerCallback(pDocView->priv->m_pDocument, callbackWorker, pDocView); +- pDocView->priv->m_pDocument->pClass->getDocumentSize(pDocView->priv->m_pDocument, &pDocView->priv->m_nDocumentWidthTwips, &pDocView->priv->m_nDocumentHeightTwips); ++ priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); ++ priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pDocView); ++ priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); + g_timeout_add(600, handleTimeout, pDocView); + +- float zoom = pDocView->priv->m_fZoom; +- long nDocumentWidthTwips = pDocView->priv->m_nDocumentWidthTwips; +- long nDocumentHeightTwips = pDocView->priv->m_nDocumentHeightTwips; ++ float zoom = priv->m_fZoom; ++ long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; ++ long nDocumentHeightTwips = priv->m_nDocumentHeightTwips; + long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); + long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); + // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + + +- pDocView->priv->m_aTileBuffer = TileBuffer(pDocView->priv->m_pDocument, +- nColumns); ++ priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, ++ nColumns); + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +@@ -1436,7 +1439,8 @@ lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath) + SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* + lok_doc_view_get_document (LOKDocView* pDocView) + { +- return pDocView->priv->m_pDocument; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return priv->m_pDocument; + } + + /** +@@ -1449,14 +1453,16 @@ lok_doc_view_get_document (LOKDocView* pDocView) + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + { +- pDocView->priv->m_fZoom = fZoom; +- long nDocumentWidthPixels = twipToPixel(pDocView->priv->m_nDocumentWidthTwips, fZoom); +- long nDocumentHeightPixels = twipToPixel(pDocView->priv->m_nDocumentHeightTwips, fZoom); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ ++ priv->m_fZoom = fZoom; ++ long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, fZoom); ++ long nDocumentHeightPixels = twipToPixel(priv->m_nDocumentHeightTwips, fZoom); + // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- pDocView->priv->m_aTileBuffer = TileBuffer(pDocView->priv->m_pDocument, +- nColumns); ++ priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, ++ nColumns); + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +@@ -1471,38 +1477,44 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_get_zoom (LOKDocView* pDocView) + { +- return pDocView->priv->m_fZoom; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return priv->m_fZoom; + } + + SAL_DLLPUBLIC_EXPORT int + lok_doc_view_get_parts (LOKDocView* pDocView) + { +- return pDocView->priv->m_pDocument->pClass->getParts( pDocView->priv->m_pDocument ); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return priv->m_pDocument->pClass->getParts( priv->m_pDocument ); + } + + SAL_DLLPUBLIC_EXPORT int + lok_doc_view_get_part (LOKDocView* pDocView) + { +- return pDocView->priv->m_pDocument->pClass->getPart( pDocView->priv->m_pDocument ); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return priv->m_pDocument->pClass->getPart( priv->m_pDocument ); + } + + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + { +- pDocView->priv->m_pDocument->pClass->setPart( pDocView->priv->m_pDocument, nPart ); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart ); + } + + SAL_DLLPUBLIC_EXPORT char* + lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart) + { +- return pDocView->priv->m_pDocument->pClass->getPartName( pDocView->priv->m_pDocument, nPart ); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return priv->m_pDocument->pClass->getPartName( priv->m_pDocument, nPart ); + } + + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_partmode(LOKDocView* pDocView, + int nPartMode) + { +- pDocView->priv->m_pDocument->pClass->setPartMode( pDocView->priv->m_pDocument, nPartMode ); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode ); + } + + /** +@@ -1516,16 +1528,17 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_edit(LOKDocView* pDocView, + gboolean bEdit) + { +- gboolean bWasEdit = pDocView->priv->m_bEdit; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ gboolean bWasEdit = priv->m_bEdit; + +- if (!pDocView->priv->m_bEdit && bEdit) ++ if (!priv->m_bEdit && bEdit) + g_info("lok_doc_view_set_edit: entering edit mode"); +- else if (pDocView->priv->m_bEdit && !bEdit) ++ else if (priv->m_bEdit && !bEdit) + { + g_info("lok_doc_view_set_edit: leaving edit mode"); +- pDocView->priv->m_pDocument->pClass->resetSelection(pDocView->priv->m_pDocument); ++ priv->m_pDocument->pClass->resetSelection(priv->m_pDocument); + } +- pDocView->priv->m_bEdit = bEdit; ++ priv->m_bEdit = bEdit; + g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit); + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } +@@ -1539,7 +1552,8 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + SAL_DLLPUBLIC_EXPORT gboolean + lok_doc_view_get_edit (LOKDocView* pDocView) + { +- return pDocView->priv->m_bEdit; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return priv->m_bEdit; + } + + /** +@@ -1555,7 +1569,8 @@ lok_doc_view_post_command (LOKDocView* pDocView, + const char* pCommand, + const char* pArguments) + { +- pDocView->priv->m_pDocument->pClass->postUnoCommand(pDocView->priv->m_pDocument, pCommand, pArguments); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pCommand, pArguments); + } + + /** +@@ -1583,7 +1598,8 @@ lok_doc_view_post_key (LOKDocView* pDocView, GdkEvent* pEvent) + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + { +- return pixelToTwip(fInput, pDocView->priv->m_fZoom); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return pixelToTwip(fInput, priv->m_fZoom); + } + + /** +@@ -1598,7 +1614,8 @@ lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_twip_to_pixel (LOKDocView* pDocView, float fInput) + { +- return twipToPixel(fInput, pDocView->priv->m_fZoom); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ return twipToPixel(fInput, priv->m_fZoom); + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0057-lokdocview-fixed-a-signal-name.patch b/SOURCES/0057-lokdocview-fixed-a-signal-name.patch new file mode 100644 index 0000000..94d15f1 --- /dev/null +++ b/SOURCES/0057-lokdocview-fixed-a-signal-name.patch @@ -0,0 +1,27 @@ +From fb96b28af8e78142da959781d17acb508e151ef2 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 22 Jun 2015 15:27:24 +0530 +Subject: [PATCH 057/398] lokdocview: fixed a signal name + +Change-Id: I645516d43562dfa03c27e2bea366e9a161829bfe +(cherry picked from commit e608a754b0ab14d3c5ec21237d163218d0be3e09) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 916c9f7cf60c..0641197d9781 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1352,7 +1352,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * @pDocView: the #LOKDocView on which the signal is emitted + * @aHyperlink: the URI which the application should handle + */ +- doc_view_signals[PART_CHANGED] = ++ doc_view_signals[HYPERLINK_CLICKED] = + g_signal_new("hyperlinked-clicked", + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, +-- +2.12.0 + diff --git a/SOURCES/0058-cppcheck-noExplicitConstructor.patch b/SOURCES/0058-cppcheck-noExplicitConstructor.patch new file mode 100644 index 0000000..d1dcda7 --- /dev/null +++ b/SOURCES/0058-cppcheck-noExplicitConstructor.patch @@ -0,0 +1,28 @@ +From 933887a5b1c5d9c07d76ab8af16bac317b02d579 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Wed, 24 Jun 2015 17:35:37 +0100 +Subject: [PATCH 058/398] cppcheck: noExplicitConstructor + +(cherry picked from commit df5ec49bcaa57aa0a137db45d7c0766733f7e508) + +Change-Id: I80cd2975f17bb7fa57fa669873ef1dd8f3595a11 +--- + desktop/source/lib/init.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 39a1fbffc533..aa8e27c7f48f 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -239,7 +239,7 @@ struct LibLODocument_Impl : public _LibreOfficeKitDocument + uno::Reference mxComponent; + shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; + +- LibLODocument_Impl(const uno::Reference &xComponent) : ++ explicit LibLODocument_Impl(const uno::Reference &xComponent) : + mxComponent( xComponent ) + { + if (!(m_pDocumentClass = gDocumentClass.lock())) +-- +2.12.0 + diff --git a/SOURCES/0059-lokdocview-Don-t-handle-hyperlink-clicks.patch b/SOURCES/0059-lokdocview-Don-t-handle-hyperlink-clicks.patch new file mode 100644 index 0000000..2c22885 --- /dev/null +++ b/SOURCES/0059-lokdocview-Don-t-handle-hyperlink-clicks.patch @@ -0,0 +1,87 @@ +From c2db3c262f702e62c2f247e62b1b313ecc6e28c5 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 23 Jun 2015 01:52:44 +0530 +Subject: [PATCH 059/398] lokdocview: Don't handle hyperlink clicks + +Instead emit the signal 'hyperlink-clicked', and let the +application decide how it wants to handle the hyperlink clicks. + +(cherry picked from commit 9d2fa921470152647cc3b54355f70a1365f752ff) + +Change-Id: Ief72bbd16727e140cacf28b852ad43952c02f7ae +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 14 +++++++++++++- + libreofficekit/source/gtk/lokdocview.cxx | 11 ++++++++--- + 2 files changed, 21 insertions(+), 4 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index fedd6c9fdf13..61f016dffab8 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -310,7 +310,18 @@ static void signalPart(LOKDocView* /*pLOKDocView*/, int nPart, gpointer /*pData* + g_bPartSelectorBroadcast = true; + } + +-/// User clicked on a cmmand button -> inform LOKDocView. ++/// User clicked on a command button -> inform LOKDocView. ++static void signalHyperlink(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer /*pData*/) ++{ ++ GError* pError = NULL; ++ gtk_show_uri(NULL, pPayload, GDK_CURRENT_TIME, &pError); ++ if (pError != NULL) ++ { ++ g_warning("Unable to show URI %s : %s", pPayload, pError->message); ++ g_error_free(pError); ++ } ++} ++ + static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + { + if (g_bToolItemBroadcast) +@@ -527,6 +538,7 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); + g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); ++ g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); + + // Input handling. + g_signal_connect(pWindow, "key-press-event", G_CALLBACK(signalKey), pDocView); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 0641197d9781..19da4b2da691 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -324,6 +324,12 @@ setPart(LOKDocView* pDocView, const std::string& rString) + g_signal_emit(pDocView, doc_view_signals[PART_CHANGED], 0, std::stoi(rString)); + } + ++static void ++hyperlinkClicked(LOKDocView* pDocView, const std::string& rString) ++{ ++ g_signal_emit(pDocView, doc_view_signals[HYPERLINK_CLICKED], 0, rString.c_str()); ++} ++ + /// Implementation of the global callback handler, invoked by globalCallback(); + static gboolean + globalCallback (gpointer pData) +@@ -507,8 +513,7 @@ callback (gpointer pData) + break; + case LOK_CALLBACK_HYPERLINK_CLICKED: + { +- GError* pError = NULL; +- gtk_show_uri(NULL, pCallback->m_aPayload.c_str(), GDK_CURRENT_TIME, &pError); ++ hyperlinkClicked(pDocView, pCallback->m_aPayload); + } + break; + case LOK_CALLBACK_STATE_CHANGED: +@@ -1353,7 +1358,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * @aHyperlink: the URI which the application should handle + */ + doc_view_signals[HYPERLINK_CLICKED] = +- g_signal_new("hyperlinked-clicked", ++ g_signal_new("hyperlink-clicked", + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +-- +2.12.0 + diff --git a/SOURCES/0060-lokdocview-Remove-superfluous-_post_key.patch b/SOURCES/0060-lokdocview-Remove-superfluous-_post_key.patch new file mode 100644 index 0000000..5588b8f --- /dev/null +++ b/SOURCES/0060-lokdocview-Remove-superfluous-_post_key.patch @@ -0,0 +1,181 @@ +From 061935437f10f6e35d0b0561a5465f4872a8c909 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 23 Jun 2015 02:58:38 +0530 +Subject: [PATCH 060/398] lokdocview: Remove superfluous *_post_key() + +Instead directly let LOKDocView handle the input. + +Change-Id: I260a460df23c3e2e5c78d8b363bb864ae5c63dab +(cherry picked from commit da49b8339828c0ee27d999ac4201e0eb12a1a47f) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 4 --- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 22 +++--------- + libreofficekit/source/gtk/lokdocview.cxx | 40 ++++++++-------------- + 3 files changed, 20 insertions(+), 46 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 3a1628b60e86..962f9d9265bb 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -74,10 +74,6 @@ void lok_doc_view_post_command (LOKDocView* + const char* pCommand, + const char* pArguments); + +-/// Posts a keyboard event to LibreOfficeKit. +-void lok_doc_view_post_key (LOKDocView* pDocView, +- GdkEvent* pEvent); +- + float lok_doc_view_pixel_to_twip (LOKDocView* pDocView, + float fInput); + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 61f016dffab8..7510ca53a928 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -190,19 +190,6 @@ static void getVisibleAreaTwips(GdkRectangle* pArea) + #endif + } + +- +-/// Handles the key-press-event of the window. +-static gboolean signalKey(GtkWidget* /*pWidget*/, GdkEvent* pEvent, gpointer/* pData*/) +-{ +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); +- if (!gtk_widget_get_visible(pFindbar) && bool(lok_doc_view_get_edit(pLOKDocView))) +- { +- lok_doc_view_post_key(pLOKDocView, pEvent); +- return TRUE; +- } +- return FALSE; +-} +- + /// Searches for the next or previous text of pFindbarEntry. + static void doSearch(bool bBackwards) + { +@@ -540,10 +527,6 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); + +- // Input handling. +- g_signal_connect(pWindow, "key-press-event", G_CALLBACK(signalKey), pDocView); +- g_signal_connect(pWindow, "key-release-event", G_CALLBACK(signalKey), pDocView); +- + // Scrolled window for DocView + pScrolledWindow = gtk_scrolled_window_new(0, 0); + gtk_widget_set_hexpand (pScrolledWindow, TRUE); +@@ -567,6 +550,11 @@ int main( int argc, char* argv[] ) + g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0); + g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0); + ++ // Make only LOKDocView widget as focussable ++ GList *focusChain = NULL; ++ focusChain = g_list_append( focusChain, pDocView ); ++ gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain ); ++ + gtk_main(); + + return 0; +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 19da4b2da691..368a8d536887 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -226,24 +226,21 @@ isEmptyRectangle(const GdkRectangle& rRectangle) + return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0; + } + +-static void +-signalKey (LOKDocView* pDocView, const GdkEvent* pEvent) ++static gboolean ++signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + { ++ LOKDocView* pDocView = LOK_DOC_VIEW(pWidget); + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + int nCharCode = 0; + int nKeyCode = 0; +- guint keyval; +- GdkModifierType state; +- gdk_event_get_keyval (pEvent, &keyval); +- gdk_event_get_state (pEvent, &state); + + if (!priv->m_bEdit) + { + g_info("signalKey: not in edit mode, ignore"); +- return; ++ return FALSE; + } + +- switch (keyval) ++ switch (pEvent->keyval) + { + case GDK_KEY_BackSpace: + nKeyCode = com::sun::star::awt::Key::BACKSPACE; +@@ -270,22 +267,24 @@ signalKey (LOKDocView* pDocView, const GdkEvent* pEvent) + nKeyCode = com::sun::star::awt::Key::RIGHT; + break; + default: +- if (keyval >= GDK_KEY_F1 && keyval <= GDK_KEY_F26) +- nKeyCode = com::sun::star::awt::Key::F1 + (keyval - GDK_KEY_F1); ++ if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26) ++ nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_KEY_F1); + else +- nCharCode = gdk_keyval_to_unicode(keyval); ++ nCharCode = gdk_keyval_to_unicode(pEvent->keyval); + } + + // rsc is not public API, but should be good enough for debugging purposes. + // If this is needed for real, then probably a new param of type + // css::awt::KeyModifier is needed in postKeyEvent(). +- if (state & GDK_SHIFT_MASK) ++ if (pEvent->state & GDK_SHIFT_MASK) + nKeyCode |= KEY_SHIFT; + + if (pEvent->type == GDK_KEY_RELEASE) + priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode); + else + priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode); ++ ++ return FALSE; + } + + static gboolean +@@ -1151,6 +1150,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + pWidgetClass->draw = lok_doc_view_draw; + pWidgetClass->button_press_event = lok_doc_view_signal_button; + pWidgetClass->button_release_event = lok_doc_view_signal_button; ++ pWidgetClass->key_press_event = signalKey; ++ pWidgetClass->key_release_event = signalKey; + pWidgetClass->motion_notify_event = lok_doc_view_signal_motion; + + /** +@@ -1431,6 +1432,8 @@ lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath) + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); ++ gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE); ++ gtk_widget_grab_focus(GTK_WIDGET(pDocView)); + } + return TRUE; + } +@@ -1579,19 +1582,6 @@ lok_doc_view_post_command (LOKDocView* pDocView, + } + + /** +- * lok_doc_view_post_key: +- * @pDocView: the #LOKDocView instance +- * @pEvent: the #GdkEventKey containing information about the event +- * +- * This methods forwards your key events to the LO core. +-*/ +-SAL_DLLPUBLIC_EXPORT void +-lok_doc_view_post_key (LOKDocView* pDocView, GdkEvent* pEvent) +-{ +- signalKey(pDocView, pEvent); +-} +- +-/** + * lok_doc_view_pixel_to_twip: + * @pDocView: The #LOKDocView instance + * @fInput: The value in pixels to convert to twips +-- +2.12.0 + diff --git a/SOURCES/0061-tilebuffer-Add-timer-to-measure-paintTile-call.patch b/SOURCES/0061-tilebuffer-Add-timer-to-measure-paintTile-call.patch new file mode 100644 index 0000000..f870060 --- /dev/null +++ b/SOURCES/0061-tilebuffer-Add-timer-to-measure-paintTile-call.patch @@ -0,0 +1,37 @@ +From 46584ff3db62f69d7f93a2ddb90f444419f49e3e Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 23 Jun 2015 14:37:09 +0530 +Subject: [PATCH 061/398] tilebuffer: Add timer to measure paintTile() call + +Change-Id: I2645863c7445e17d77e2c4e2dc24e22f8685034e +(cherry picked from commit 580c70883ca8c9bc73ea42cb05983b9df57f55ff) +--- + libreofficekit/source/gtk/tilebuffer.cxx | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 3f22f983d2ab..60aa16f6c50a 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -91,7 +91,7 @@ Tile& TileBuffer::getTile(int x, int y, float aZoom) + aTileRectangle.x = pixelToTwip(nTileSizePixels, aZoom) * y; + aTileRectangle.y = pixelToTwip(nTileSizePixels, aZoom) * x; + +- g_info ("Rendering (%d, %d)", x, y); ++ g_test_timer_start(); + m_pLOKDocument->pClass->paintTile(m_pLOKDocument, + pBuffer, + nTileSizePixels, nTileSizePixels, +@@ -99,6 +99,9 @@ Tile& TileBuffer::getTile(int x, int y, float aZoom) + pixelToTwip(nTileSizePixels, aZoom), + pixelToTwip(nTileSizePixels, aZoom)); + ++ double elapsedTime = g_test_timer_elapsed(); ++ g_info ("Rendered (%d, %d) in %f seconds", x, y, elapsedTime); ++ + //create a mapping for it + m_mTiles[index].setPixbuf(pPixBuf); + m_mTiles[index].valid = true; +-- +2.12.0 + diff --git a/SOURCES/0062-lokdocview-Handle-DELETE-key.patch b/SOURCES/0062-lokdocview-Handle-DELETE-key.patch new file mode 100644 index 0000000..2262654 --- /dev/null +++ b/SOURCES/0062-lokdocview-Handle-DELETE-key.patch @@ -0,0 +1,28 @@ +From 133c38f06f1e1b60a553e5c48a9834d0a52450ee Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 24 Jun 2015 02:02:39 +0530 +Subject: [PATCH 062/398] lokdocview: Handle DELETE key + +Change-Id: I58d0c36decf81c812c108458b449402416ebcc2d +(cherry picked from commit e2c73bf76a35ee8ce18e4499587de849c92eef1c) +--- + libreofficekit/source/gtk/lokdocview.cxx | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 368a8d536887..2c7bb7be4867 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -245,6 +245,9 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + case GDK_KEY_BackSpace: + nKeyCode = com::sun::star::awt::Key::BACKSPACE; + break; ++ case GDK_KEY_Delete: ++ nKeyCode = com::sun::star::awt::Key::DELETE; ++ break; + case GDK_KEY_Return: + nKeyCode = com::sun::star::awt::Key::RETURN; + break; +-- +2.12.0 + diff --git a/SOURCES/0063-gtktiledviewer-Don-t-continue-on-widget-init-failure.patch b/SOURCES/0063-gtktiledviewer-Don-t-continue-on-widget-init-failure.patch new file mode 100644 index 0000000..759e09a --- /dev/null +++ b/SOURCES/0063-gtktiledviewer-Don-t-continue-on-widget-init-failure.patch @@ -0,0 +1,29 @@ +From 2b0fe3b8c3f7d6de3fe2ca63f0d595d5891d36a4 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 29 Jun 2015 13:34:24 +0530 +Subject: [PATCH 063/398] gtktiledviewer: Don't continue on widget init failure + +Change-Id: I5916357903fad5878d29bc31f21af45816a45ec5 +(cherry picked from commit a482d3289fa7e3789a306970ea76d074527c3579) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 7510ca53a928..131fb5bb2d33 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -519,8 +519,8 @@ int main( int argc, char* argv[] ) + + // Docview + pDocView = lok_doc_view_new (argv[1], NULL, NULL); +- if (pDocView == NULL) +- g_error ("Error while creating LOKDocView widget"); ++ g_assert_nonnull(pDocView); ++ + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); +-- +2.12.0 + diff --git a/SOURCES/0064-g_assert_nonnull-was-not-declared.patch b/SOURCES/0064-g_assert_nonnull-was-not-declared.patch new file mode 100644 index 0000000..99746ab --- /dev/null +++ b/SOURCES/0064-g_assert_nonnull-was-not-declared.patch @@ -0,0 +1,28 @@ +From 6069cb43c79b715f557e6c64cc0091633292d382 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 29 Jun 2015 13:31:56 +0100 +Subject: [PATCH 064/398] g_assert_nonnull was not declared + +Change-Id: Ie98c37d4bdaa365ac27e8620fb5bbecbb0faccdf +(cherry picked from commit 48abc97220bd95841225cf4e18cd067ef470929a) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 131fb5bb2d33..d40cceb291ed 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -519,7 +519,9 @@ int main( int argc, char* argv[] ) + + // Docview + pDocView = lok_doc_view_new (argv[1], NULL, NULL); ++#if GLIB_CHECK_VERSION(2,40,0) + g_assert_nonnull(pDocView); ++#endif + + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); +-- +2.12.0 + diff --git a/SOURCES/0065-LOK-Don-t-try-to-absolutize-URL-s.patch b/SOURCES/0065-LOK-Don-t-try-to-absolutize-URL-s.patch new file mode 100644 index 0000000..99e1e86 --- /dev/null +++ b/SOURCES/0065-LOK-Don-t-try-to-absolutize-URL-s.patch @@ -0,0 +1,80 @@ +From 68f3bc4d183e56e09975c3e41aceaeba95ddac46 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Fri, 3 Jul 2015 18:14:31 +0200 +Subject: [PATCH 065/398] LOK: Don't try to absolutize URL's. + +Based on a patch by Henry Castro. + +(cherry picked from commit e83cb37cf7546e8bc46d0d49b487dcd352b67093) + +Change-Id: Ia7aca20feb8f6095adf7dfe510ed78b1e9882740 +--- + desktop/source/lib/init.cxx | 34 +++++++++------------------------- + 1 file changed, 9 insertions(+), 25 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index aa8e27c7f48f..c08f1eec85de 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -166,23 +166,19 @@ static OUString getUString(const char* pString) + static OUString getAbsoluteURL(const char* pURL) + { + OUString aURL(getUString(pURL)); +- if (aURL.isEmpty()) ++ ++ // return unchanged if it likely is an URL already ++ if (aURL.indexOf("://") > 0) + return aURL; + +- // convert relative paths to absolute ones +- OUString aWorkingDir; +- osl_getProcessWorkingDir(&aWorkingDir.pData); +- if (!aWorkingDir.endsWith("/")) +- aWorkingDir += "/"; ++ OUString sAbsoluteDocUrl, sWorkingDir, sDocPathUrl; + +- try { +- return rtl::Uri::convertRelToAbs(aWorkingDir, aURL); +- } +- catch (const rtl::MalformedUriException &) +- { +- } ++ // convert relative paths to absolute ones ++ osl_getProcessWorkingDir(&sWorkingDir.pData); ++ osl::FileBase::getFileURLFromSystemPath( aURL, sDocPathUrl ); ++ osl::FileBase::getAbsoluteFileURL(sWorkingDir, sDocPathUrl, sAbsoluteDocUrl); + +- return OUString(); ++ return sAbsoluteDocUrl; + } + + extern "C" +@@ -354,12 +350,6 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, + SolarMutexGuard aGuard; + + OUString aURL(getAbsoluteURL(pURL)); +- if (aURL.isEmpty()) +- { +- pLib->maLastExceptionMsg = "Filename to load was not provided."; +- SAL_INFO("lok", "URL for load is empty"); +- return NULL; +- } + + pLib->maLastExceptionMsg.clear(); + +@@ -426,12 +416,6 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha + + OUString sFormat = getUString(pFormat); + OUString aURL(getAbsoluteURL(sUrl)); +- if (aURL.isEmpty()) +- { +- gImpl->maLastExceptionMsg = "Filename to save to was not provided."; +- SAL_INFO("lok", "URL for save is empty"); +- return false; +- } + + try + { +-- +2.12.0 + diff --git a/SOURCES/0066-LOK-Cleanup-absolutizing-of-URLs.patch b/SOURCES/0066-LOK-Cleanup-absolutizing-of-URLs.patch new file mode 100644 index 0000000..067894b --- /dev/null +++ b/SOURCES/0066-LOK-Cleanup-absolutizing-of-URLs.patch @@ -0,0 +1,77 @@ +From 203eaebd472da9d8c83493331af698b2f9811b55 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Mon, 6 Jul 2015 15:16:56 +0200 +Subject: [PATCH 066/398] LOK: Cleanup absolutizing of URLs. + +Thanks to Stephan Bergmann. + +Change-Id: I22aa3bb827db28bce3eabebb9b8c514663fad860 +(cherry picked from commit b183507ee293d8bcafa9c1c5b2844b7a83fea17b) +--- + desktop/source/lib/init.cxx | 32 +++++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index c08f1eec85de..63fe90b585b2 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -166,19 +166,21 @@ static OUString getUString(const char* pString) + static OUString getAbsoluteURL(const char* pURL) + { + OUString aURL(getUString(pURL)); +- +- // return unchanged if it likely is an URL already +- if (aURL.indexOf("://") > 0) ++ if (aURL.isEmpty()) + return aURL; + +- OUString sAbsoluteDocUrl, sWorkingDir, sDocPathUrl; +- + // convert relative paths to absolute ones +- osl_getProcessWorkingDir(&sWorkingDir.pData); +- osl::FileBase::getFileURLFromSystemPath( aURL, sDocPathUrl ); +- osl::FileBase::getAbsoluteFileURL(sWorkingDir, sDocPathUrl, sAbsoluteDocUrl); ++ OUString aWorkingDir; ++ osl_getProcessWorkingDir(&aWorkingDir.pData); ++ ++ try { ++ return rtl::Uri::convertRelToAbs(aWorkingDir + "/", aURL); ++ } ++ catch (const rtl::MalformedUriException &) ++ { ++ } + +- return sAbsoluteDocUrl; ++ return OUString(); + } + + extern "C" +@@ -350,6 +352,12 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, + SolarMutexGuard aGuard; + + OUString aURL(getAbsoluteURL(pURL)); ++ if (aURL.isEmpty()) ++ { ++ pLib->maLastExceptionMsg = "Filename to load was not provided."; ++ SAL_INFO("lok", "URL for load is empty"); ++ return NULL; ++ } + + pLib->maLastExceptionMsg.clear(); + +@@ -416,6 +424,12 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha + + OUString sFormat = getUString(pFormat); + OUString aURL(getAbsoluteURL(sUrl)); ++ if (aURL.isEmpty()) ++ { ++ gImpl->maLastExceptionMsg = "Filename to save to was not provided."; ++ SAL_INFO("lok", "URL for save is empty"); ++ return false; ++ } + + try + { +-- +2.12.0 + diff --git a/SOURCES/0067-LOK-Corner-case-with-working-dir-as.patch b/SOURCES/0067-LOK-Corner-case-with-working-dir-as.patch new file mode 100644 index 0000000..97d903a --- /dev/null +++ b/SOURCES/0067-LOK-Corner-case-with-working-dir-as.patch @@ -0,0 +1,31 @@ +From 423505af348586c46792d2d89c05b8cb9e021928 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 7 Jul 2015 08:40:28 +0200 +Subject: [PATCH 067/398] LOK: Corner case with working dir as '/'. + +Change-Id: I3965966f0d3fe65389e8834d67452ac56f9df2d6 +(cherry picked from commit c4e74d50901eeaf979be4707815c1d3490b543ea) +--- + desktop/source/lib/init.cxx | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 63fe90b585b2..aa8e27c7f48f 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -172,9 +172,11 @@ static OUString getAbsoluteURL(const char* pURL) + // convert relative paths to absolute ones + OUString aWorkingDir; + osl_getProcessWorkingDir(&aWorkingDir.pData); ++ if (!aWorkingDir.endsWith("/")) ++ aWorkingDir += "/"; + + try { +- return rtl::Uri::convertRelToAbs(aWorkingDir + "/", aURL); ++ return rtl::Uri::convertRelToAbs(aWorkingDir, aURL); + } + catch (const rtl::MalformedUriException &) + { +-- +2.12.0 + diff --git a/SOURCES/0068-lokdocview-Grab-focus-on-mouse-button-press-event.patch b/SOURCES/0068-lokdocview-Grab-focus-on-mouse-button-press-event.patch new file mode 100644 index 0000000..88a315f --- /dev/null +++ b/SOURCES/0068-lokdocview-Grab-focus-on-mouse-button-press-event.patch @@ -0,0 +1,26 @@ +From 9a0f632a8a5d76f8f685068738344cc1d7932805 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 2 Jul 2015 23:47:33 +0530 +Subject: [PATCH 068/398] lokdocview: Grab focus on mouse 'button-press-event' + +Change-Id: I65187bbd2cc32d9278d8b3890a82b5555390858a +(cherry picked from commit a625cd702700ae1773966a3133d27027d1c4d083) +--- + libreofficekit/source/gtk/lokdocview.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 2c7bb7be4867..5de795a1a961 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -812,6 +812,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + (int)pEvent->x, (int)pEvent->y, + (int)pixelToTwip(pEvent->x, priv->m_fZoom), + (int)pixelToTwip(pEvent->y, priv->m_fZoom)); ++ gtk_widget_grab_focus(GTK_WIDGET(pDocView)); + + if (pEvent->type == GDK_BUTTON_RELEASE) + { +-- +2.12.0 + diff --git a/SOURCES/0069-vcl-ITiledRenderable-getTextSelection-can-be-pure-vi.patch b/SOURCES/0069-vcl-ITiledRenderable-getTextSelection-can-be-pure-vi.patch new file mode 100644 index 0000000..bc0b01e --- /dev/null +++ b/SOURCES/0069-vcl-ITiledRenderable-getTextSelection-can-be-pure-vi.patch @@ -0,0 +1,31 @@ +From 30f6cbde85e6d5a0d522a6da19bea4f96396aeba Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 10 Jul 2015 09:11:20 +0200 +Subject: [PATCH 069/398] vcl::ITiledRenderable: getTextSelection() can be pure + virtual now + +Change-Id: Ifb33ee9a70afeccc01f45996b2953fcd5f3700cc +Reviewed-on: https://gerrit.libreoffice.org/16906 +Reviewed-by: Miklos Vajna +Tested-by: Jenkins +(cherry picked from commit 459bcc222f2aee52477cef8f94eb2789ff4ecd9a) +--- + include/vcl/ITiledRenderable.hxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index d212519bc9be..8824361f9f70 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -126,7 +126,7 @@ public: + * + * @see lok::Document::getTextSelection(). + */ +- virtual OString getTextSelection(const char* /*pMimeType*/, OString& /*rUsedMimeType*/) { return OString(); } ++ virtual OString getTextSelection(const char* pMimeType, OString& rUsedMimeType) = 0; + + /** + * Adjusts the graphic selection. +-- +2.12.0 + diff --git a/SOURCES/0070-With-enable-gtk3-we-need-GLib-2.38.patch b/SOURCES/0070-With-enable-gtk3-we-need-GLib-2.38.patch new file mode 100644 index 0000000..940e5fe --- /dev/null +++ b/SOURCES/0070-With-enable-gtk3-we-need-GLib-2.38.patch @@ -0,0 +1,36 @@ +From 1e080d37ad18059cbd2ca7d39ceafece5b826623 Mon Sep 17 00:00:00 2001 +From: Tor Lillqvist +Date: Tue, 14 Jul 2015 11:01:48 +0300 +Subject: [PATCH 070/398] With --enable-gtk3 we need GLib >= 2.38 + +The G_ADD_PRIVATE used in libreofficekit/source/gtk/lokdocview.cxx is from +2.38. + +(cherry picked from commit f3df77accae2941ba9c6a5e48b84d661f7a87863) + +Change-Id: I2058932f8252d2715f970f020160f4f960987125 +--- + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index d1d82ea28cad..4e27231f6a5f 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -9900,11 +9900,11 @@ if test "x$enable_gtk3" = "xyes"; then + AC_MSG_ERROR([System cairo required for gtk3 support, do not combine --enable-gtk3 with --without-system-cairo]) + fi + : ${with_system_cairo:=yes} +- PKG_CHECK_MODULES(GTK3, gtk+-3.0 >= 3.8 gtk+-unix-print-3.0 gmodule-no-export-2.0 cairo, ENABLE_GTK3="TRUE", ENABLE_GTK3="") ++ PKG_CHECK_MODULES(GTK3, gtk+-3.0 >= 3.8 gtk+-unix-print-3.0 gmodule-no-export-2.0 glib-2.0 >= 2.38 cairo, ENABLE_GTK3="TRUE", ENABLE_GTK3="") + if test "x$ENABLE_GTK3" = "xTRUE"; then + R="gtk3" + else +- AC_MSG_ERROR([gtk3 libraries of the correct versions, not found]) ++ AC_MSG_ERROR([gtk3 or dependent libraries of the correct versions, not found]) + fi + GTK3_CFLAGS=$(printf '%s' "$GTK3_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") + fi +-- +2.12.0 + diff --git a/SOURCES/0071-gtktiledviewer-method-for-resetting-all-tiles.patch b/SOURCES/0071-gtktiledviewer-method-for-resetting-all-tiles.patch new file mode 100644 index 0000000..c04e266 --- /dev/null +++ b/SOURCES/0071-gtktiledviewer-method-for-resetting-all-tiles.patch @@ -0,0 +1,69 @@ +From 143ffe8df3ee844c4022a8b4d6e3053a8d558f11 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Tue, 21 Jul 2015 18:49:21 +0300 +Subject: [PATCH 071/398] gtktiledviewer: method for resetting all tiles + +[ Miklos Vajna: The point of the change is that without this, part switching in +Calc does not work, as Calc does not invalidate everything after a part switch +(unlike Impress), and we suppose the right fix for this is to let the clients +throw away the tiles, rather than letting Calc send out invalidations, too. ] + +Change-Id: Id368b955c54efb87ecf3d59278ddb5cdbb2e7856 +Reviewed-on: https://gerrit.libreoffice.org/17267 +Reviewed-by: Miklos Vajna +Tested-by: Miklos Vajna +(cherry picked from commit ed9d6ef1e647b574f58ba870d71a4291d958c0ad) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 3 +++ + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 1 + + libreofficekit/source/gtk/lokdocview.cxx | 8 ++++++++ + 3 files changed, 12 insertions(+) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 962f9d9265bb..b98a85646e0e 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -63,6 +63,9 @@ char* lok_doc_view_get_part_name (LOKDocView* + int nPart); + void lok_doc_view_set_partmode (LOKDocView* pDocView, + int nPartMode); ++ ++void lok_doc_view_reset_view (LOKDocView* pDocView); ++ + /// Sets if the viewer is actually an editor or not. + void lok_doc_view_set_edit (LOKDocView* pDocView, + gboolean bEdit); +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index d40cceb291ed..8c43e9d68092 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -356,6 +356,7 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + if (g_bPartSelectorBroadcast && pDocView) + { + lok_doc_view_set_part( LOK_DOC_VIEW(pDocView), nPart ); ++ lok_doc_view_reset_view( LOK_DOC_VIEW(pDocView) ); + } + } + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 5de795a1a961..27d597ae57e3 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1529,6 +1529,14 @@ lok_doc_view_set_partmode(LOKDocView* pDocView, + priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode ); + } + ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_reset_view(LOKDocView* pDocView) ++{ ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_aTileBuffer.resetAllTiles(); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++} ++ + /** + * lok_doc_view_set_edit: + * @pDocView: The #LOKDocView instance +-- +2.12.0 + diff --git a/SOURCES/0072-lokdocview-Call-open_document-in-another-thread.patch b/SOURCES/0072-lokdocview-Call-open_document-in-another-thread.patch new file mode 100644 index 0000000..c477d61 --- /dev/null +++ b/SOURCES/0072-lokdocview-Call-open_document-in-another-thread.patch @@ -0,0 +1,244 @@ +From ccd9b4a66c6cc65892321dafcb8a633514a717e5 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 6 Jul 2015 22:01:30 +0530 +Subject: [PATCH 072/398] lokdocview: Call open_document in another thread + +This is to keep the widget responsive during document load. + +Change-Id: I81acaffc75ca7deddd6cc2de6abae22d009d40cd +(cherry picked from commit 645f00543405450cd3a3862482dc4e1cda65d098) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 11 +++- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 42 +++++++++------ + libreofficekit/source/gtk/lokdocview.cxx | 59 +++++++++++++++++++--- + 3 files changed, 86 insertions(+), 26 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index b98a85646e0e..3f56f08b2dce 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -45,8 +45,15 @@ GtkWidget* lok_doc_view_new (const gchar* + GCancellable *cancellable, + GError **error); + +-gboolean lok_doc_view_open_document (LOKDocView* pDocView, +- const gchar* pPath); ++void lok_doc_view_open_document (LOKDocView* pDocView, ++ const gchar* pPath, ++ GCancellable* cancellable, ++ GAsyncReadyCallback callback, ++ gpointer userdata); ++ ++gboolean lok_doc_view_open_document_finish (LOKDocView* pDocView, ++ GAsyncResult* res, ++ GError** error); + + /// Gets the document the viewer displays. + LibreOfficeKitDocument* lok_doc_view_get_document (LOKDocView* pDocView); +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 8c43e9d68092..c9fd3f2e5ca4 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -41,6 +41,7 @@ std::map g_aCommandNameToolItems; + bool g_bToolItemBroadcast = true; + static GtkWidget* pVBox; + static GtkComboBoxText* pPartSelector; ++static GtkWidget* pPartModeComboBox; + /// Should the part selector avoid calling lok::Document::setPart()? + static bool g_bPartSelectorBroadcast = true; + GtkWidget* pFindbar; +@@ -290,6 +291,7 @@ static void signalSearch(LOKDocView* /*pLOKDocView*/, char* /*pPayload*/, gpoint + gtk_label_set_text(GTK_LABEL(pFindbarLabel), "Search key not found"); + } + ++ + static void signalPart(LOKDocView* /*pLOKDocView*/, int nPart, gpointer /*pData*/) + { + g_bPartSelectorBroadcast = false; +@@ -380,6 +382,28 @@ static void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ ) + } + } + ++static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpointer /*userdata*/) ++{ ++ LOKDocView* pDocView1 = LOK_DOC_VIEW (source_object); ++ GError* error = NULL; ++ GList *focusChain = NULL; ++ ++ if (!lok_doc_view_open_document_finish(pDocView1, res, &error)) ++ { ++ g_warning ("Error occurred while opening the document : %s", error->message); ++ g_error_free (error); ++ } ++ ++ populatePartSelector(); ++ populatePartModeSelector( GTK_COMBO_BOX_TEXT(pPartModeComboBox) ); ++ // Connect these signals after populating the selectors, to avoid re-rendering on setting the default part/partmode. ++ g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0); ++ g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0); ++ ++ focusChain = g_list_append( focusChain, pDocView1 ); ++ gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain ); ++} ++ + int main( int argc, char* argv[] ) + { + if( argc < 3 || +@@ -435,7 +459,7 @@ int main( int argc, char* argv[] ) + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pSeparator2, -1); + + GtkToolItem* pPartModeSelectorToolItem = gtk_tool_item_new(); +- GtkWidget* pPartModeComboBox = gtk_combo_box_text_new(); ++ pPartModeComboBox = gtk_combo_box_text_new(); + gtk_container_add( GTK_CONTAINER(pPartModeSelectorToolItem), pPartModeComboBox ); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1 ); + +@@ -542,21 +566,7 @@ int main( int argc, char* argv[] ) + // Hide the findbar by default. + gtk_widget_hide(pFindbar); + +- int bOpened = lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2] ); +- if (!bOpened) +- g_error("main: lok_doc_view_open_document() failed"); +- assert(lok_doc_view_get_document(LOK_DOC_VIEW(pDocView))); +- +- populatePartSelector(); +- populatePartModeSelector( GTK_COMBO_BOX_TEXT(pPartModeComboBox) ); +- // Connect these signals after populating the selectors, to avoid re-rendering on setting the default part/partmode. +- g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0); +- g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0); +- +- // Make only LOKDocView widget as focussable +- GList *focusChain = NULL; +- focusChain = g_list_append( focusChain, pDocView ); +- gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain ); ++ lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView ); + + gtk_main(); + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 27d597ae57e3..40c0860973ad 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -108,8 +108,6 @@ struct _LOKDocViewPrivate + + enum + { +- LOAD_CHANGED, +- LOAD_FAILED, + EDIT_CHANGED, + COMMAND_CHANGED, + SEARCH_NOT_FOUND, +@@ -337,19 +335,23 @@ static gboolean + globalCallback (gpointer pData) + { + CallbackData* pCallback = static_cast(pData); ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pCallback->m_pDocView)); + + switch (pCallback->m_nType) + { + case LOK_CALLBACK_STATUS_INDICATOR_START: + { ++ priv->m_nLoadProgress = 0; + } + break; + case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE: + { ++ priv->m_nLoadProgress = std::stoi(pCallback->m_aPayload); + } + break; + case LOK_CALLBACK_STATUS_INDICATOR_FINISH: + { ++ priv->m_nLoadProgress = 100; + } + break; + default: +@@ -1389,15 +1391,30 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + } + + /** +- * lok_doc_view_open_document: ++ * lok_doc_view_open_document_finish: + * @pDocView: The #LOKDocView instance +- * @pPath: The path of the document that #LOKDocView widget should try to open ++ * @res: ++ * @error: + * + * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise + */ + SAL_DLLPUBLIC_EXPORT gboolean +-lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath) ++lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GError** error) ++{ ++ GTask* task = G_TASK(res); ++ ++ g_return_val_if_fail(g_task_is_valid(res, pDocView), NULL); ++ //FIXME: make source_tag workx ++ //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL); ++ g_return_val_if_fail(error == NULL || *error == NULL, NULL); ++ ++ return g_task_propagate_boolean(task, error); ++} ++ ++static void ++lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer task_data, GCancellable* cancellable) + { ++ LOKDocView* pDocView = LOK_DOC_VIEW(source_object); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + if ( priv->m_pDocument ) +@@ -1407,13 +1424,13 @@ lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath) + } + + priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView); +- priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, pPath ); ++ priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, priv->m_aDocPath ); + if ( !priv->m_pDocument ) + { + // FIXME: should have a GError parameter and populate it. + char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice ); + fprintf( stderr, "Error opening document '%s'\n", pError ); +- return FALSE; ++ g_task_return_new_error(task, 0, 0, pError); + } + else + { +@@ -1438,8 +1455,34 @@ lok_doc_view_open_document (LOKDocView* pDocView, const gchar* pPath) + nDocumentHeightPixels); + gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(pDocView)); ++ g_task_return_boolean (task, true); + } +- return TRUE; ++} ++ ++/** ++ * lok_doc_view_open_document: ++ * @pDocView: The #LOKDocView instance ++ * @pPath: The path of the document that #LOKDocView widget should try to open ++ * ++ * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise ++ */ ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_open_document (LOKDocView* pDocView, ++ const gchar* pPath, ++ GCancellable* cancellable, ++ GAsyncReadyCallback callback, ++ gpointer userdata) ++{ ++ GTask *task; ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_aDocPath = g_strdup(pPath); ++ ++ task = g_task_new(pDocView, cancellable, callback, userdata); ++ // FIXME: Use source_tag to check the task. ++ //g_task_set_source_tag(task, lok_doc_view_open_document); ++ ++ g_task_run_in_thread(task, lok_doc_view_open_document_func); ++ g_object_unref(task); + } + + /** +-- +2.12.0 + diff --git a/SOURCES/0073-lokdocview-Emit-load-changed-signal-showing-load-pro.patch b/SOURCES/0073-lokdocview-Emit-load-changed-signal-showing-load-pro.patch new file mode 100644 index 0000000..f33be0d --- /dev/null +++ b/SOURCES/0073-lokdocview-Emit-load-changed-signal-showing-load-pro.patch @@ -0,0 +1,185 @@ +From 2ce0084db53e9e029ed6a276823ece21297a3050 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 7 Jul 2015 21:16:45 +0530 +Subject: [PATCH 073/398] lokdocview: Emit load-changed signal showing load + progress + +Change-Id: I69b4c05d12c0c0b2ca6b7d1ad76ed74cc1f4346a +(cherry picked from commit da129b682f81a8fdbc6be95142456f204b2b7951) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 17 ++++++++ + libreofficekit/source/gtk/lokdocview.cxx | 45 +++++++++++++++------- + 2 files changed, 49 insertions(+), 13 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index c9fd3f2e5ca4..5ff357d4a089 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -30,6 +30,7 @@ static int help() + } + + static GtkWidget* pDocView; ++static GtkWidget* pStatusBar; + static GtkToolItem* pEnableEditing; + static GtkToolItem* pBold; + static GtkToolItem* pItalic; +@@ -285,6 +286,12 @@ static void signalCommand(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer + } + } + ++static void loadChanged(LOKDocView* /*pLOKDocView*/, gdouble fValue, gpointer pData) ++{ ++ GtkWidget* pProgressBar = GTK_WIDGET (pData); ++ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(pProgressBar), fValue); ++} ++ + /// LOKDocView found no search matches -> set the search label accordingly. + static void signalSearch(LOKDocView* /*pLOKDocView*/, char* /*pPayload*/, gpointer /*pData*/) + { +@@ -402,6 +409,8 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo + + focusChain = g_list_append( focusChain, pDocView1 ); + gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain ); ++ ++ gtk_widget_hide (pStatusBar); + } + + int main( int argc, char* argv[] ) +@@ -554,6 +563,7 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); + ++ + // Scrolled window for DocView + pScrolledWindow = gtk_scrolled_window_new(0, 0); + gtk_widget_set_hexpand (pScrolledWindow, TRUE); +@@ -562,6 +572,13 @@ int main( int argc, char* argv[] ) + + gtk_container_add(GTK_CONTAINER(pScrolledWindow), pDocView); + ++ GtkWidget* pProgressBar = gtk_progress_bar_new (); ++ g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); ++ ++ pStatusBar = gtk_statusbar_new (); ++ gtk_container_add (GTK_CONTAINER(pVBox), pStatusBar); ++ gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); ++ + gtk_widget_show_all( pWindow ); + // Hide the findbar by default. + gtk_widget_hide(pFindbar); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 40c0860973ad..bc9b27ac6302 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -40,7 +40,7 @@ struct _LOKDocViewPrivate + { + gchar* m_aLOPath; + gchar* m_aDocPath; +- guint m_nLoadProgress; ++ gdouble m_nLoadProgress; + gboolean m_bIsLoading; + gboolean m_bCanZoomIn; + gboolean m_bCanZoomOut; +@@ -108,6 +108,7 @@ struct _LOKDocViewPrivate + + enum + { ++ LOAD_CHANGED, + EDIT_CHANGED, + COMMAND_CHANGED, + SEARCH_NOT_FOUND, +@@ -341,17 +342,20 @@ globalCallback (gpointer pData) + { + case LOK_CALLBACK_STATUS_INDICATOR_START: + { +- priv->m_nLoadProgress = 0; ++ priv->m_nLoadProgress = 0.0; ++ g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, 0.0); + } + break; + case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE: + { +- priv->m_nLoadProgress = std::stoi(pCallback->m_aPayload); ++ priv->m_nLoadProgress = static_cast(std::stoi(pCallback->m_aPayload)/100.0); ++ g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, priv->m_nLoadProgress); + } + break; + case LOK_CALLBACK_STATUS_INDICATOR_FINISH: + { +- priv->m_nLoadProgress = 100; ++ priv->m_nLoadProgress = 1.0; ++ g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, 1.0); + } + break; + default: +@@ -1069,7 +1073,7 @@ static void lok_doc_view_get_property (GObject* object, guint propId, GValue *va + g_value_set_boolean (value, priv->m_bEdit); + break; + case PROP_LOAD_PROGRESS: +- g_value_set_uint (value, priv->m_nLoadProgress); ++ g_value_set_double (value, priv->m_nLoadProgress); + break; + case PROP_ZOOM: + g_value_set_float (value, priv->m_fZoom); +@@ -1210,11 +1214,11 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + */ + g_object_class_install_property (pGObjectClass, + PROP_LOAD_PROGRESS, +- g_param_spec_int("load-progress", +- "Estimated Load Progress", +- "Whether the content is in edit mode or not", +- 0, 100, 0, +- G_PARAM_READABLE)); ++ g_param_spec_double("load-progress", ++ "Estimated Load Progress", ++ "Shows the progress of the document load operation", ++ 0.0, 1.0, 0.0, ++ G_PARAM_READABLE)); + + /** + * LOKDocView:zoom-level: +@@ -1300,6 +1304,21 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + | G_PARAM_STATIC_STRINGS))); + + /** ++ * LOKDocView::load-changed: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @fLoadProgress: the new progress value ++ */ ++ doc_view_signals[LOAD_CHANGED] = ++ g_signal_new("load-changed", ++ G_TYPE_FROM_CLASS (pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, NULL, ++ g_cclosure_marshal_VOID__DOUBLE, ++ G_TYPE_NONE, 1, ++ G_TYPE_DOUBLE); ++ ++ /** + * LOKDocView::edit-changed: + * @pDocView: the #LOKDocView on which the signal is emitted + * @bEdit: the new edit value of the view +@@ -1403,16 +1422,16 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr + { + GTask* task = G_TASK(res); + +- g_return_val_if_fail(g_task_is_valid(res, pDocView), NULL); ++ g_return_val_if_fail(g_task_is_valid(res, pDocView), false); + //FIXME: make source_tag workx + //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL); +- g_return_val_if_fail(error == NULL || *error == NULL, NULL); ++ g_return_val_if_fail(error == NULL || *error == NULL, false); + + return g_task_propagate_boolean(task, error); + } + + static void +-lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer task_data, GCancellable* cancellable) ++lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer /*task_data*/, GCancellable* /*cancellable*/) + { + LOKDocView* pDocView = LOK_DOC_VIEW(source_object); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +-- +2.12.0 + diff --git a/SOURCES/0074-gtktiledviewer-Fill-whole-statusbar-with-progressbar.patch b/SOURCES/0074-gtktiledviewer-Fill-whole-statusbar-with-progressbar.patch new file mode 100644 index 0000000..c0342e1 --- /dev/null +++ b/SOURCES/0074-gtktiledviewer-Fill-whole-statusbar-with-progressbar.patch @@ -0,0 +1,44 @@ +From a7d821e0029c0c2c8d23adb6f95c18a3264d53c9 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 11 Jul 2015 21:29:53 +0530 +Subject: [PATCH 074/398] gtktiledviewer: Fill whole statusbar with progressbar + +We don't have anything yet to put in statusbar. Let progressbar +fill the whole width of statusbar for now. + +Change-Id: I4cd8745e997a0d2b917bc5baf358b097174d0df9 +(cherry picked from commit cb94e003c066033db96da62596022385794f281c) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 5ff357d4a089..a3999c09b29a 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -369,6 +369,11 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + } + } + ++static void removeChildrenFromStatusbar(GtkWidget* children, gpointer) ++{ ++ gtk_container_remove(GTK_CONTAINER(pStatusBar), children); ++} ++ + static void populatePartModeSelector( GtkComboBoxText* pSelector ) + { + gtk_combo_box_text_append_text( pSelector, "Standard" ); +@@ -576,8 +581,10 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); + + pStatusBar = gtk_statusbar_new (); ++ gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, NULL); + gtk_container_add (GTK_CONTAINER(pVBox), pStatusBar); + gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); ++ gtk_widget_set_hexpand(pProgressBar, true); + + gtk_widget_show_all( pWindow ); + // Hide the findbar by default. +-- +2.12.0 + diff --git a/SOURCES/0075-lokdocview-Use-a-thread-pool-for-most-LOK-calls.patch b/SOURCES/0075-lokdocview-Use-a-thread-pool-for-most-LOK-calls.patch new file mode 100644 index 0000000..9d30001 --- /dev/null +++ b/SOURCES/0075-lokdocview-Use-a-thread-pool-for-most-LOK-calls.patch @@ -0,0 +1,472 @@ +From ebaad17eeafbfa87a4feacde6514a77b37872178 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 12 Jul 2015 23:22:51 +0530 +Subject: [PATCH 075/398] lokdocview: Use a thread pool for most LOK calls + +This is a thread pool with just single thread because LOK is +single threaded; using multiple threads in this case would be +useless. + +Primary reason we are using a thread pool here is to avoid the +overhead in spawning a new thread for each LOK call. + +Change-Id: Ibbfdb7cb0a8ef9f07bcc659e65ce8997716aa245 +(cherry picked from commit a433ea9f46cc1cc0de7282f3d360d70ad215aaa8) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 4 +- + libreofficekit/source/gtk/lokdocview.cxx | 327 ++++++++++++++++++++++------- + 2 files changed, 253 insertions(+), 78 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 3f56f08b2dce..02789ad3f585 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -81,8 +81,8 @@ gboolean lok_doc_view_get_edit (LOKDocView* + + /// Posts the .uno: command to the LibreOfficeKit. + void lok_doc_view_post_command (LOKDocView* pDocView, +- const char* pCommand, +- const char* pArguments); ++ const gchar* pCommand, ++ const gchar* pArguments); + + float lok_doc_view_pixel_to_twip (LOKDocView* pDocView, + float fInput); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index bc9b27ac6302..46b031950e8a 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -134,6 +134,16 @@ enum + PROP_CAN_ZOOM_OUT + }; + ++enum ++{ ++ LOK_LOAD_DOC, ++ LOK_POST_COMMAND, ++ LOK_SET_EDIT, ++ LOK_SET_PARTMODE, ++ LOK_SET_PART, ++ LOK_POST_KEY ++}; ++ + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + + static void lok_doc_view_initable_iface_init (GInitableIface *iface); +@@ -150,6 +160,7 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA, + #pragma GCC diagnostic pop + #endif + ++static GThreadPool* lokThreadPool; + + struct CallbackData + { +@@ -163,6 +174,40 @@ struct CallbackData + m_pDocView(pDocView) {} + }; + ++struct LOEvent ++{ ++ int m_nType; ++ const gchar* m_pCommand; ++ const gchar* m_pArguments; ++ gchar* m_pPath; ++ gboolean m_bEdit; ++ int m_nPartMode; ++ int m_nPart; ++ int m_nKeyEvent; ++ int m_nCharCode; ++ int m_nKeyCode; ++ ++ LOEvent(int type) ++ : m_nType(type) {} ++ ++ LOEvent(int type, const gchar* pCommand, const gchar* pArguments) ++ : m_nType(type), ++ m_pCommand(pCommand), ++ m_pArguments(pArguments) {} ++ ++ LOEvent(int type, const gchar* pPath) ++ : m_nType(type) ++ { ++ m_pPath = g_strdup(pPath); ++ } ++ ++ LOEvent(int type, int nKeyEvent, int nCharCode, int nKeyCode) ++ : m_nType(type), ++ m_nKeyEvent(nKeyEvent), ++ m_nCharCode(nCharCode), ++ m_nKeyCode(nKeyCode) {} ++}; ++ + static void + payloadToSize(const char* pPayload, long& rWidth, long& rHeight) + { +@@ -225,6 +270,20 @@ isEmptyRectangle(const GdkRectangle& rRectangle) + return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0; + } + ++static void ++postKeyEventInThread(gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ ++ priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, ++ pLOEvent->m_nKeyEvent, ++ pLOEvent->m_nCharCode, ++ pLOEvent->m_nKeyCode); ++} ++ + static gboolean + signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + { +@@ -281,10 +340,23 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + if (pEvent->state & GDK_SHIFT_MASK) + nKeyCode |= KEY_SHIFT; + ++ + if (pEvent->type == GDK_KEY_RELEASE) +- priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode); ++ { ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); ++ } + else +- priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode); ++ { ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); ++ } + + return FALSE; + } +@@ -1013,6 +1085,143 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + return FALSE; + } + ++static void ++lok_doc_view_open_document_in_thread (gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ ++ if ( priv->m_pDocument ) ++ { ++ priv->m_pDocument->pClass->destroy( priv->m_pDocument ); ++ priv->m_pDocument = 0; ++ } ++ ++ priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView); ++ priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, priv->m_aDocPath ); ++ if ( !priv->m_pDocument ) ++ { ++ // FIXME: should have a GError parameter and populate it. ++ char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice ); ++ fprintf( stderr, "Error opening document '%s'\n", pError ); ++ g_task_return_new_error(task, 0, 0, pError); ++ } ++ else ++ { ++ priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); ++ priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pDocView); ++ priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); ++ g_timeout_add(600, handleTimeout, pDocView); ++ ++ float zoom = priv->m_fZoom; ++ long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; ++ long nDocumentHeightTwips = priv->m_nDocumentHeightTwips; ++ long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); ++ long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); ++ // Total number of columns in this document. ++ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); ++ ++ ++ priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, ++ nColumns); ++ gtk_widget_set_size_request(GTK_WIDGET(pDocView), ++ nDocumentWidthPixels, ++ nDocumentHeightPixels); ++ gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE); ++ gtk_widget_grab_focus(GTK_WIDGET(pDocView)); ++ g_task_return_boolean (task, true); ++ } ++} ++ ++static void ++lok_doc_view_set_part_in_thread(gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ int nPart = pLOEvent->m_nPart; ++ ++ priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart ); ++} ++ ++static void ++lok_doc_view_set_partmode_in_thread(gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ int nPartMode = pLOEvent->m_nPartMode; ++ ++ priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode ); ++} ++ ++static void ++lok_doc_view_set_edit_in_thread(gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ gboolean bWasEdit = priv->m_bEdit; ++ gboolean bEdit = pLOEvent->m_bEdit; ++ ++ if (!priv->m_bEdit && bEdit) ++ g_info("lok_doc_view_set_edit: entering edit mode"); ++ else if (priv->m_bEdit && !bEdit) ++ { ++ g_info("lok_doc_view_set_edit: leaving edit mode"); ++ priv->m_pDocument->pClass->resetSelection(priv->m_pDocument); ++ } ++ priv->m_bEdit = bEdit; ++ g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++} ++ ++static void ++lok_doc_view_post_command_in_thread (gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ ++ priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments); ++} ++ ++static void ++lokThreadFunc(gpointer data, gpointer /*user_data*/) ++{ ++ GTask* task = G_TASK(data); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ ++ switch (pLOEvent->m_nType) ++ { ++ case LOK_LOAD_DOC: ++ lok_doc_view_open_document_in_thread (task); ++ break; ++ case LOK_POST_COMMAND: ++ lok_doc_view_post_command_in_thread (task); ++ break; ++ case LOK_SET_EDIT: ++ lok_doc_view_set_edit_in_thread(task); ++ break; ++ case LOK_SET_PART: ++ lok_doc_view_set_part_in_thread(task); ++ break; ++ case LOK_SET_PARTMODE: ++ lok_doc_view_set_partmode_in_thread(task); ++ break; ++ case LOK_POST_KEY: ++ postKeyEventInThread(task); ++ break; ++ } ++ ++ g_object_unref(task); ++} ++ + static void lok_doc_view_init (LOKDocView* pDocView) + { + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +@@ -1392,6 +1601,12 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); ++ ++ lokThreadPool = g_thread_pool_new(lokThreadFunc, ++ NULL, ++ 1, ++ FALSE, ++ NULL); + } + + /** +@@ -1423,60 +1638,13 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr + GTask* task = G_TASK(res); + + g_return_val_if_fail(g_task_is_valid(res, pDocView), false); +- //FIXME: make source_tag workx ++ //FIXME: make source_tag work + //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL); + g_return_val_if_fail(error == NULL || *error == NULL, false); + + return g_task_propagate_boolean(task, error); + } + +-static void +-lok_doc_view_open_document_func (GTask* task, gpointer source_object, gpointer /*task_data*/, GCancellable* /*cancellable*/) +-{ +- LOKDocView* pDocView = LOK_DOC_VIEW(source_object); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- +- if ( priv->m_pDocument ) +- { +- priv->m_pDocument->pClass->destroy( priv->m_pDocument ); +- priv->m_pDocument = 0; +- } +- +- priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView); +- priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, priv->m_aDocPath ); +- if ( !priv->m_pDocument ) +- { +- // FIXME: should have a GError parameter and populate it. +- char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice ); +- fprintf( stderr, "Error opening document '%s'\n", pError ); +- g_task_return_new_error(task, 0, 0, pError); +- } +- else +- { +- priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); +- priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pDocView); +- priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); +- g_timeout_add(600, handleTimeout, pDocView); +- +- float zoom = priv->m_fZoom; +- long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; +- long nDocumentHeightTwips = priv->m_nDocumentHeightTwips; +- long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); +- long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); +- // Total number of columns in this document. +- guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +- +- +- priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, +- nColumns); +- gtk_widget_set_size_request(GTK_WIDGET(pDocView), +- nDocumentWidthPixels, +- nDocumentHeightPixels); +- gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE); +- gtk_widget_grab_focus(GTK_WIDGET(pDocView)); +- g_task_return_boolean (task, true); +- } +-} + + /** + * lok_doc_view_open_document: +@@ -1492,15 +1660,13 @@ lok_doc_view_open_document (LOKDocView* pDocView, + GAsyncReadyCallback callback, + gpointer userdata) + { +- GTask *task; ++ GTask* task = g_task_new(pDocView, cancellable, callback, userdata); ++ LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC, pPath); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + priv->m_aDocPath = g_strdup(pPath); ++ g_task_set_task_data(task, pLOEvent, g_free); + +- task = g_task_new(pDocView, cancellable, callback, userdata); +- // FIXME: Use source_tag to check the task. +- //g_task_set_source_tag(task, lok_doc_view_open_document); +- +- g_task_run_in_thread(task, lok_doc_view_open_document_func); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + +@@ -1572,8 +1738,13 @@ lok_doc_view_get_part (LOKDocView* pDocView) + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart ); ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); ++ pLOEvent->m_nPart = nPart; ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); + } + + SAL_DLLPUBLIC_EXPORT char* +@@ -1587,8 +1758,13 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_partmode(LOKDocView* pDocView, + int nPartMode) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode ); ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); ++ pLOEvent->m_nPartMode = nPartMode; ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); + } + + SAL_DLLPUBLIC_EXPORT void +@@ -1610,19 +1786,13 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_edit(LOKDocView* pDocView, + gboolean bEdit) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- gboolean bWasEdit = priv->m_bEdit; ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); ++ pLOEvent->m_bEdit = bEdit; ++ g_task_set_task_data(task, pLOEvent, g_free); + +- if (!priv->m_bEdit && bEdit) +- g_info("lok_doc_view_set_edit: entering edit mode"); +- else if (priv->m_bEdit && !bEdit) +- { +- g_info("lok_doc_view_set_edit: leaving edit mode"); +- priv->m_pDocument->pClass->resetSelection(priv->m_pDocument); +- } +- priv->m_bEdit = bEdit; +- g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit); +- gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); + } + + /** +@@ -1648,11 +1818,16 @@ lok_doc_view_get_edit (LOKDocView* pDocView) + */ + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_post_command (LOKDocView* pDocView, +- const char* pCommand, +- const char* pArguments) ++ const gchar* pCommand, ++ const gchar* pArguments) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pCommand, pArguments); ++ ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND, pCommand, pArguments); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); + } + + /** +-- +2.12.0 + diff --git a/SOURCES/0076-lokdocview-Make-paintTile-async.patch b/SOURCES/0076-lokdocview-Make-paintTile-async.patch new file mode 100644 index 0000000..0af3db4 --- /dev/null +++ b/SOURCES/0076-lokdocview-Make-paintTile-async.patch @@ -0,0 +1,239 @@ +From d52f669ccaad0522c52716779acddd2715be440e Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 19 Jul 2015 01:03:56 +0530 +Subject: [PATCH 076/398] lokdocview: Make paintTile() async + +Change-Id: I57db9e3adf26996e6e1e105b8b95f53e88e7760f +(cherry picked from commit 4edbf5a01fb8d93f3e6f2b9f7100a0c3d2eafa6e) +--- + libreofficekit/source/gtk/lokdocview.cxx | 12 ++++- + libreofficekit/source/gtk/tilebuffer.cxx | 91 ++++++++++++++++++++------------ + libreofficekit/source/gtk/tilebuffer.hxx | 28 ++++++++-- + 3 files changed, 91 insertions(+), 40 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 46b031950e8a..0740e04dd6c8 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -520,7 +520,7 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + + for (int i = aStart.x; i < aEnd.x; i++) + for (int j = aStart.y; j < aEnd.y; j++) +- priv->m_aTileBuffer.setInvalid(i, j); ++ priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom); + } + + static gboolean +@@ -741,6 +741,12 @@ renderGraphicHandle(LOKDocView* pDocView, + } + } + ++static void ++renderDocumentCallback(GObject* source_object, GAsyncResult*, gpointer) ++{ ++ LOKDocView* pDocView = LOK_DOC_VIEW(source_object); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++} + + static gboolean + renderDocument(LOKDocView* pDocView, cairo_t* pCairo) +@@ -790,7 +796,9 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + + if (bPaint) + { +- Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom); ++ GTask* task = g_task_new(pDocView, NULL, renderDocumentCallback, NULL); ++ Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task); ++ + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, + twipToPixel(aTileRectangleTwips.x, priv->m_fZoom), +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 60aa16f6c50a..d488f8b0516c 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -27,6 +27,42 @@ float twipToPixel(float fInput, float zoom) + return fInput / 1440.0f * DPI * zoom; + } + ++static void getTileFunc(GTask*, gpointer, gpointer task_data, GCancellable*) ++{ ++ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); ++ GetTileCallbackData* pCallback = static_cast(task_data); ++ TileBuffer* buffer = pCallback->m_pBuffer; ++ int index = pCallback->m_nX * buffer->m_nWidth + pCallback->m_nY; ++ if (!pPixBuf) ++ { ++ g_info ("Error allocating memory to pixbuf"); ++ return; ++ } ++ ++ unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); ++ GdkRectangle aTileRectangle; ++ aTileRectangle.x = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nY; ++ aTileRectangle.y = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nX; ++ ++ g_test_timer_start(); ++ buffer->m_pLOKDocument->pClass->paintTile(buffer->m_pLOKDocument, ++ pBuffer, ++ nTileSizePixels, nTileSizePixels, ++ aTileRectangle.x, aTileRectangle.y, ++ pixelToTwip(nTileSizePixels, pCallback->m_fZoom), ++ pixelToTwip(nTileSizePixels, pCallback->m_fZoom)); ++ ++ double elapsedTime = g_test_timer_elapsed(); ++ g_info ("Rendered (%d, %d) in %f seconds", ++ pCallback->m_nX, ++ pCallback->m_nY, ++ elapsedTime); ++ ++ //create a mapping for it ++ buffer->m_mTiles[index].setPixbuf(pPixBuf); ++ buffer->m_mTiles[index].valid = true; ++} ++ + /* ---------------------------- + Tile class member functions + ---------------------------- +@@ -56,55 +92,42 @@ void TileBuffer::resetAllTiles() + std::map::iterator it = m_mTiles.begin(); + for (; it != m_mTiles.end(); ++it) + { +- it->second.release(); ++ it->second.valid = false; + } +- m_mTiles.clear(); + } + +-void TileBuffer::setInvalid(int x, int y) ++void TileBuffer::setInvalid(int x, int y, float fZoom) + { + int index = x * m_nWidth + y; + g_info("Setting tile invalid (%d, %d)", x, y); + if (m_mTiles.find(index) != m_mTiles.end()) + { + m_mTiles[index].valid = false; +- m_mTiles[index].release(); +- m_mTiles.erase(index); ++ GTask* task = g_task_new(this, NULL, NULL, NULL); ++ GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, fZoom, this); ++ g_task_set_task_data(task, pCallback, g_free); ++ g_task_run_in_thread(task, getTileFunc); + } + } + +-Tile& TileBuffer::getTile(int x, int y, float aZoom) ++Tile& TileBuffer::getTile(int x, int y, float aZoom, GTask* task) + { + int index = x * m_nWidth + y; +- if(m_mTiles.find(index) == m_mTiles.end() || !m_mTiles[index].valid) +- { + +- GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); +- if (!pPixBuf) +- { +- g_info ("Error allocating memory to pixbuf"); +- return m_mTiles[index]; +- } +- +- unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); +- GdkRectangle aTileRectangle; +- aTileRectangle.x = pixelToTwip(nTileSizePixels, aZoom) * y; +- aTileRectangle.y = pixelToTwip(nTileSizePixels, aZoom) * x; +- +- g_test_timer_start(); +- m_pLOKDocument->pClass->paintTile(m_pLOKDocument, +- pBuffer, +- nTileSizePixels, nTileSizePixels, +- aTileRectangle.x, aTileRectangle.y, +- pixelToTwip(nTileSizePixels, aZoom), +- pixelToTwip(nTileSizePixels, aZoom)); +- +- double elapsedTime = g_test_timer_elapsed(); +- g_info ("Rendered (%d, %d) in %f seconds", x, y, elapsedTime); +- +- //create a mapping for it +- m_mTiles[index].setPixbuf(pPixBuf); +- m_mTiles[index].valid = true; ++ if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid) ++ { ++ GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this); ++ g_task_set_task_data(task, pCallback, g_free); ++ g_task_run_in_thread(task, getTileFunc); ++ return m_mTiles[index]; ++ } ++ else if(m_mTiles.find(index) == m_mTiles.end()) ++ { ++ GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this); ++ g_task_set_task_data(task, pCallback, g_free); ++ g_info ("running in thread new tile"); ++ g_task_run_in_thread(task, getTileFunc); ++ return m_DummyTile; + } + + return m_mTiles[index]; +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 6e6c0beb48f3..50de72d9d3b9 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -86,7 +86,10 @@ class TileBuffer + int columns) + : m_pLOKDocument(document) + , m_nWidth(columns) +- { } ++ { ++ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); ++ m_DummyTile.setPixbuf(pPixBuf); ++ } + + ~TileBuffer() {} + +@@ -104,7 +107,7 @@ class TileBuffer + + @return the tile at the mentioned position (x, y) + */ +- Tile& getTile(int x, int y, float aZoom); ++ Tile& getTile(int x, int y, float aZoom, GTask*); + /// Destroys all the tiles in the tile buffer; also frees the memory allocated + /// for all the Tile objects. + void resetAllTiles(); +@@ -115,17 +118,34 @@ class TileBuffer + @param x the position of tile along x-axis + @param y the position of tile along y-axis + */ +- void setInvalid(int x, int y); ++ void setInvalid(int x, int y, float zoom); ++ + +- private: + /// Contains the reference to the LOK Document that this tile buffer is for. + LibreOfficeKitDocument *m_pLOKDocument; + /// Stores all the tiles cached by this tile buffer. + std::map m_mTiles; + /// Width of the current tile buffer (number of columns) + int m_nWidth; ++ /// Dummy tile ++ Tile m_DummyTile; + }; + ++struct GetTileCallbackData ++{ ++ int m_nX; ++ int m_nY; ++ float m_fZoom; ++ TileBuffer* m_pBuffer; ++ ++ GetTileCallbackData(int x, int y, float zoom, TileBuffer* buffer) ++ : m_nX(x), ++ m_nY(y), ++ m_fZoom(zoom), ++ m_pBuffer(buffer) { } ++}; ++ ++ + #endif // INCLUDED_TILEBUFFER_HXX + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0077-lokdocview-tilebuffer-Add-DOxygen-comments.patch b/SOURCES/0077-lokdocview-tilebuffer-Add-DOxygen-comments.patch new file mode 100644 index 0000000..81794bc --- /dev/null +++ b/SOURCES/0077-lokdocview-tilebuffer-Add-DOxygen-comments.patch @@ -0,0 +1,77 @@ +From 490b3e99671ae4fee3b4e4bb2cc9b40e66f26e3c Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 22 Jul 2015 20:25:36 +0530 +Subject: [PATCH 077/398] lokdocview, tilebuffer: Add DOxygen comments + +Change-Id: I27377f0a758729a7877cfc6a56ea1b4bb3d1c3c9 +(cherry picked from commit e032b64451347f5079c2a5bfbfda8d843db91e2d) +--- + libreofficekit/source/gtk/lokdocview.cxx | 12 ++++++++++++ + libreofficekit/source/gtk/tilebuffer.hxx | 5 +++++ + 2 files changed, 17 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 0740e04dd6c8..ddb3c386b0ca 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -36,6 +36,7 @@ + // Number of handles around a graphic selection. + #define GRAPHIC_HANDLE_COUNT 8 + ++/// Private struct used by this GObject type + struct _LOKDocViewPrivate + { + gchar* m_aLOPath; +@@ -162,6 +163,7 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA, + + static GThreadPool* lokThreadPool; + ++/// Helper struct used to pass the data from soffice thread -> main thread. + struct CallbackData + { + int m_nType; +@@ -174,8 +176,16 @@ struct CallbackData + m_pDocView(pDocView) {} + }; + ++/** ++ A struct that we use to store the data about the LOK call. ++ ++ Object of this type is passed with all the LOK calls, ++ so that they can be idenitified. Additionally, it also contains ++ the data that LOK call needs. ++*/ + struct LOEvent + { ++ /// To identify the type of LOK call + int m_nType; + const gchar* m_pCommand; + const gchar* m_pArguments; +@@ -187,6 +197,8 @@ struct LOEvent + int m_nCharCode; + int m_nKeyCode; + ++ ++ /// Constructor to easily instantiate an object for LOK call of `type' type. + LOEvent(int type) + : m_nType(type) {} + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 50de72d9d3b9..40fb2abbae6d 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -131,6 +131,11 @@ class TileBuffer + Tile m_DummyTile; + }; + ++/** ++ Helper struct used to pass the data from main thread to spawned threads. ++ Spawned threads are responsible for calling paintTile, and store the result ++ in tile buffer. ++*/ + struct GetTileCallbackData + { + int m_nX; +-- +2.12.0 + diff --git a/SOURCES/0078-Use-thread-pool-for-LOK-call-paintTile.patch b/SOURCES/0078-Use-thread-pool-for-LOK-call-paintTile.patch new file mode 100644 index 0000000..c315bbf --- /dev/null +++ b/SOURCES/0078-Use-thread-pool-for-LOK-call-paintTile.patch @@ -0,0 +1,413 @@ +From aec82a6e59d9d1aef25507d07ded71570527fd19 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 24 Jul 2015 01:10:42 +0530 +Subject: [PATCH 078/398] Use thread pool for LOK call: paintTile() + +Change-Id: I45e94248013277affa11e91439fbc16995b8ed8e +(cherry picked from commit a7f12df929226ba43356d3d092851b07c84ae1c4) +--- + libreofficekit/source/gtk/lokdocview.cxx | 122 ++++++++++++++----------------- + libreofficekit/source/gtk/tilebuffer.cxx | 61 ++++------------ + libreofficekit/source/gtk/tilebuffer.hxx | 69 +++++++++++++---- + 3 files changed, 125 insertions(+), 127 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index ddb3c386b0ca..f32c3e10546e 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -135,16 +135,6 @@ enum + PROP_CAN_ZOOM_OUT + }; + +-enum +-{ +- LOK_LOAD_DOC, +- LOK_POST_COMMAND, +- LOK_SET_EDIT, +- LOK_SET_PARTMODE, +- LOK_SET_PART, +- LOK_POST_KEY +-}; +- + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + + static void lok_doc_view_initable_iface_init (GInitableIface *iface); +@@ -161,7 +151,7 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA, + #pragma GCC diagnostic pop + #endif + +-static GThreadPool* lokThreadPool; ++GThreadPool* lokThreadPool; + + /// Helper struct used to pass the data from soffice thread -> main thread. + struct CallbackData +@@ -176,50 +166,6 @@ struct CallbackData + m_pDocView(pDocView) {} + }; + +-/** +- A struct that we use to store the data about the LOK call. +- +- Object of this type is passed with all the LOK calls, +- so that they can be idenitified. Additionally, it also contains +- the data that LOK call needs. +-*/ +-struct LOEvent +-{ +- /// To identify the type of LOK call +- int m_nType; +- const gchar* m_pCommand; +- const gchar* m_pArguments; +- gchar* m_pPath; +- gboolean m_bEdit; +- int m_nPartMode; +- int m_nPart; +- int m_nKeyEvent; +- int m_nCharCode; +- int m_nKeyCode; +- +- +- /// Constructor to easily instantiate an object for LOK call of `type' type. +- LOEvent(int type) +- : m_nType(type) {} +- +- LOEvent(int type, const gchar* pCommand, const gchar* pArguments) +- : m_nType(type), +- m_pCommand(pCommand), +- m_pArguments(pArguments) {} +- +- LOEvent(int type, const gchar* pPath) +- : m_nType(type) +- { +- m_pPath = g_strdup(pPath); +- } +- +- LOEvent(int type, int nKeyEvent, int nCharCode, int nKeyCode) +- : m_nType(type), +- m_nKeyEvent(nKeyEvent), +- m_nCharCode(nCharCode), +- m_nKeyCode(nKeyCode) {} +-}; +- + static void + payloadToSize(const char* pPayload, long& rWidth, long& rHeight) + { +@@ -529,10 +475,12 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + aStart.y = aRectanglePixels.x / nTileSizePixels; + aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; + aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; +- ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + for (int i = aStart.x; i < aEnd.x; i++) + for (int j = aStart.y; j < aEnd.y; j++) +- priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom); ++ priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task); ++ ++ g_object_unref(task); + } + + static gboolean +@@ -753,13 +701,6 @@ renderGraphicHandle(LOKDocView* pDocView, + } + } + +-static void +-renderDocumentCallback(GObject* source_object, GAsyncResult*, gpointer) +-{ +- LOKDocView* pDocView = LOK_DOC_VIEW(source_object); +- gtk_widget_queue_draw(GTK_WIDGET(pDocView)); +-} +- + static gboolean + renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + { +@@ -808,14 +749,14 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + + if (bPaint) + { +- GTask* task = g_task_new(pDocView, NULL, renderDocumentCallback, NULL); ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task); +- + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, + twipToPixel(aTileRectangleTwips.x, priv->m_fZoom), + twipToPixel(aTileRectangleTwips.y, priv->m_fZoom)); + cairo_paint(pCairo); ++ g_object_unref(task); + } + } + } +@@ -1212,6 +1153,52 @@ lok_doc_view_post_command_in_thread (gpointer data) + } + + static void ++paintTileInThread (gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ TileBuffer& buffer = priv->m_aTileBuffer; ++ int index = pLOEvent->m_nX * buffer.m_nWidth + pLOEvent->m_nY; ++ if (buffer.m_mTiles.find(index) != buffer.m_mTiles.end() && ++ buffer.m_mTiles[index].valid) ++ return; ++ ++ GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); ++ if (!pPixBuf) ++ { ++ g_info ("Error allocating memory to pixbuf"); ++ return; ++ } ++ ++ unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); ++ GdkRectangle aTileRectangle; ++ aTileRectangle.x = pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom) * pLOEvent->m_nY; ++ aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom) * pLOEvent->m_nX; ++ ++ g_test_timer_start(); ++ priv->m_pDocument->pClass->paintTile(priv->m_pDocument, ++ pBuffer, ++ nTileSizePixels, nTileSizePixels, ++ aTileRectangle.x, aTileRectangle.y, ++ pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom), ++ pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom)); ++ ++ double elapsedTime = g_test_timer_elapsed(); ++ g_info ("Rendered (%d, %d) in %f seconds", ++ pLOEvent->m_nX, ++ pLOEvent->m_nY, ++ elapsedTime); ++ ++ //create a mapping for it ++ buffer.m_mTiles[index].setPixbuf(pPixBuf); ++ buffer.m_mTiles[index].valid = true; ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++} ++ ++ ++static void + lokThreadFunc(gpointer data, gpointer /*user_data*/) + { + GTask* task = G_TASK(data); +@@ -1237,6 +1224,9 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + case LOK_POST_KEY: + postKeyEventInThread(task); + break; ++ case LOK_PAINT_TILE: ++ paintTileInThread(task); ++ break; + } + + g_object_unref(task); +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index d488f8b0516c..a8594fc916f0 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -13,6 +13,8 @@ + #define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__) + #endif + ++extern GThreadPool* lokThreadPool; ++ + /* ------------------ + Utility functions + ------------------ +@@ -27,42 +29,6 @@ float twipToPixel(float fInput, float zoom) + return fInput / 1440.0f * DPI * zoom; + } + +-static void getTileFunc(GTask*, gpointer, gpointer task_data, GCancellable*) +-{ +- GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); +- GetTileCallbackData* pCallback = static_cast(task_data); +- TileBuffer* buffer = pCallback->m_pBuffer; +- int index = pCallback->m_nX * buffer->m_nWidth + pCallback->m_nY; +- if (!pPixBuf) +- { +- g_info ("Error allocating memory to pixbuf"); +- return; +- } +- +- unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); +- GdkRectangle aTileRectangle; +- aTileRectangle.x = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nY; +- aTileRectangle.y = pixelToTwip(nTileSizePixels, pCallback->m_fZoom) * pCallback->m_nX; +- +- g_test_timer_start(); +- buffer->m_pLOKDocument->pClass->paintTile(buffer->m_pLOKDocument, +- pBuffer, +- nTileSizePixels, nTileSizePixels, +- aTileRectangle.x, aTileRectangle.y, +- pixelToTwip(nTileSizePixels, pCallback->m_fZoom), +- pixelToTwip(nTileSizePixels, pCallback->m_fZoom)); +- +- double elapsedTime = g_test_timer_elapsed(); +- g_info ("Rendered (%d, %d) in %f seconds", +- pCallback->m_nX, +- pCallback->m_nY, +- elapsedTime); +- +- //create a mapping for it +- buffer->m_mTiles[index].setPixbuf(pPixBuf); +- buffer->m_mTiles[index].valid = true; +-} +- + /* ---------------------------- + Tile class member functions + ---------------------------- +@@ -96,17 +62,17 @@ void TileBuffer::resetAllTiles() + } + } + +-void TileBuffer::setInvalid(int x, int y, float fZoom) ++void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task) + { + int index = x * m_nWidth + y; + g_info("Setting tile invalid (%d, %d)", x, y); + if (m_mTiles.find(index) != m_mTiles.end()) + { + m_mTiles[index].valid = false; +- GTask* task = g_task_new(this, NULL, NULL, NULL); +- GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, fZoom, this); +- g_task_set_task_data(task, pCallback, g_free); +- g_task_run_in_thread(task, getTileFunc); ++ ++ LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, fZoom); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + } + } + +@@ -116,17 +82,16 @@ Tile& TileBuffer::getTile(int x, int y, float aZoom, GTask* task) + + if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid) + { +- GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this); +- g_task_set_task_data(task, pCallback, g_free); +- g_task_run_in_thread(task, getTileFunc); ++ LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + return m_mTiles[index]; + } + else if(m_mTiles.find(index) == m_mTiles.end()) + { +- GetTileCallbackData* pCallback = new GetTileCallbackData(x, y, aZoom, this); +- g_task_set_task_data(task, pCallback, g_free); +- g_info ("running in thread new tile"); +- g_task_run_in_thread(task, getTileFunc); ++ LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + return m_DummyTile; + } + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 40fb2abbae6d..f23b02330616 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -107,7 +107,7 @@ class TileBuffer + + @return the tile at the mentioned position (x, y) + */ +- Tile& getTile(int x, int y, float aZoom, GTask*); ++ Tile& getTile(int x, int y, float aZoom, GTask* task); + /// Destroys all the tiles in the tile buffer; also frees the memory allocated + /// for all the Tile objects. + void resetAllTiles(); +@@ -118,8 +118,7 @@ class TileBuffer + @param x the position of tile along x-axis + @param y the position of tile along y-axis + */ +- void setInvalid(int x, int y, float zoom); +- ++ void setInvalid(int x, int y, float zoom, GTask* task); + + /// Contains the reference to the LOK Document that this tile buffer is for. + LibreOfficeKitDocument *m_pLOKDocument; +@@ -131,26 +130,70 @@ class TileBuffer + Tile m_DummyTile; + }; + ++enum ++{ ++ LOK_LOAD_DOC, ++ LOK_POST_COMMAND, ++ LOK_SET_EDIT, ++ LOK_SET_PARTMODE, ++ LOK_SET_PART, ++ LOK_POST_KEY, ++ LOK_PAINT_TILE ++}; ++ + /** +- Helper struct used to pass the data from main thread to spawned threads. +- Spawned threads are responsible for calling paintTile, and store the result +- in tile buffer. ++ A struct that we use to store the data about the LOK call. ++ ++ Object of this type is passed with all the LOK calls, ++ so that they can be idenitified. Additionally, it also contains ++ the data that LOK call needs. + */ +-struct GetTileCallbackData ++struct LOEvent + { ++ /// To identify the type of LOK call ++ int m_nType; ++ const gchar* m_pCommand; ++ const gchar* m_pArguments; ++ gchar* m_pPath; ++ gboolean m_bEdit; ++ int m_nPartMode; ++ int m_nPart; ++ int m_nKeyEvent; ++ int m_nCharCode; ++ int m_nKeyCode; ++ + int m_nX; + int m_nY; + float m_fZoom; +- TileBuffer* m_pBuffer; + +- GetTileCallbackData(int x, int y, float zoom, TileBuffer* buffer) +- : m_nX(x), ++ /// Constructor to easily instantiate an object for LOK call of `type' type. ++ LOEvent(int type) ++ : m_nType(type) {} ++ ++ LOEvent(int type, const gchar* pCommand, const gchar* pArguments) ++ : m_nType(type), ++ m_pCommand(pCommand), ++ m_pArguments(pArguments) {} ++ ++ LOEvent(int type, const gchar* pPath) ++ : m_nType(type) ++ { ++ m_pPath = g_strdup(pPath); ++ } ++ ++ LOEvent(int type, int nKeyEvent, int nCharCode, int nKeyCode) ++ : m_nType(type), ++ m_nKeyEvent(nKeyEvent), ++ m_nCharCode(nCharCode), ++ m_nKeyCode(nKeyCode) {} ++ ++ LOEvent(int type, int x, int y, float zoom) ++ : m_nType(type), ++ m_nX(x), + m_nY(y), +- m_fZoom(zoom), +- m_pBuffer(buffer) { } ++ m_fZoom(zoom) {} + }; + +- + #endif // INCLUDED_TILEBUFFER_HXX + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0079-lokdocview-Cannot-use-same-GTask-object-for-all-call.patch b/SOURCES/0079-lokdocview-Cannot-use-same-GTask-object-for-all-call.patch new file mode 100644 index 0000000..585ea4c --- /dev/null +++ b/SOURCES/0079-lokdocview-Cannot-use-same-GTask-object-for-all-call.patch @@ -0,0 +1,38 @@ +From 82d1cdb5446334ddcd25cb61558d9974bd4c8e6f Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 25 Jul 2015 21:21:34 +0530 +Subject: [PATCH 079/398] lokdocview: Cannot use same GTask object for all + calls. + +Change-Id: I875d49a9e4360659087ae70456edefb15bc57b20 +(cherry picked from commit 57ec1780d654e335e09a6c64c4d48234f0556635) +--- + libreofficekit/source/gtk/lokdocview.cxx | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index f32c3e10546e..bebd5fdb5546 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -475,12 +475,15 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + aStart.y = aRectanglePixels.x / nTileSizePixels; + aEnd.x = (aRectanglePixels.y + aRectanglePixels.height + nTileSizePixels) / nTileSizePixels; + aEnd.y = (aRectanglePixels.x + aRectanglePixels.width + nTileSizePixels) / nTileSizePixels; +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + for (int i = aStart.x; i < aEnd.x; i++) ++ { + for (int j = aStart.y; j < aEnd.y; j++) ++ { ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task); +- +- g_object_unref(task); ++ g_object_unref(task); ++ } ++ } + } + + static gboolean +-- +2.12.0 + diff --git a/SOURCES/0080-lokdocview-Follow-the-camelCase-naming-convention.patch b/SOURCES/0080-lokdocview-Follow-the-camelCase-naming-convention.patch new file mode 100644 index 0000000..afd6618 --- /dev/null +++ b/SOURCES/0080-lokdocview-Follow-the-camelCase-naming-convention.patch @@ -0,0 +1,88 @@ +From cd86f9867b9e4ad7b4a7cb73784b114de2551086 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 26 Jul 2015 17:22:13 +0530 +Subject: [PATCH 080/398] lokdocview: Follow the camelCase naming convention + +Change-Id: I05582d33ee3535d4b677fa8138c9d573585a4252 +(cherry picked from commit ee0f4f75d2d95aaed8995337947c4cc665722aaf) +--- + libreofficekit/source/gtk/lokdocview.cxx | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index bebd5fdb5546..e44f9b96886a 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1050,7 +1050,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + } + + static void +-lok_doc_view_open_document_in_thread (gpointer data) ++openDocumentInThread (gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +@@ -1099,7 +1099,7 @@ lok_doc_view_open_document_in_thread (gpointer data) + } + + static void +-lok_doc_view_set_part_in_thread(gpointer data) ++setPartInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +@@ -1111,7 +1111,7 @@ lok_doc_view_set_part_in_thread(gpointer data) + } + + static void +-lok_doc_view_set_partmode_in_thread(gpointer data) ++setPartmodeInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +@@ -1123,7 +1123,7 @@ lok_doc_view_set_partmode_in_thread(gpointer data) + } + + static void +-lok_doc_view_set_edit_in_thread(gpointer data) ++setEditInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +@@ -1145,7 +1145,7 @@ lok_doc_view_set_edit_in_thread(gpointer data) + } + + static void +-lok_doc_view_post_command_in_thread (gpointer data) ++postCommandInThread (gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +@@ -1210,19 +1210,19 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + switch (pLOEvent->m_nType) + { + case LOK_LOAD_DOC: +- lok_doc_view_open_document_in_thread (task); ++ openDocumentInThread(task); + break; + case LOK_POST_COMMAND: +- lok_doc_view_post_command_in_thread (task); ++ postCommandInThread(task); + break; + case LOK_SET_EDIT: +- lok_doc_view_set_edit_in_thread(task); ++ setEditInThread(task); + break; + case LOK_SET_PART: +- lok_doc_view_set_part_in_thread(task); ++ setPartInThread(task); + break; + case LOK_SET_PARTMODE: +- lok_doc_view_set_partmode_in_thread(task); ++ setPartmodeInThread(task); + break; + case LOK_POST_KEY: + postKeyEventInThread(task); +-- +2.12.0 + diff --git a/SOURCES/0081-lokdocview-Use-only-one-ctor-for-instantiating-LOEve.patch b/SOURCES/0081-lokdocview-Use-only-one-ctor-for-instantiating-LOEve.patch new file mode 100644 index 0000000..97ce1b2 --- /dev/null +++ b/SOURCES/0081-lokdocview-Use-only-one-ctor-for-instantiating-LOEve.patch @@ -0,0 +1,247 @@ +From a9ed2a81b472091a2f255cf1ffba6f48001f46d6 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 26 Jul 2015 18:24:02 +0530 +Subject: [PATCH 081/398] lokdocview: Use only one ctor for instantiating + LOEvent + +... and set each member variable manually. + +Additionally, improves documentation of the struct LOEvent. + +Change-Id: I2e8e1dc70298dc85943769e2f01c6127eedb8207 +(cherry picked from commit 4fb3d2e6be39fb3a7323b11a02adf853ed37a3ca) +--- + libreofficekit/source/gtk/lokdocview.cxx | 41 +++++++++++++++--------- + libreofficekit/source/gtk/tilebuffer.cxx | 17 +++++++--- + libreofficekit/source/gtk/tilebuffer.hxx | 54 +++++++++++++++----------------- + 3 files changed, 65 insertions(+), 47 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index e44f9b96886a..6bee2f513ae9 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -39,8 +39,8 @@ + /// Private struct used by this GObject type + struct _LOKDocViewPrivate + { +- gchar* m_aLOPath; +- gchar* m_aDocPath; ++ const gchar* m_aLOPath; ++ const gchar* m_aDocPath; + gdouble m_nLoadProgress; + gboolean m_bIsLoading; + gboolean m_bCanZoomIn; +@@ -302,7 +302,10 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + if (pEvent->type == GDK_KEY_RELEASE) + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +- LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYUP, nCharCode, nKeyCode); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY); ++ pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYUP; ++ pLOEvent->m_nCharCode = nCharCode; ++ pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, g_free); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -310,7 +313,10 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + else + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +- LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY, LOK_KEYEVENT_KEYINPUT, nCharCode, nKeyCode); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY); ++ pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYINPUT; ++ pLOEvent->m_nCharCode = nCharCode; ++ pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, g_free); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1163,7 +1169,7 @@ paintTileInThread (gpointer data) + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + TileBuffer& buffer = priv->m_aTileBuffer; +- int index = pLOEvent->m_nX * buffer.m_nWidth + pLOEvent->m_nY; ++ int index = pLOEvent->m_nPaintTileX * buffer.m_nWidth + pLOEvent->m_nPaintTileY; + if (buffer.m_mTiles.find(index) != buffer.m_mTiles.end() && + buffer.m_mTiles[index].valid) + return; +@@ -1177,21 +1183,21 @@ paintTileInThread (gpointer data) + + unsigned char* pBuffer = gdk_pixbuf_get_pixels(pPixBuf); + GdkRectangle aTileRectangle; +- aTileRectangle.x = pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom) * pLOEvent->m_nY; +- aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom) * pLOEvent->m_nX; ++ aTileRectangle.x = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileY; ++ aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileX; + + g_test_timer_start(); + priv->m_pDocument->pClass->paintTile(priv->m_pDocument, + pBuffer, + nTileSizePixels, nTileSizePixels, + aTileRectangle.x, aTileRectangle.y, +- pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom), +- pixelToTwip(nTileSizePixels, pLOEvent->m_fZoom)); ++ pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom), ++ pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom)); + + double elapsedTime = g_test_timer_elapsed(); + g_info ("Rendered (%d, %d) in %f seconds", +- pLOEvent->m_nX, +- pLOEvent->m_nY, ++ pLOEvent->m_nPaintTileX, ++ pLOEvent->m_nPaintTileY, + elapsedTime); + + //create a mapping for it +@@ -1674,9 +1680,12 @@ lok_doc_view_open_document (LOKDocView* pDocView, + gpointer userdata) + { + GTask* task = g_task_new(pDocView, cancellable, callback, userdata); +- LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC, pPath); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- priv->m_aDocPath = g_strdup(pPath); ++ ++ LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC); ++ pLOEvent->m_pPath = pPath; ++ ++ priv->m_aDocPath = pPath; + g_task_set_task_data(task, pLOEvent, g_free); + + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); +@@ -1836,9 +1845,11 @@ lok_doc_view_post_command (LOKDocView* pDocView, + { + + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +- LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND, pCommand, pArguments); +- g_task_set_task_data(task, pLOEvent, g_free); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); ++ pLOEvent->m_pCommand = pCommand; ++ pLOEvent->m_pArguments = pArguments; + ++ g_task_set_task_data(task, pLOEvent, g_free); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index a8594fc916f0..21ea58b0faff 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -70,26 +70,35 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task) + { + m_mTiles[index].valid = false; + +- LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, fZoom); ++ LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE); ++ pLOEvent->m_nPaintTileX = x; ++ pLOEvent->m_nPaintTileY = y; ++ pLOEvent->m_fPaintTileZoom = fZoom; + g_task_set_task_data(task, pLOEvent, g_free); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + } + } + +-Tile& TileBuffer::getTile(int x, int y, float aZoom, GTask* task) ++Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task) + { + int index = x * m_nWidth + y; + + if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid) + { +- LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom); ++ LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE); ++ pLOEvent->m_nPaintTileX = x; ++ pLOEvent->m_nPaintTileY = y; ++ pLOEvent->m_fPaintTileZoom = fZoom; + g_task_set_task_data(task, pLOEvent, g_free); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + return m_mTiles[index]; + } + else if(m_mTiles.find(index) == m_mTiles.end()) + { +- LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE, x, y, aZoom); ++ LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE); ++ pLOEvent->m_nPaintTileX = x; ++ pLOEvent->m_nPaintTileY = y; ++ pLOEvent->m_fPaintTileZoom = fZoom; + g_task_set_task_data(task, pLOEvent, g_free); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + return m_DummyTile; +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index f23b02330616..6e57d2fe8bd5 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -152,46 +152,44 @@ struct LOEvent + { + /// To identify the type of LOK call + int m_nType; ++ ++ /// @name post_command parameters ++ ///@{ + const gchar* m_pCommand; + const gchar* m_pArguments; +- gchar* m_pPath; ++ ///@} ++ ++ /// @name open_document parameter ++ ///@{ ++ const gchar* m_pPath; ++ ///@} ++ ++ /// set_edit parameter + gboolean m_bEdit; ++ ++ /// set_partmode parameter + int m_nPartMode; ++ ++ /// set_part parameter + int m_nPart; ++ ++ /// @name postKeyEvent parameters ++ ///@{ + int m_nKeyEvent; + int m_nCharCode; + int m_nKeyCode; ++ ///@} + +- int m_nX; +- int m_nY; +- float m_fZoom; ++ /// @name paintTile parameters ++ ///@{ ++ int m_nPaintTileX; ++ int m_nPaintTileY; ++ float m_fPaintTileZoom; ++ ///@} + +- /// Constructor to easily instantiate an object for LOK call of `type' type. ++ /// Constructor to instantiate an object of type `type`. + LOEvent(int type) + : m_nType(type) {} +- +- LOEvent(int type, const gchar* pCommand, const gchar* pArguments) +- : m_nType(type), +- m_pCommand(pCommand), +- m_pArguments(pArguments) {} +- +- LOEvent(int type, const gchar* pPath) +- : m_nType(type) +- { +- m_pPath = g_strdup(pPath); +- } +- +- LOEvent(int type, int nKeyEvent, int nCharCode, int nKeyCode) +- : m_nType(type), +- m_nKeyEvent(nKeyEvent), +- m_nCharCode(nCharCode), +- m_nKeyCode(nKeyCode) {} +- +- LOEvent(int type, int x, int y, float zoom) +- : m_nType(type), +- m_nX(x), +- m_nY(y), +- m_fZoom(zoom) {} + }; + + #endif // INCLUDED_TILEBUFFER_HXX +-- +2.12.0 + diff --git a/SOURCES/0082-lokdocview-Move-postMouseEvent-in-separate-LOK-threa.patch b/SOURCES/0082-lokdocview-Move-postMouseEvent-in-separate-LOK-threa.patch new file mode 100644 index 0000000..c815da5 --- /dev/null +++ b/SOURCES/0082-lokdocview-Move-postMouseEvent-in-separate-LOK-threa.patch @@ -0,0 +1,134 @@ +From 9ca320506308555b6b7fc7bbb3f82d76cdbf9a82 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 26 Jul 2015 22:23:46 +0530 +Subject: [PATCH 082/398] lokdocview: Move postMouseEvent in separate LOK + thread + +Change-Id: I9d1a08db2a91a596d3039a2388c22e6ea76dc2b1 +(cherry picked from commit de9224bf9686550e63876eb5ac1241b27c01bc25) +--- + libreofficekit/source/gtk/lokdocview.cxx | 52 ++++++++++++++++++++++++++++++-- + libreofficekit/source/gtk/tilebuffer.hxx | 11 ++++++- + 2 files changed, 59 insertions(+), 4 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 6bee2f513ae9..d23ac1af2fc1 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -958,7 +958,16 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + if ((pEvent->time - priv->m_nLastButtonPressTime) < 250) + nCount++; + priv->m_nLastButtonPressTime = pEvent->time; +- priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount); ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT); ++ pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEBUTTONDOWN; ++ pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ pLOEvent->m_nPostMouseEventCount = nCount; ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); + break; + } + case GDK_BUTTON_RELEASE: +@@ -967,7 +976,16 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + if ((pEvent->time - priv->m_nLastButtonReleaseTime) < 250) + nCount++; + priv->m_nLastButtonReleaseTime = pEvent->time; +- priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), nCount); ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT); ++ pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEBUTTONUP; ++ pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ pLOEvent->m_nPostMouseEventCount = nCount; ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); + break; + } + default: +@@ -1050,12 +1068,37 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + } + + // Otherwise a mouse move, as on the desktop. +- priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, LOK_MOUSEEVENT_MOUSEMOVE, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom), 1); ++ ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT); ++ pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEMOVE; ++ pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ pLOEvent->m_nPostMouseEventCount = 1; ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); + + return FALSE; + } + + static void ++postMouseEventInThread(gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ ++ priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, ++ pLOEvent->m_nPostMouseEventType, ++ pLOEvent->m_nPostMouseEventX, ++ pLOEvent->m_nPostMouseEventY, ++ pLOEvent->m_nPostMouseEventCount); ++} ++ ++static void + openDocumentInThread (gpointer data) + { + GTask* task = G_TASK(data); +@@ -1236,6 +1279,9 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + case LOK_PAINT_TILE: + paintTileInThread(task); + break; ++ case LOK_POST_MOUSE_EVENT: ++ postMouseEventInThread(task); ++ break; + } + + g_object_unref(task); +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 6e57d2fe8bd5..aa496aaf3e8f 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -138,7 +138,8 @@ enum + LOK_SET_PARTMODE, + LOK_SET_PART, + LOK_POST_KEY, +- LOK_PAINT_TILE ++ LOK_PAINT_TILE, ++ LOK_POST_MOUSE_EVENT + }; + + /** +@@ -187,6 +188,14 @@ struct LOEvent + float m_fPaintTileZoom; + ///@} + ++ /// @name postMouseEvent parameters ++ ///@{ ++ int m_nPostMouseEventType; ++ int m_nPostMouseEventX; ++ int m_nPostMouseEventY; ++ int m_nPostMouseEventCount; ++ ///@} ++ + /// Constructor to instantiate an object of type `type`. + LOEvent(int type) + : m_nType(type) {} +-- +2.12.0 + diff --git a/SOURCES/0083-lokdocview-setGraphicSelection-in-another-thread.patch b/SOURCES/0083-lokdocview-setGraphicSelection-in-another-thread.patch new file mode 100644 index 0000000..bcc92c7 --- /dev/null +++ b/SOURCES/0083-lokdocview-setGraphicSelection-in-another-thread.patch @@ -0,0 +1,157 @@ +From 3bb042ae678b26e234d19913846d695e8bfd8927 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 26 Jul 2015 22:39:43 +0530 +Subject: [PATCH 083/398] lokdocview: setGraphicSelection in another thread + +Change-Id: Ib7a6bf63ee6f300c6c5d50d02a3465d0a075a5be +(cherry picked from commit 7c45a57081a921b8f56812dd37c2fcd4b86d2a1a) +--- + libreofficekit/source/gtk/lokdocview.cxx | 68 ++++++++++++++++++++++++++++---- + libreofficekit/source/gtk/tilebuffer.hxx | 10 ++++- + 2 files changed, 70 insertions(+), 8 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d23ac1af2fc1..edd2179495f0 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -889,7 +889,17 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { + g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i); + priv->m_bInDragGraphicHandles[i] = false; +- priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom)); ++ ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); ++ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; ++ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); ++ + return FALSE; + } + } +@@ -898,7 +908,17 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { + g_info("LOKDocView_Impl::signalButton: end of drag graphic selection"); + priv->m_bInDragGraphicSelection = false; +- priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_END, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom)); ++ ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); ++ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; ++ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); ++ + return FALSE; + } + } +@@ -937,10 +957,17 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { + g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i); + priv->m_bInDragGraphicHandles[i] = true; +- priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, +- LOK_SETGRAPHICSELECTION_START, +- pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom), +- pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom)); ++ ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); ++ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; ++ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom); ++ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); ++ + return FALSE; + } + } +@@ -1063,7 +1090,17 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + { + g_info("lcl_signalMotion: start of drag graphic selection"); + priv->m_bInDragGraphicSelection = true; +- priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, LOK_SETGRAPHICSELECTION_START, pixelToTwip(pEvent->x, priv->m_fZoom), pixelToTwip(pEvent->y, priv->m_fZoom)); ++ ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); ++ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; ++ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ g_task_set_task_data(task, pLOEvent, g_free); ++ ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_object_unref(task); ++ + return FALSE; + } + +@@ -1084,6 +1121,20 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + } + + static void ++setGraphicSelectionInThread(gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ ++ priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, ++ pLOEvent->m_nSetGraphicSelectionType, ++ pLOEvent->m_nSetGraphicSelectionX, ++ pLOEvent->m_nSetGraphicSelectionY); ++} ++ ++static void + postMouseEventInThread(gpointer data) + { + GTask* task = G_TASK(data); +@@ -1282,6 +1333,9 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + case LOK_POST_MOUSE_EVENT: + postMouseEventInThread(task); + break; ++ case LOK_SET_GRAPHIC_SELECTION: ++ setGraphicSelectionInThread(task); ++ break; + } + + g_object_unref(task); +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index aa496aaf3e8f..d2451b6c2290 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -139,7 +139,8 @@ enum + LOK_SET_PART, + LOK_POST_KEY, + LOK_PAINT_TILE, +- LOK_POST_MOUSE_EVENT ++ LOK_POST_MOUSE_EVENT, ++ LOK_SET_GRAPHIC_SELECTION + }; + + /** +@@ -196,6 +197,13 @@ struct LOEvent + int m_nPostMouseEventCount; + ///@} + ++ /// @name setGraphicSelection parameters ++ ///@{ ++ int m_nSetGraphicSelectionType; ++ int m_nSetGraphicSelectionX; ++ int m_nSetGraphicSelectionY; ++ ///@} ++ + /// Constructor to instantiate an object of type `type`. + LOEvent(int type) + : m_nType(type) {} +-- +2.12.0 + diff --git a/SOURCES/0084-lokdocview-post_command-arguments-are-not-supposed-t.patch b/SOURCES/0084-lokdocview-post_command-arguments-are-not-supposed-t.patch new file mode 100644 index 0000000..0782d8e --- /dev/null +++ b/SOURCES/0084-lokdocview-post_command-arguments-are-not-supposed-t.patch @@ -0,0 +1,42 @@ +From 05fb507c0d86ad94da29826a3e61934cef476b92 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 27 Jul 2015 22:13:39 +0530 +Subject: [PATCH 084/398] lokdocview: post_command arguments are not supposed + to be const + +Change-Id: Ibc22d03d9eee9fd151ecf5773e36c2519141a5eb +(cherry picked from commit 2d2b392dcda5bdfab61a358dc1dd725d65fba07f) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + libreofficekit/source/gtk/tilebuffer.hxx | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index edd2179495f0..b72a664c9320 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1947,7 +1947,7 @@ lok_doc_view_post_command (LOKDocView* pDocView, + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); + pLOEvent->m_pCommand = pCommand; +- pLOEvent->m_pArguments = pArguments; ++ pLOEvent->m_pArguments = g_strdup(pArguments); + + g_task_set_task_data(task, pLOEvent, g_free); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index d2451b6c2290..dabf72f9ea67 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -158,7 +158,7 @@ struct LOEvent + /// @name post_command parameters + ///@{ + const gchar* m_pCommand; +- const gchar* m_pArguments; ++ gchar* m_pArguments; + ///@} + + /// @name open_document parameter +-- +2.12.0 + diff --git a/SOURCES/0085-libreofficekit-Werror-Wformat-security.patch b/SOURCES/0085-libreofficekit-Werror-Wformat-security.patch new file mode 100644 index 0000000..ac28720 --- /dev/null +++ b/SOURCES/0085-libreofficekit-Werror-Wformat-security.patch @@ -0,0 +1,27 @@ +From 435dcf370f19ea9b514c480a7c5a87b8cbc7b2d2 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 28 Jul 2015 16:35:02 +0200 +Subject: [PATCH 085/398] libreofficekit: -Werror,-Wformat-security + +Change-Id: I177ea091fb1061d9fa71f7fb1a84629128afd6a0 +(cherry picked from commit b120adb290cee480516b14683f314318573c9d7e) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index b72a664c9320..cb77aa4097d0 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1169,7 +1169,7 @@ openDocumentInThread (gpointer data) + // FIXME: should have a GError parameter and populate it. + char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice ); + fprintf( stderr, "Error opening document '%s'\n", pError ); +- g_task_return_new_error(task, 0, 0, pError); ++ g_task_return_new_error(task, 0, 0, "%s", pError); + } + else + { +-- +2.12.0 + diff --git a/SOURCES/0086-LOK-Implement-parts-for-Writer-too.patch b/SOURCES/0086-LOK-Implement-parts-for-Writer-too.patch new file mode 100644 index 0000000..ba321c1 --- /dev/null +++ b/SOURCES/0086-LOK-Implement-parts-for-Writer-too.patch @@ -0,0 +1,213 @@ +From fd9d67a7ad8b68399b5866406bd934829297a8d3 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Sat, 1 Aug 2015 02:13:47 +0200 +Subject: [PATCH 086/398] LOK: Implement parts for Writer too. + +In Writer, the meaning of 'parts' is a bit different than in Calc or Impress. +In Writer, the parts mean pages, and the document does not give a completely +different view, the cursor just jumps to the given page. + +It is up to the client to follow the cursor appropriately to have the desired +effect. + +Change-Id: I56b3264e0340cd639bdabfa92b74b52bd1f391a5 +(cherry picked from commit 512b782cf466a19ed77d818fa660e1a0dc74fc35) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 8 ++++ + libreofficekit/source/gtk/lokdocview.cxx | 18 +++++++++ + sw/inc/unotxdoc.hxx | 8 ++++ + sw/inc/viscrs.hxx | 3 ++ + sw/source/core/crsr/viscrs.cxx | 12 ++++++ + sw/source/uibase/uno/unotxdoc.cxx | 44 ++++++++++++++++++++++ + 6 files changed, 93 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index a3999c09b29a..3399087cb6db 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -358,6 +358,13 @@ static void populatePartSelector() + lok_doc_view_get_part( LOK_DOC_VIEW(pDocView) ) ); + } + ++static void signalSize(LOKDocView* /*pLOKDocView*/, gpointer /*pData*/) ++{ ++ g_bPartSelectorBroadcast = false; ++ populatePartSelector(); ++ g_bPartSelectorBroadcast = true; ++} ++ + static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + { + int nPart = gtk_combo_box_get_active( GTK_COMBO_BOX(pSelector) ); +@@ -566,6 +573,7 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); + g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); ++ g_signal_connect(pDocView, "size-changed", G_CALLBACK(signalSize), NULL); + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); + + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index cb77aa4097d0..bdae55fc54e0 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -114,6 +114,7 @@ enum + COMMAND_CHANGED, + SEARCH_NOT_FOUND, + PART_CHANGED, ++ SIZE_CHANGED, + HYPERLINK_CLICKED, + + LAST_SIGNAL +@@ -581,6 +582,8 @@ callback (gpointer pData) + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom), + twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom)); ++ ++ g_signal_emit(pDocView, doc_view_signals[SIZE_CHANGED], 0, NULL); + } + break; + case LOK_CALLBACK_SET_PART: +@@ -1707,6 +1710,21 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_INT); + + /** ++ * LOKDocView::size-changed: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aCommand: NULL, we just notify that want to notify the UI elements that are interested. ++ */ ++ doc_view_signals[SIZE_CHANGED] = ++ g_signal_new("size-changed", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, NULL, ++ g_cclosure_marshal_VOID__VOID, ++ G_TYPE_NONE, 1, ++ G_TYPE_INT); ++ ++ /** + * LOKDocView::hyperlinked-clicked: + * @pDocView: the #LOKDocView on which the signal is emitted + * @aHyperlink: the URI which the application should handle +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index c90a852ac8ee..9f0b03b3af38 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -407,6 +407,14 @@ public: + long nTileHeight ) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::getDocumentSize(). + virtual Size getDocumentSize() SAL_OVERRIDE; ++ /// @see vcl::ITiledRenderable::setPart(). ++ virtual void setPart(int nPart) SAL_OVERRIDE; ++ /// @see vcl::ITiledRenderable::getParts(). ++ virtual int getParts() SAL_OVERRIDE; ++ /// @see vcl::ITiledRenderable::getPart(). ++ virtual int getPart() SAL_OVERRIDE; ++ /// @see vcl::ITiledRenderable::getPartName(). ++ virtual OUString getPartName(int nPart) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::initializeForTiledRendering(). + virtual void initializeForTiledRendering() SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::registerCallback(). +diff --git a/sw/inc/viscrs.hxx b/sw/inc/viscrs.hxx +index 159fb2ffbc41..525b551b9867 100644 +--- a/sw/inc/viscrs.hxx ++++ b/sw/inc/viscrs.hxx +@@ -43,6 +43,9 @@ class SwVisCrsr + vcl::Cursor m_aTextCrsr; + const SwCrsrShell* m_pCrsrShell; + ++ /// For LibreOfficeKit only - remember what page we were at the last time. ++ sal_uInt16 m_nPageLastTime; ++ + void _SetPosAndShow(); + + public: +diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx +index 3e92ce5ef4e5..e0d32cc86e11 100644 +--- a/sw/source/core/crsr/viscrs.cxx ++++ b/sw/source/core/crsr/viscrs.cxx +@@ -67,6 +67,7 @@ MapMode* SwSelPaintRects::s_pMapMode = 0; + // Starting from here: classes / methods for the non-text-cursor + SwVisCrsr::SwVisCrsr( const SwCrsrShell * pCShell ) + : m_pCrsrShell( pCShell ) ++ , m_nPageLastTime(0) + { + pCShell->GetWin()->SetCursor( &m_aTextCrsr ); + m_bIsVisible = m_aTextCrsr.IsVisible(); +@@ -179,6 +180,17 @@ void SwVisCrsr::_SetPosAndShow() + + if (m_pCrsrShell->isTiledRendering()) + { ++ // notify about page number change (if that happened) ++ sal_uInt16 nPage, nVirtPage; ++ const_cast(m_pCrsrShell)->GetPageNum(nPage, nVirtPage); ++ if (nPage != m_nPageLastTime) ++ { ++ m_nPageLastTime = nPage; ++ OString aPayload = OString::number(nPage - 1); ++ m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); ++ } ++ ++ // notify about the cursor position & size + Rectangle aSVRect(aRect.Pos().getX(), aRect.Pos().getY(), aRect.Pos().getX() + aRect.SSize().Width(), aRect.Pos().getY() + aRect.SSize().Height()); + OString sRect = aSVRect.toString(); + m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, sRect.getStr()); +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 450650d26c13..0dbde54f9144 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3154,6 +3154,50 @@ Size SwXTextDocument::getDocumentSize() + aDocSize.Height() + 2L * DOCUMENTBORDER); + } + ++void SwXTextDocument::setPart(int nPart) ++{ ++ SolarMutexGuard aGuard; ++ ++ SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); ++ if (!pWrtShell) ++ return; ++ ++ pWrtShell->GotoPage(nPart + 1, true); ++} ++ ++int SwXTextDocument::getParts() ++{ ++ SolarMutexGuard aGuard; ++ ++ SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); ++ if (!pWrtShell) ++ return 0; ++ ++ return pWrtShell->GetPageCnt(); ++} ++ ++int SwXTextDocument::getPart() ++{ ++ SolarMutexGuard aGuard; ++ ++ SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); ++ if (!pWrtShell) ++ return 0; ++ ++ sal_uInt16 nPage, nLogPage; ++ OUString sDisplay; ++ pWrtShell->GetPageNumber(-1, pWrtShell->IsCrsrVisible(), nPage, nLogPage, sDisplay); ++ ++ return nPage - 1; ++} ++ ++OUString SwXTextDocument::getPartName(int nPart) ++{ ++ SolarMutexGuard aGuard; ++ ++ return OUString(SW_RES(STR_PAGE)) + OUString::number(nPart + 1); ++} ++ + void SwXTextDocument::initializeForTiledRendering() + { + SolarMutexGuard aGuard; +-- +2.12.0 + diff --git a/SOURCES/0087-Removed-some-whole-page-invalidations-in-impress.patch b/SOURCES/0087-Removed-some-whole-page-invalidations-in-impress.patch new file mode 100644 index 0000000..66a0f6c --- /dev/null +++ b/SOURCES/0087-Removed-some-whole-page-invalidations-in-impress.patch @@ -0,0 +1,60 @@ +From 41fe248a52c4685a4f59dd18bb9885f3576fd0ed Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Fri, 31 Jul 2015 18:24:33 +0300 +Subject: [PATCH 087/398] Removed some whole page invalidations in impress + +1. For tiled rendering, don't invalidate the whole page when hiding it +2. Don't invalidate when showing a page because we've just hidden the +previous one +3. No need for invalidation when setting visible layers + +Change-Id: I858401b22c95093c58ec00896fe92b766fddb6de +Reviewed-on: https://gerrit.libreoffice.org/17452 +Tested-by: Jenkins +Reviewed-by: Jan Holesovsky +(cherry picked from commit a381d16d23d0efb678e9e410db3ad23313693640) +--- + include/svx/svdpagv.hxx | 2 +- + svx/source/svdraw/svdpagv.cxx | 6 ++++-- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/include/svx/svdpagv.hxx b/include/svx/svdpagv.hxx +index 8bf305f6be60..f28e3e7cb79d 100644 +--- a/include/svx/svdpagv.hxx ++++ b/include/svx/svdpagv.hxx +@@ -216,7 +216,7 @@ public: + void PagePosToLogic(Point& rPnt) const { rPnt+=aPgOrg; } + void PagePosToLogic(Rectangle& rRect) const { rRect.Move(aPgOrg.X(),aPgOrg.Y()); } + +- void SetVisibleLayers(const SetOfByte& rSet) { aLayerVisi=rSet; InvalidateAllWin(); } ++ void SetVisibleLayers(const SetOfByte& rSet) { aLayerVisi=rSet; } + const SetOfByte& GetVisibleLayers() const { return aLayerVisi; } + void SetPrintableLayers(const SetOfByte& rSet) { aLayerPrn=rSet; } + const SetOfByte& GetPrintableLayers() const { return aLayerPrn; } +diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx +index e8caa445fe9c..9c74d433e1c9 100644 +--- a/svx/source/svdraw/svdpagv.cxx ++++ b/svx/source/svdraw/svdpagv.cxx +@@ -229,7 +229,6 @@ void SdrPageView::Show() + if(!IsVisible()) + { + mbVisible = true; +- InvalidateAllWin(); + + for(sal_uInt32 a(0L); a < GetView().PaintWindowCount(); a++) + { +@@ -242,7 +241,10 @@ void SdrPageView::Hide() + { + if(IsVisible()) + { +- InvalidateAllWin(); ++ if (!GetView().GetModel()->isTiledRendering()) ++ { ++ InvalidateAllWin(); ++ } + mbVisible = false; + ClearPageWindows(); + } +-- +2.12.0 + diff --git a/SOURCES/0088-coverity-1315075-Uninitialized-pointer-field.patch b/SOURCES/0088-coverity-1315075-Uninitialized-pointer-field.patch new file mode 100644 index 0000000..6cc2494 --- /dev/null +++ b/SOURCES/0088-coverity-1315075-Uninitialized-pointer-field.patch @@ -0,0 +1,48 @@ +From fba4131c0f03038ec07aec11d7fe2ffea4c14a94 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 3 Aug 2015 20:15:18 +0100 +Subject: [PATCH 088/398] coverity#1315075 Uninitialized pointer field + +Change-Id: I4e933b458ca26b2a92d4953ca6cd6220dd730cf9 +(cherry picked from commit 1bc0cd0ee0251d42a6cbe75e5d86de4366f59029) +--- + libreofficekit/source/gtk/tilebuffer.hxx | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index dabf72f9ea67..b00724367b8d 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -206,7 +206,28 @@ struct LOEvent + + /// Constructor to instantiate an object of type `type`. + LOEvent(int type) +- : m_nType(type) {} ++ : m_nType(type) ++ , m_pCommand(0) ++ , m_pArguments(0) ++ , m_pPath(0) ++ , m_bEdit(false) ++ , m_nPartMode(0) ++ , m_nPart(0) ++ , m_nKeyEvent(0) ++ , m_nCharCode(0) ++ , m_nKeyCode(0) ++ , m_nPaintTileX(0) ++ , m_nPaintTileY(0) ++ , m_fPaintTileZoom(0) ++ , m_nPostMouseEventType(0) ++ , m_nPostMouseEventX(0) ++ , m_nPostMouseEventY(0) ++ , m_nPostMouseEventCount(0) ++ , m_nSetGraphicSelectionType(0) ++ , m_nSetGraphicSelectionX(0) ++ , m_nSetGraphicSelectionY(0) ++ { ++ } + }; + + #endif // INCLUDED_TILEBUFFER_HXX +-- +2.12.0 + diff --git a/SOURCES/0089-lokdocview-Don-t-use-extern-variable-lokThreadPool.patch b/SOURCES/0089-lokdocview-Don-t-use-extern-variable-lokThreadPool.patch new file mode 100644 index 0000000..46fbfc5 --- /dev/null +++ b/SOURCES/0089-lokdocview-Don-t-use-extern-variable-lokThreadPool.patch @@ -0,0 +1,304 @@ +From ade489c20e735224810e79ede6ef37bbbe8d56c0 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 29 Jul 2015 21:41:56 +0530 +Subject: [PATCH 089/398] lokdocview: Don't use extern variable: lokThreadPool + +Change-Id: Ia208e3309bb64baf71ceb97cdf1b3b57b6120353 +(cherry picked from commit 4df957f7255cf2ddce47a088dd30f945db6975be) +--- + libreofficekit/source/gtk/lokdocview.cxx | 53 +++++++++++++++++--------------- + libreofficekit/source/gtk/tilebuffer.cxx | 8 ++--- + libreofficekit/source/gtk/tilebuffer.hxx | 15 +++++++-- + 3 files changed, 44 insertions(+), 32 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index bdae55fc54e0..364590167f56 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -49,6 +49,7 @@ struct _LOKDocViewPrivate + LibreOfficeKitDocument* m_pDocument; + + TileBuffer m_aTileBuffer; ++ GThreadPool* lokThreadPool; + + gfloat m_fZoom; + glong m_nDocumentWidthTwips; +@@ -152,8 +153,6 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA, + #pragma GCC diagnostic pop + #endif + +-GThreadPool* lokThreadPool; +- + /// Helper struct used to pass the data from soffice thread -> main thread. + struct CallbackData + { +@@ -308,7 +307,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, g_free); +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + else +@@ -319,7 +318,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, g_free); +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + +@@ -487,7 +486,7 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + for (int j = aStart.y; j < aEnd.y; j++) + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +- priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task); ++ priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task, priv->lokThreadPool); + g_object_unref(task); + } + } +@@ -762,7 +761,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + if (bPaint) + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +- Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task); ++ Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task, priv->lokThreadPool); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, + twipToPixel(aTileRectangleTwips.x, priv->m_fZoom), +@@ -900,7 +899,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + + return FALSE; +@@ -919,7 +918,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + + return FALSE; +@@ -968,7 +967,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + + return FALSE; +@@ -996,7 +995,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nPostMouseEventCount = nCount; + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + break; + } +@@ -1014,7 +1013,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nPostMouseEventCount = nCount; + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + break; + } +@@ -1101,7 +1100,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + + return FALSE; +@@ -1117,7 +1116,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + pLOEvent->m_nPostMouseEventCount = 1; + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + + return FALSE; +@@ -1355,6 +1354,12 @@ static void lok_doc_view_init (LOKDocView* pDocView) + |GDK_BUTTON_MOTION_MASK + |GDK_KEY_PRESS_MASK + |GDK_KEY_RELEASE_MASK); ++ ++ priv->lokThreadPool = g_thread_pool_new(lokThreadFunc, ++ NULL, ++ 1, ++ FALSE, ++ NULL); + } + + static void lok_doc_view_set_property (GObject* object, guint propId, const GValue *value, GParamSpec *pspec) +@@ -1738,12 +1743,6 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +- +- lokThreadPool = g_thread_pool_new(lokThreadFunc, +- NULL, +- 1, +- FALSE, +- NULL); + } + + /** +@@ -1806,7 +1805,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + priv->m_aDocPath = pPath; + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + +@@ -1878,12 +1877,14 @@ lok_doc_view_get_part (LOKDocView* pDocView) + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + { ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); ++ + pLOEvent->m_nPart = nPart; + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + +@@ -1898,12 +1899,13 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_partmode(LOKDocView* pDocView, + int nPartMode) + { ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); + pLOEvent->m_nPartMode = nPartMode; + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + +@@ -1926,12 +1928,13 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_edit(LOKDocView* pDocView, + gboolean bEdit) + { ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); + pLOEvent->m_bEdit = bEdit; + g_task_set_task_data(task, pLOEvent, g_free); + +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + +@@ -1961,14 +1964,14 @@ lok_doc_view_post_command (LOKDocView* pDocView, + const gchar* pCommand, + const gchar* pArguments) + { +- ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); + pLOEvent->m_pCommand = pCommand; + pLOEvent->m_pArguments = g_strdup(pArguments); + + g_task_set_task_data(task, pLOEvent, g_free); +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 21ea58b0faff..85f6eb0422c2 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -13,8 +13,6 @@ + #define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__) + #endif + +-extern GThreadPool* lokThreadPool; +- + /* ------------------ + Utility functions + ------------------ +@@ -62,7 +60,8 @@ void TileBuffer::resetAllTiles() + } + } + +-void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task) ++void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, ++ GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; + g_info("Setting tile invalid (%d, %d)", x, y); +@@ -79,7 +78,8 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task) + } + } + +-Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task) ++Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, ++ GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index b00724367b8d..d4e7120e6587 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -103,11 +103,15 @@ class TileBuffer + + @param x the tile along the x-axis of the buffer + @param y the tile along the y-axis of the buffer +- @param aZoom This function needs the zoom factor to draw the tile using paintTile() ++ @param aZoom current zoom factor of the document ++ @param task GTask object containing the necessary data ++ @param pool GThreadPool managed by the widget instance used for all the ++ LOK calls made by widget. It is needed here because getTile invokes one ++ of the LOK call : paintTile. + + @return the tile at the mentioned position (x, y) + */ +- Tile& getTile(int x, int y, float aZoom, GTask* task); ++ Tile& getTile(int x, int y, float aZoom, GTask* task, GThreadPool* pool); + /// Destroys all the tiles in the tile buffer; also frees the memory allocated + /// for all the Tile objects. + void resetAllTiles(); +@@ -117,8 +121,13 @@ class TileBuffer + + @param x the position of tile along x-axis + @param y the position of tile along y-axis ++ @param zoom zoom factor of the document ++ @param task GTask object containing the necessary data ++ @param pool GThreadPool managed by the widget instance used for all the ++ LOK calls made by widget. It is needed here because setInvalid() invokes one ++ of the LOK call : paintTile. + */ +- void setInvalid(int x, int y, float zoom, GTask* task); ++ void setInvalid(int x, int y, float zoom, GTask* task, GThreadPool*); + + /// Contains the reference to the LOK Document that this tile buffer is for. + LibreOfficeKitDocument *m_pLOKDocument; +-- +2.12.0 + diff --git a/SOURCES/0090-LOKit-set-thread-name-lo_startmain.patch b/SOURCES/0090-LOKit-set-thread-name-lo_startmain.patch new file mode 100644 index 0000000..98bd50e --- /dev/null +++ b/SOURCES/0090-LOKit-set-thread-name-lo_startmain.patch @@ -0,0 +1,29 @@ +From 9d18b66a61ab8adb0ed6614a4538afa20b9e732e Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Thu, 6 Aug 2015 11:40:28 -0400 +Subject: [PATCH 090/398] LOKit: set thread name lo_startmain + +It is necessary the thread name for debugging LOKit threads. + +Change-Id: I713595eb1319234ff90a6eddebcac5ebad912b04 +(cherry picked from commit 21531da576eca7ef9cb2ee78d1643b25d5f86ae3) +--- + desktop/source/lib/init.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index aa8e27c7f48f..abd8ca0b640b 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -942,6 +942,8 @@ static bool initialize_uno(const OUString& aAppProgramURL) + + static void lo_startmain(void*) + { ++ osl_setThreadName("lo_startmain"); ++ + soffice_main(); + } + +-- +2.12.0 + diff --git a/SOURCES/0091-tdf-93154-Save-button-often-does-not-save.patch b/SOURCES/0091-tdf-93154-Save-button-often-does-not-save.patch new file mode 100644 index 0000000..5e170cd --- /dev/null +++ b/SOURCES/0091-tdf-93154-Save-button-often-does-not-save.patch @@ -0,0 +1,90 @@ +From 72189a2e2d875772e83eb7c110540f224262eec9 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Wed, 12 Aug 2015 10:32:07 +0300 +Subject: [PATCH 091/398] tdf#93154: Save button often does not save + +The problem is that in tiled rendering LO doesn't always consider the +document to be modified. Some operations such as Bold, Italic, etc do +not mark the document as being modified, but we need to be able to save +the changes. This solved the issue by always allowing to save. + +Change-Id: Iaf8120abadc768a07b24f42c287c50080b4e4d89 +Reviewed-on: https://gerrit.libreoffice.org/17665 +Reviewed-by: Jan Holesovsky +Tested-by: Jan Holesovsky +(cherry picked from commit e5ba9090f4809906ffa1c1dea352161cb988b97f) +--- + sc/source/ui/unoobj/docuno.cxx | 4 ++++ + sd/source/ui/unoidl/unomodel.cxx | 4 ++++ + sw/source/uibase/uno/unotxdoc.cxx | 4 ++++ + 3 files changed, 12 insertions(+) + +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index e1235b90cb7a..84b2857b6542 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -44,6 +44,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -839,6 +840,9 @@ void ScModelObj::initializeForTiledRendering() + aInputOptions.SetTextWysiwyg(true); + SC_MOD()->SetInputOptions(aInputOptions); + pDocShell->CalcOutputFactor(); ++ // tdf#93154: in tiled rendering LO doesn't always detect changes ++ SvtMiscOptions aMiscOpt; ++ aMiscOpt.SetSaveAlwaysAllowed(true); + } + + uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType ) +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 4148035c899a..0e88a099e081 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -60,6 +60,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -2388,6 +2389,9 @@ void SdXImpressDocument::initializeForTiledRendering() + pWindow->EnableMapMode(false); + } + } ++ // tdf#93154: in tiled rendering LO doesn't always detect changes ++ SvtMiscOptions aMiscOpt; ++ aMiscOpt.SetSaveAlwaysAllowed(true); + } + + void SdXImpressDocument::registerCallback(LibreOfficeKitCallback pCallback, void* pData) +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 0dbde54f9144..d6315d2964ae 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -136,6 +136,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -3235,6 +3236,9 @@ void SwXTextDocument::initializeForTiledRendering() + // directly in twips. + SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin(); + rEditWin.EnableMapMode(false); ++ // tdf#93154: in tiled rendering LO doesn't always detect changes ++ SvtMiscOptions aMiscOpt; ++ aMiscOpt.SetSaveAlwaysAllowed(true); + } + + void SwXTextDocument::registerCallback(LibreOfficeKitCallback pCallback, void* pData) +-- +2.12.0 + diff --git a/SOURCES/0092-sc-LOK_CALLBACK_DOCUMENT_SIZE_CHANGED-callback.patch b/SOURCES/0092-sc-LOK_CALLBACK_DOCUMENT_SIZE_CHANGED-callback.patch new file mode 100644 index 0000000..3e57f0f --- /dev/null +++ b/SOURCES/0092-sc-LOK_CALLBACK_DOCUMENT_SIZE_CHANGED-callback.patch @@ -0,0 +1,54 @@ +From d5adff883259a0f4128e6c88fe96a33aabd579c9 Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Thu, 13 Aug 2015 14:00:47 -0400 +Subject: [PATCH 092/398] sc: LOK_CALLBACK_DOCUMENT_SIZE_CHANGED callback + +Handle the LOK_CALLBACK_DOCUMENT_SIZE_CHANGED callback. + +Change-Id: I855b1e23cfc6ec66e2a0eec603e38e9dd1e28cc5 +(cherry picked from commit 8f6c7f3ca1baa6c29161cbbe41494c03b0a9d000) +--- + sc/source/ui/view/tabview5.cxx | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx +index 768c4b39d5a6..5644feaf7a2e 100644 +--- a/sc/source/ui/view/tabview5.cxx ++++ b/sc/source/ui/view/tabview5.cxx +@@ -51,7 +51,10 @@ + #include + #include + ++#include + #include ++#include ++ + + using namespace com::sun::star; + +@@ -298,6 +301,22 @@ void ScTabView::TabChanged( bool bSameTabButMoved ) + pImp->SheetChanged( bSameTabButMoved ); + } + } ++ ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ ScDocShell* pDocSh; ++ ScModelObj* pModelObj; ++ ++ if ( ( pDocSh = GetViewData().GetDocShell() ) && ++ ( pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() )) ) ++ { ++ Size aDocSize = pModelObj->getDocumentSize(); ++ std::stringstream ss; ++ ss << aDocSize.Width() << ", " << aDocSize.Height(); ++ OString sRect = ss.str().c_str(); ++ pDocSh->libreOfficeKitCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, sRect.getStr()); ++ } ++ } + } + + void ScTabView::UpdateLayerLocks() +-- +2.12.0 + diff --git a/SOURCES/0093-sc-fix-LOKit-invalidate-setPart.patch b/SOURCES/0093-sc-fix-LOKit-invalidate-setPart.patch new file mode 100644 index 0000000..0b154fe --- /dev/null +++ b/SOURCES/0093-sc-fix-LOKit-invalidate-setPart.patch @@ -0,0 +1,44 @@ +From b797ad256580c32b36f6bdce797ef67edf394dcf Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Thu, 13 Aug 2015 16:08:46 -0400 +Subject: [PATCH 093/398] sc: fix LOKit invalidate setPart + +The bindings invalidate correct tiles. + +Change-Id: Id28a7a78157030243ef1ad798daba9583746f0d3 +(cherry picked from commit 6609b05765e674f2f4694854097a5318b617fd54) +--- + sc/source/ui/unoobj/docuno.cxx | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index 84b2857b6542..1a59f887b7d7 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -496,7 +496,22 @@ void ScModelObj::paintTile( VirtualDevice& rDevice, + void ScModelObj::setPart( int nPart ) + { + ScViewData* pViewData = ScDocShell::GetViewData(); +- pViewData->SetTabNo( nPart ); ++ SfxUInt16Item aItem( SID_CURRENTTAB, nPart + 1 ); ++ SfxDispatcher& rDisp = pViewData->GetDispatcher(); ++ ++ rDisp.Execute( SID_CURRENTTAB, SfxCallMode::SLOT | SfxCallMode::RECORD, &aItem, nullptr ); ++ ++ SfxBindings& rBind = pViewData->GetBindings(); ++ rBind.Invalidate( FID_FILL_TAB ); ++ rBind.Invalidate( FID_TAB_DESELECTALL ); ++ rBind.Invalidate( FID_INS_TABLE ); ++ rBind.Invalidate( FID_TAB_APPEND ); ++ rBind.Invalidate( FID_TAB_MOVE ); ++ rBind.Invalidate( FID_TAB_RENAME ); ++ rBind.Invalidate( FID_DELETE_TABLE ); ++ rBind.Invalidate( FID_TABLE_SHOW ); ++ rBind.Invalidate( FID_TABLE_HIDE ); ++ rBind.Invalidate( FID_TAB_SET_TAB_BG_COLOR ); + } + + int ScModelObj::getParts() +-- +2.12.0 + diff --git a/SOURCES/0094-gtktiledviewer-Jump-to-cursor-position-when-it-chang.patch b/SOURCES/0094-gtktiledviewer-Jump-to-cursor-position-when-it-chang.patch new file mode 100644 index 0000000..7c63b9f --- /dev/null +++ b/SOURCES/0094-gtktiledviewer-Jump-to-cursor-position-when-it-chang.patch @@ -0,0 +1,183 @@ +From 35bc0137636c6d1c537188b909d173e523786ff9 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 15 Aug 2015 18:48:11 +0530 +Subject: [PATCH 094/398] gtktiledviewer: Jump to cursor position when it + changes + +Change-Id: If50ac0bd21e59b0e0639aa353513451e88ae2a9f +(cherry picked from commit a9b266aeea80423210618fe4c015e4791ceb1bc2) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 85 +++++++++++++++++----- + libreofficekit/source/gtk/lokdocview.cxx | 25 +++++++ + 2 files changed, 93 insertions(+), 17 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 3399087cb6db..57d0c113d6ac 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -57,6 +57,25 @@ static void lcl_registerToolItem(GtkToolItem* pItem, const std::string& rName) + + const float fZooms[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 5.0 }; + ++ ++/// Get the visible area of the scrolled window ++static void getVisibleAreaTwips(GdkRectangle* pArea) ++{ ++#if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() ++ GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ ++ pArea->x = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_value(pHAdjustment)); ++ pArea->y = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_value(pVAdjustment)); ++ pArea->width = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_page_size(pHAdjustment)); ++ pArea->height = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), ++ gtk_adjustment_get_page_size(pVAdjustment)); ++#endif ++} ++ + static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + { + const char *sName = gtk_tool_button_get_icon_name( GTK_TOOL_BUTTON(pButton) ); +@@ -174,23 +193,6 @@ static void doCopy(GtkWidget* /*pButton*/, gpointer /*pItem*/) + free(pSelection); + } + +-/// Get the visible area of the scrolled window +-static void getVisibleAreaTwips(GdkRectangle* pArea) +-{ +-#if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() +- GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); +- GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); +- +- pArea->x = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), +- gtk_adjustment_get_value(pHAdjustment)); +- pArea->y = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), +- gtk_adjustment_get_value(pVAdjustment)); +- pArea->width = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), +- gtk_adjustment_get_page_size(pHAdjustment)); +- pArea->height = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), +- gtk_adjustment_get_page_size(pVAdjustment)); +-#endif +-} + + /// Searches for the next or previous text of pFindbarEntry. + static void doSearch(bool bBackwards) +@@ -318,6 +320,54 @@ static void signalHyperlink(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointe + } + } + ++/// Cursor position changed ++static void cursorChanged(LOKDocView* /*pDocView*/, gint nX, gint nY, ++ gint /*nWidth*/, gint /*nHeight*/, gpointer /*pData*/) ++{ ++ GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ GdkRectangle visArea; ++ gdouble upper; ++ gint x = -1, y = -1; ++ ++ getVisibleAreaTwips(&visArea); ++ ++ // check vertically ++ if (nY < visArea.y) ++ { ++ y = nY - visArea.height/2; ++ if (y < 0) ++ y = gtk_adjustment_get_lower(vadj); ++ } ++ else if (nY > visArea.y + visArea.height) ++ { ++ y = nY - visArea.height/2; ++ upper = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), gtk_adjustment_get_upper(vadj)); ++ if (y > upper) ++ y = upper; ++ ++ } ++ ++ if (nX < visArea.x) ++ { ++ x = nX - visArea.width/2; ++ if (x < 0) ++ x = gtk_adjustment_get_lower(hadj); ++ } ++ else if (nX > visArea.x + visArea.width) ++ { ++ x = nX - visArea.width/2; ++ upper = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), gtk_adjustment_get_upper(hadj)); ++ if (x > upper) ++ x = upper; ++ } ++ ++ if (y!=-1) ++ gtk_adjustment_set_value(vadj, lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), y)); ++ if (x!=-1) ++ gtk_adjustment_set_value(hadj, lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), x)); ++} ++ + static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + { + if (g_bToolItemBroadcast) +@@ -575,6 +625,7 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); + g_signal_connect(pDocView, "size-changed", G_CALLBACK(signalSize), NULL); + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); ++ g_signal_connect(pDocView, "cursor-changed", G_CALLBACK(cursorChanged), NULL); + + + // Scrolled window for DocView +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 364590167f56..859e96b29e20 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -117,6 +117,7 @@ enum + PART_CHANGED, + SIZE_CHANGED, + HYPERLINK_CLICKED, ++ CURSOR_CHANGED, + + LAST_SIGNAL + }; +@@ -518,6 +519,11 @@ callback (gpointer pData) + { + priv->m_aVisibleCursor = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); + priv->m_bCursorOverlayVisible = true; ++ g_signal_emit(pDocView, doc_view_signals[CURSOR_CHANGED], 0, ++ priv->m_aVisibleCursor.x, ++ priv->m_aVisibleCursor.y, ++ priv->m_aVisibleCursor.width, ++ priv->m_aVisibleCursor.height); + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + break; +@@ -1743,6 +1749,25 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); ++ ++ /** ++ * LOKDocView::cursor-changed: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @nX: The new cursor position (X coordinate) in pixels ++ * @nY: The new cursor position (Y coordinate) in pixels ++ * @nWidth: The width of new cursor ++ * @nHeight: The height of new cursor ++ */ ++ doc_view_signals[CURSOR_CHANGED] = ++ g_signal_new("cursor-changed", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, NULL, ++ g_cclosure_marshal_generic, ++ G_TYPE_NONE, 4, ++ G_TYPE_INT, G_TYPE_INT, ++ G_TYPE_INT, G_TYPE_INT); + } + + /** +-- +2.12.0 + diff --git a/SOURCES/0095-lok-Document-getStyles-method.patch b/SOURCES/0095-lok-Document-getStyles-method.patch new file mode 100644 index 0000000..b3b3115 --- /dev/null +++ b/SOURCES/0095-lok-Document-getStyles-method.patch @@ -0,0 +1,192 @@ +From 642f6386a1a73c13ed3997f54a737385e8894992 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Mon, 17 Aug 2015 18:49:40 +0300 +Subject: [PATCH 095/398] lok::Document getStyles method + +This method returns a JSON mapping of style families to a list of styles +from the corresponding family. +Will be used to know and apply styles in tiledrendering. + +Change-Id: I0aa395c40b9573920ade44255f97c077475ae5f1 +(cherry picked from commit c5a516bd1bf0216ee39f31322369f6bffdf464eb) +--- + desktop/source/lib/init.cxx | 34 ++++++++++++++++++++++++++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 3 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 8 +++++++ + libreofficekit/qa/unit/tiledrendering.cxx | 35 +++++++++++++++++++++++++++++++ + 4 files changed, 80 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index abd8ca0b640b..51302d1f8466 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -35,11 +35,13 @@ + #include + + #include ++#include + #include + #include + #include + #include + #include ++#include + #include + #include + +@@ -233,6 +235,7 @@ static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + int nX, + int nY); + static void doc_resetSelection (LibreOfficeKitDocument* pThis); ++static char* doc_getStyles(LibreOfficeKitDocument* pThis); + + struct LibLODocument_Impl : public _LibreOfficeKitDocument + { +@@ -267,6 +270,7 @@ struct LibLODocument_Impl : public _LibreOfficeKitDocument + m_pDocumentClass->getTextSelection = doc_getTextSelection; + m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection; + m_pDocumentClass->resetSelection = doc_resetSelection; ++ m_pDocumentClass->getStyles = doc_getStyles; + + gDocumentClass = m_pDocumentClass; + } +@@ -864,6 +868,36 @@ static void doc_resetSelection(LibreOfficeKitDocument* pThis) + pDoc->resetSelection(); + } + ++static char* doc_getStyles(LibreOfficeKitDocument* pThis) ++{ ++ LibLODocument_Impl* pDocument = static_cast(pThis); ++ ++ boost::property_tree::ptree aTree; ++ uno::Reference xStyleFamiliesSupplier(pDocument->mxComponent, uno::UNO_QUERY); ++ uno::Reference xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); ++ uno::Sequence aStyleFamilies = xStyleFamilies->getElementNames(); ++ ++ for (sal_Int32 nStyleFam = 0; nStyleFam < aStyleFamilies.getLength(); ++nStyleFam) ++ { ++ boost::property_tree::ptree aChildren; ++ OUString sStyleFam = aStyleFamilies[nStyleFam]; ++ uno::Reference xStyleFamily(xStyleFamilies->getByName(sStyleFam), uno::UNO_QUERY); ++ uno::Sequence aStyles = xStyleFamily->getElementNames(); ++ for (sal_Int32 nInd = 0; nInd < aStyles.getLength(); ++nInd) ++ { ++ boost::property_tree::ptree aChild; ++ aChild.put("", aStyles[nInd]); ++ aChildren.push_back(std::make_pair("", aChild)); ++ } ++ aTree.add_child(sStyleFam.toUtf8().getStr(), aChildren); ++ } ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ char* pJson = static_cast(malloc(aStream.str().size() + 1)); ++ strcpy(pJson, aStream.str().c_str()); ++ pJson[aStream.str().size()] = '\0'; ++ return pJson; ++} + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index e3b485052444..af7155c4db67 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -159,6 +159,9 @@ struct _LibreOfficeKitDocumentClass + + /// @see lok::Document::resetSelection + void (*resetSelection) (LibreOfficeKitDocument* pThis); ++ ++ /// @see lok::Document:getStyles ++ char* (*getStyles) (LibreOfficeKitDocument* pThis); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 816ade5649b2..c526bda95593 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -246,6 +246,14 @@ public: + { + mpDoc->pClass->resetSelection(mpDoc); + } ++ ++ /** ++ * Returns a json map, {"familyName1" : ["list of style names in the family1"], etc.} ++ */ ++ inline char* getStyles() ++ { ++ return mpDoc->pClass->getStyles(mpDoc); ++ } + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/libreofficekit/qa/unit/tiledrendering.cxx b/libreofficekit/qa/unit/tiledrendering.cxx +index fb2f7416ba34..a0f4bcb5b8eb 100644 +--- a/libreofficekit/qa/unit/tiledrendering.cxx ++++ b/libreofficekit/qa/unit/tiledrendering.cxx +@@ -9,6 +9,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -67,6 +68,7 @@ public: + void testDocumentTypes( Office* pOffice ); + void testImpressSlideNames( Office* pOffice ); + void testCalcSheetNames( Office* pOffice ); ++ void testGetStyles( Office* pOffice ); + #if 0 + void testOverlay( Office* pOffice ); + #endif +@@ -93,6 +95,7 @@ void TiledRenderingTest::runAllTests() + testDocumentTypes( pOffice.get() ); + testImpressSlideNames( pOffice.get() ); + testCalcSheetNames( pOffice.get() ); ++ testGetStyles( pOffice.get() ); + #if 0 + testOverlay( pOffice.get() ); + #endif +@@ -181,6 +184,38 @@ void TiledRenderingTest::testCalcSheetNames( Office* pOffice ) + CPPUNIT_ASSERT( strcmp( pDocument->getPartName( 2 ), "Sheet3" ) == 0 ); + } + ++void TiledRenderingTest::testGetStyles( Office* pOffice ) ++{ ++ const string sDocPath = m_sSrcRoot + "/libreofficekit/qa/data/blank_text.odt"; ++ const string sLockFile = m_sSrcRoot +"/libreofficekit/qa/data/.~lock.blank_text.odt#"; ++ ++ // FIXME: LOK will fail when trying to open a locked file ++ remove( sLockFile.c_str() ); ++ ++ scoped_ptr< Document> pDocument( pOffice->documentLoad( sDocPath.c_str() ) ); ++ ++ boost::property_tree::ptree aTree; ++ char* pJSON = pDocument->getStyles(); ++ std::stringstream aStream(pJSON); ++ boost::property_tree::read_json(aStream, aTree); ++ CPPUNIT_ASSERT( aTree.size() > 0 ); ++ ++ for (const std::pair& rPair : aTree) ++ { ++ CPPUNIT_ASSERT( rPair.second.size() > 0); ++ if (rPair.first != "CharacterStyles" && ++ rPair.first != "ParagraphStyles" && ++ rPair.first != "FrameStyles" && ++ rPair.first != "PageStyles" && ++ rPair.first != "NumberingStyles" && ++ rPair.first != "CellStyles" && ++ rPair.first != "ShapeStyles") ++ { ++ CPPUNIT_FAIL("Unknown style family: " + rPair.first); ++ } ++ } ++} ++ + #if 0 + static void dumpRGBABitmap( const OUString& rPath, const unsigned char* pBuffer, + const int nWidth, const int nHeight ) +-- +2.12.0 + diff --git a/SOURCES/0096-lok-namespace-and-re-work-various-types-helper-funct.patch b/SOURCES/0096-lok-namespace-and-re-work-various-types-helper-funct.patch new file mode 100644 index 0000000..6105dd7 --- /dev/null +++ b/SOURCES/0096-lok-namespace-and-re-work-various-types-helper-funct.patch @@ -0,0 +1,179 @@ +From c8a7b2b66db5025526a0dba1b0d33dcf1b93f985 Mon Sep 17 00:00:00 2001 +From: Michael Meeks +Date: Tue, 18 Aug 2015 12:09:08 +0100 +Subject: [PATCH 096/398] lok: namespace and re-work various types & helper + functions. + +Change-Id: I36e2a01822883251f9556fcde0e0a9830356ac98 +Reviewed-on: https://gerrit.libreoffice.org/17833 +Tested-by: Jenkins +Reviewed-by: Michael Meeks +Tested-by: Michael Meeks +(cherry picked from commit a5d5ce5dfa0f0cdd048192d60c70da575a6f1735) +--- + include/LibreOfficeKit/LibreOfficeKitInit.h | 60 ++++++++++++++++++----------- + 1 file changed, 37 insertions(+), 23 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitInit.h b/include/LibreOfficeKit/LibreOfficeKitInit.h +index f1966c764605..c2f342661e31 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitInit.h ++++ b/include/LibreOfficeKit/LibreOfficeKitInit.h +@@ -40,7 +40,7 @@ extern "C" + #endif + #define SEPARATOR '/' + +- void *_dlopen(const char *pFN) ++ void *lok_loadlib(const char *pFN) + { + return dlopen(pFN, RTLD_LAZY + #if defined __clang__ && defined __linux__ \ +@@ -52,17 +52,17 @@ extern "C" + ); + } + +- char *_dlerror(void) ++ char *lok_dlerror(void) + { + return dlerror(); + } + +- void *_dlsym(void *Hnd, const char *pName) ++ void *lok_dlsym(void *Hnd, const char *pName) + { + return dlsym(Hnd, pName); + } + +- int _dlclose(void *Hnd) ++ int lok_dlclose(void *Hnd) + { + return dlclose(Hnd); + } +@@ -80,24 +80,24 @@ extern "C" + #define SEPARATOR '\\' + #define UNOPATH "\\..\\URE\\bin" + +- void *_dlopen(const char *pFN) ++ void *lok_loadlib(const char *pFN) + { + return (void *) LoadLibrary(pFN); + } + +- char *_dlerror(void) ++ char *lok_dlerror(void) + { + LPSTR buf = NULL; + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, reinterpret_cast(&buf), 0, NULL); + return buf; + } + +- void *_dlsym(void *Hnd, const char *pName) ++ void *lok_dlsym(void *Hnd, const char *pName) + { + return GetProcAddress((HINSTANCE) Hnd, pName); + } + +- int _dlclose(void *Hnd) ++ int lok_dlclose(void *Hnd) + { + return FreeLibrary((HINSTANCE) Hnd); + } +@@ -139,16 +139,12 @@ extern "C" + } + #endif + +-typedef LibreOfficeKit *(HookFunction)( const char *install_path); +- +-typedef LibreOfficeKit *(HookFunction2)( const char *install_path, const char *user_profile_path ); +- +-static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_profile_path ) ++static void *lok_dlopen( const char *install_path, char ** _imp_lib ) + { + char *imp_lib; + void *dlhandle; +- HookFunction *pSym; +- HookFunction2 *pSym2; ++ ++ *_imp_lib = NULL; + + #if !(defined(__APPLE__) && defined(__arm__)) + size_t partial_length; +@@ -172,7 +168,7 @@ static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_p + imp_lib[partial_length++] = SEPARATOR; + strcpy(imp_lib + partial_length, TARGET_LIB); + +- dlhandle = _dlopen(imp_lib); ++ dlhandle = lok_loadlib(imp_lib); + if (!dlhandle) + { + // If TARGET_LIB exists, and likely is a real library (not a +@@ -183,18 +179,18 @@ static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_p + if (stat(imp_lib, &st) == 0 && st.st_size > 100) + { + fprintf(stderr, "failed to open library '%s': %s\n", +- imp_lib, _dlerror()); ++ imp_lib, lok_dlerror()); + free(imp_lib); + return NULL; + } + + strcpy(imp_lib + partial_length, TARGET_MERGED_LIB); + +- dlhandle = _dlopen(imp_lib); ++ dlhandle = lok_loadlib(imp_lib); + if (!dlhandle) + { + fprintf(stderr, "failed to open library '%s': %s\n", +- imp_lib, _dlerror()); ++ imp_lib, lok_dlerror()); + free(imp_lib); + return NULL; + } +@@ -203,23 +199,41 @@ static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_p + imp_lib = strdup("the app executable"); + dlhandle = RTLD_MAIN_ONLY; + #endif ++ *_imp_lib = imp_lib; ++ return dlhandle; ++} ++ ++typedef LibreOfficeKit *(LokHookFunction)( const char *install_path); ++ ++typedef LibreOfficeKit *(LokHookFunction2)( const char *install_path, const char *user_profile_path ); ++ ++typedef int (LokHookPreInit) ( const char *install_path, const char *user_profile_path ); ++ ++static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_profile_path ) ++{ ++ char *imp_lib; ++ void *dlhandle; ++ LokHookFunction *pSym; ++ LokHookFunction2 *pSym2; ++ ++ dlhandle = lok_dlopen(install_path, &imp_lib); + +- pSym2 = (HookFunction2 *) _dlsym( dlhandle, "libreofficekit_hook_2" ); ++ pSym2 = (LokHookFunction2 *) lok_dlsym(dlhandle, "libreofficekit_hook_2"); + if (!pSym2) + { + if (user_profile_path != NULL) + { + fprintf( stderr, "the LibreOffice version in '%s' does not support passing a user profile to the hook function\n", + imp_lib ); +- _dlclose( dlhandle ); ++ lok_dlclose( dlhandle ); + free( imp_lib ); + return NULL; + } +- pSym = (HookFunction *) _dlsym( dlhandle, "libreofficekit_hook" ); ++ pSym = (LokHookFunction *) lok_dlsym( dlhandle, "libreofficekit_hook" ); + if (!pSym) + { + fprintf( stderr, "failed to find hook in library '%s'\n", imp_lib ); +- _dlclose( dlhandle ); ++ lok_dlclose( dlhandle ); + free( imp_lib ); + return NULL; + } +-- +2.12.0 + diff --git a/SOURCES/0097-Fix-incomplete-g-i-annotations.patch b/SOURCES/0097-Fix-incomplete-g-i-annotations.patch new file mode 100644 index 0000000..941b77e --- /dev/null +++ b/SOURCES/0097-Fix-incomplete-g-i-annotations.patch @@ -0,0 +1,30 @@ +From 00299a202f0a83fb9ed9d0d381cf5213c8fee42d Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 16 Aug 2015 15:17:15 +0530 +Subject: [PATCH 097/398] Fix incomplete g-i annotations + +Change-Id: I2665a12251921523045f4071df88ca69ecd5a5c0 +(cherry picked from commit 520053459aa6a34b6d9ad52d97704399e5138d3d) +--- + libreofficekit/source/gtk/lokdocview.cxx | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 859e96b29e20..83bb8b5e0aa5 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1810,7 +1810,10 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr + /** + * lok_doc_view_open_document: + * @pDocView: The #LOKDocView instance +- * @pPath: The path of the document that #LOKDocView widget should try to open ++ * @pPath: (transfer full): The path of the document that #LOKDocView widget should try to open ++ * @cancellable: ++ * @callback: ++ * @userdata: + * + * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise + */ +-- +2.12.0 + diff --git a/SOURCES/0098-log-resource-usage-of-unit-tests-on-UNX-platforms.patch b/SOURCES/0098-log-resource-usage-of-unit-tests-on-UNX-platforms.patch new file mode 100644 index 0000000..ffa4413 --- /dev/null +++ b/SOURCES/0098-log-resource-usage-of-unit-tests-on-UNX-platforms.patch @@ -0,0 +1,118 @@ +From a105e5ba1e92f91b34e7f25cc4b307900248881a Mon Sep 17 00:00:00 2001 +From: Markus Mohrhard +Date: Mon, 31 Aug 2015 01:36:02 +0200 +Subject: [PATCH 098/398] log resource usage of unit tests on UNX platforms + +Change-Id: I3788eae60f73bc42488bf2e4961922962f7e505b +Reviewed-on: https://gerrit.libreoffice.org/18155 +Reviewed-by: Markus Mohrhard +Tested-by: Markus Mohrhard +(cherry picked from commit 87514b0907dfbb479e2646b5ff951c68babf3417) +--- + sal/cppunittester/cppunittester.cxx | 50 +++++++++++++++++++++++++++++++++++++ + solenv/gbuild/CppunitTest.mk | 2 +- + 2 files changed, 51 insertions(+), 1 deletion(-) + +diff --git a/sal/cppunittester/cppunittester.cxx b/sal/cppunittester/cppunittester.cxx +index b637fb62cb2d..ef9212d6a2fa 100644 +--- a/sal/cppunittester/cppunittester.cxx ++++ b/sal/cppunittester/cppunittester.cxx +@@ -21,6 +21,11 @@ + #include + #endif + ++#ifdef UNX ++#include ++#include ++#endif ++ + #include + #include + #include +@@ -292,11 +297,48 @@ public: + } + }; + ++#ifdef UNX ++ ++double get_time(timeval* time) ++{ ++ double nTime = (double)time->tv_sec; ++ nTime += ((double)time->tv_usec)/1000000.0; ++ return nTime; ++} ++ ++OString generateTestName(const OUString& rPath) ++{ ++ sal_Int32 nPathSep = rPath.lastIndexOf("/"); ++ OUString aTestName = rPath.copy(nPathSep+1); ++ return OUStringToOString(aTestName, RTL_TEXTENCODING_UTF8); ++} ++ ++void reportResourceUsage(const OUString& rPath) ++{ ++ OUString aFullPath = rPath + OUString(".resource.log"); ++ rusage resource_usage; ++ getrusage(RUSAGE_SELF, &resource_usage); ++ ++ OString aPath = OUStringToOString(aFullPath, RTL_TEXTENCODING_UTF8); ++ std::ofstream resource_file(aPath.getStr()); ++ resource_file << "Name = " << generateTestName(rPath) << std::endl; ++ double nUserSpace = get_time(&resource_usage.ru_utime); ++ double nKernelSpace = get_time(&resource_usage.ru_stime); ++ resource_file << "UserSpace = " << nUserSpace << std::endl; ++ resource_file << "KernelSpace = " << nKernelSpace << std::endl; ++} ++#else ++void reportResourceUsage(const OUString& /*rPath*/) ++{ ++} ++#endif ++ + } + + SAL_IMPLEMENT_MAIN() + { + bool ok = false; ++ OUString path; + try + { + #ifdef WNT +@@ -322,6 +364,12 @@ SAL_IMPLEMENT_MAIN() + while (index < rtl_getAppCommandArgCount()) + { + rtl::OUString arg = getArgument(index); ++ if (arg == "--target") ++ { ++ path = getArgument(++index); ++ ++index; ++ continue; ++ } + if ( arg != "--protector" ) + { + if (testlib.empty()) +@@ -383,6 +431,8 @@ SAL_IMPLEMENT_MAIN() + SAL_WARN("vcl.app", "Fatal exception: " << e.what()); + } + ++ reportResourceUsage(path); ++ + return ok ? EXIT_SUCCESS : EXIT_FAILURE; + } + +diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk +index 021ecc8c37aa..944a87ab612d 100644 +--- a/solenv/gbuild/CppunitTest.mk ++++ b/solenv/gbuild/CppunitTest.mk +@@ -101,7 +101,7 @@ $(call gb_CppunitTest_get_target,%) :| $(gb_CppunitTest_RUNTIMEDEPS) + PYTHONDONTWRITEBYTECODE=1) \ + $(ICECREAM_RUN) $(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_CppunitTest_CPPTESTCOMMAND) \ + $(call gb_LinkTarget_get_target,$(call gb_CppunitTest_get_linktarget,$*)) \ +- $(call gb_CppunitTest__make_args) \ ++ $(call gb_CppunitTest__make_args) --target $@ \ + $(if $(gb_CppunitTest__interactive),, \ + > $@.log 2>&1 \ + || ($(if $(value gb_CppunitTest_postprocess), \ +-- +2.12.0 + diff --git a/SOURCES/0099-sal-don-t-use-target-as-parameter-to-cppunittester.patch b/SOURCES/0099-sal-don-t-use-target-as-parameter-to-cppunittester.patch new file mode 100644 index 0000000..377a803 --- /dev/null +++ b/SOURCES/0099-sal-don-t-use-target-as-parameter-to-cppunittester.patch @@ -0,0 +1,72 @@ +From 929bef368a34b4df91ff6595de9cb3304ef02c99 Mon Sep 17 00:00:00 2001 +From: Michael Stahl +Date: Mon, 31 Aug 2015 23:09:16 +0200 +Subject: [PATCH 099/398] sal: don't use --target as parameter to cppunittester + +CppunitTest_libreofficekit_tiledrendering hangs because the soffice_main +exits due to the unrecognized command line arg --target. + +Use a -env:VARIABLE argument instead, which is filtered out by +rtl_getAppCommandArg() so does not reach the soffice_main code. + +(regression from 87514b0907dfbb479e2646b5ff951c68babf3417) + +Change-Id: I2c801305398dccfb447e4e5c44726f42bf2a72ef +(cherry picked from commit d0ebb6e438dc8f7dcb5467ae6f72068cf40dcb7a) +--- + sal/cppunittester/cppunittester.cxx | 12 ++++++++---- + solenv/gbuild/CppunitTest.mk | 2 +- + 2 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/sal/cppunittester/cppunittester.cxx b/sal/cppunittester/cppunittester.cxx +index ef9212d6a2fa..f2f36af51134 100644 +--- a/sal/cppunittester/cppunittester.cxx ++++ b/sal/cppunittester/cppunittester.cxx +@@ -361,15 +361,19 @@ SAL_IMPLEMENT_MAIN() + std::string args; + std::string testlib; + sal_uInt32 index = 0; +- while (index < rtl_getAppCommandArgCount()) ++ while (index < osl_getCommandArgCount()) + { + rtl::OUString arg = getArgument(index); +- if (arg == "--target") ++ if (arg.startsWith("-env:CPPUNITTESTTARGET=", &path)) + { +- path = getArgument(++index); + ++index; + continue; + } ++ if (arg.startsWith("-env:")) ++ { ++ ++index; ++ continue; // ignore it here - will be read later ++ } + if ( arg != "--protector" ) + { + if (testlib.empty()) +@@ -385,7 +389,7 @@ SAL_IMPLEMENT_MAIN() + ++index; + continue; + } +- if (rtl_getAppCommandArgCount() - index < 3) { ++ if (osl_getCommandArgCount() - index < 3) { + usageFailure(); + } + rtl::OUString lib(getArgument(index + 1)); +diff --git a/solenv/gbuild/CppunitTest.mk b/solenv/gbuild/CppunitTest.mk +index 944a87ab612d..bbd7370b655d 100644 +--- a/solenv/gbuild/CppunitTest.mk ++++ b/solenv/gbuild/CppunitTest.mk +@@ -101,7 +101,7 @@ $(call gb_CppunitTest_get_target,%) :| $(gb_CppunitTest_RUNTIMEDEPS) + PYTHONDONTWRITEBYTECODE=1) \ + $(ICECREAM_RUN) $(gb_CppunitTest_GDBTRACE) $(gb_CppunitTest_VALGRINDTOOL) $(gb_CppunitTest_CPPTESTCOMMAND) \ + $(call gb_LinkTarget_get_target,$(call gb_CppunitTest_get_linktarget,$*)) \ +- $(call gb_CppunitTest__make_args) --target $@ \ ++ $(call gb_CppunitTest__make_args) "-env:CPPUNITTESTTARGET=$@" \ + $(if $(gb_CppunitTest__interactive),, \ + > $@.log 2>&1 \ + || ($(if $(value gb_CppunitTest_postprocess), \ +-- +2.12.0 + diff --git a/SOURCES/0100-LOK-added-a-general-getCommandValues-method.patch b/SOURCES/0100-LOK-added-a-general-getCommandValues-method.patch new file mode 100644 index 0000000..66fce55 --- /dev/null +++ b/SOURCES/0100-LOK-added-a-general-getCommandValues-method.patch @@ -0,0 +1,153 @@ +From e25532e14fae9a909d62c354ed93c581522f4683 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Fri, 4 Sep 2015 10:27:58 +0300 +Subject: [PATCH 100/398] LOK: added a general getCommandValues method + +This method returns a JSON mapping of the posible values for the given +command (e.g. .uno:StyleApply, etc). + +returns: +{commandName: "cmdName", commandValues: {json_of_cmd_values}} + +Change-Id: Ic8f970d077af6be9bc226f72f725b6cdf2d4c160 +(cherry picked from commit 9640dcea46dd3201aa4c27f6a3918f7419288a2a) +--- + desktop/source/lib/init.cxx | 24 ++++++++++++++++++++---- + include/LibreOfficeKit/LibreOfficeKit.h | 2 +- + include/LibreOfficeKit/LibreOfficeKit.hxx | 9 ++++++--- + libreofficekit/qa/unit/tiledrendering.cxx | 8 ++++++-- + 4 files changed, 33 insertions(+), 10 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 51302d1f8466..44a9e197d77a 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -235,7 +235,7 @@ static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + int nX, + int nY); + static void doc_resetSelection (LibreOfficeKitDocument* pThis); +-static char* doc_getStyles(LibreOfficeKitDocument* pThis); ++static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand); + + struct LibLODocument_Impl : public _LibreOfficeKitDocument + { +@@ -270,7 +270,7 @@ struct LibLODocument_Impl : public _LibreOfficeKitDocument + m_pDocumentClass->getTextSelection = doc_getTextSelection; + m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection; + m_pDocumentClass->resetSelection = doc_resetSelection; +- m_pDocumentClass->getStyles = doc_getStyles; ++ m_pDocumentClass->getCommandValues = doc_getCommandValues; + + gDocumentClass = m_pDocumentClass; + } +@@ -868,15 +868,17 @@ static void doc_resetSelection(LibreOfficeKitDocument* pThis) + pDoc->resetSelection(); + } + +-static char* doc_getStyles(LibreOfficeKitDocument* pThis) ++static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + { + LibLODocument_Impl* pDocument = static_cast(pThis); + + boost::property_tree::ptree aTree; ++ aTree.put("commandName", pCommand); + uno::Reference xStyleFamiliesSupplier(pDocument->mxComponent, uno::UNO_QUERY); + uno::Reference xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); + uno::Sequence aStyleFamilies = xStyleFamilies->getElementNames(); + ++ boost::property_tree::ptree aValues; + for (sal_Int32 nStyleFam = 0; nStyleFam < aStyleFamilies.getLength(); ++nStyleFam) + { + boost::property_tree::ptree aChildren; +@@ -889,8 +891,9 @@ static char* doc_getStyles(LibreOfficeKitDocument* pThis) + aChild.put("", aStyles[nInd]); + aChildren.push_back(std::make_pair("", aChild)); + } +- aTree.add_child(sStyleFam.toUtf8().getStr(), aChildren); ++ aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren); + } ++ aTree.add_child("commandValues", aValues); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + char* pJson = static_cast(malloc(aStream.str().size() + 1)); +@@ -898,6 +901,19 @@ static char* doc_getStyles(LibreOfficeKitDocument* pThis) + pJson[aStream.str().size()] = '\0'; + return pJson; + } ++ ++static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand) ++{ ++ if (!strcmp(pCommand, ".uno:StyleApply")) ++ { ++ return getStyles(pThis, pCommand); ++ } ++ else { ++ gImpl->maLastExceptionMsg = "Unknown command, no values returned"; ++ return NULL; ++ } ++} ++ + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index af7155c4db67..8060f0e6ec7c 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -161,7 +161,7 @@ struct _LibreOfficeKitDocumentClass + void (*resetSelection) (LibreOfficeKitDocument* pThis); + + /// @see lok::Document:getStyles +- char* (*getStyles) (LibreOfficeKitDocument* pThis); ++ char* (*getCommandValues) (LibreOfficeKitDocument* pThis, const char* pCommand); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index c526bda95593..44599948e659 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -248,11 +248,14 @@ public: + } + + /** +- * Returns a json map, {"familyName1" : ["list of style names in the family1"], etc.} ++ * Returns a json mapping of the possible values for the given command ++ * e.g. {commandName: ".uno:StyleApply", commandValues: {"familyName1" : ["list of style names in the family1"], etc.}} ++ * @param pCommand a uno command for which the possible values are requested ++ * @return {commandName: unoCmd, commandValues: {possible_values}} + */ +- inline char* getStyles() ++ inline char* getCommandValues(const char* pCommand) + { +- return mpDoc->pClass->getStyles(mpDoc); ++ return mpDoc->pClass->getCommandValues(mpDoc, pCommand); + } + #endif // LOK_USE_UNSTABLE_API + }; +diff --git a/libreofficekit/qa/unit/tiledrendering.cxx b/libreofficekit/qa/unit/tiledrendering.cxx +index a0f4bcb5b8eb..f4a721b3e164 100644 +--- a/libreofficekit/qa/unit/tiledrendering.cxx ++++ b/libreofficekit/qa/unit/tiledrendering.cxx +@@ -195,12 +195,16 @@ void TiledRenderingTest::testGetStyles( Office* pOffice ) + scoped_ptr< Document> pDocument( pOffice->documentLoad( sDocPath.c_str() ) ); + + boost::property_tree::ptree aTree; +- char* pJSON = pDocument->getStyles(); ++ char* pJSON = pDocument->getCommandValues(".uno:StyleApply"); + std::stringstream aStream(pJSON); + boost::property_tree::read_json(aStream, aTree); + CPPUNIT_ASSERT( aTree.size() > 0 ); ++ CPPUNIT_ASSERT( aTree.get_value("commandName") == ".uno:StyleApply" ); + +- for (const std::pair& rPair : aTree) ++ ++ boost::property_tree::ptree aValues = aTree.get_child("commandValues"); ++ CPPUNIT_ASSERT( aValues.size() > 0 ); ++ for (const std::pair& rPair : aValues) + { + CPPUNIT_ASSERT( rPair.second.size() > 0); + if (rPair.first != "CharacterStyles" && +-- +2.12.0 + diff --git a/SOURCES/0101-LOK-allow-float-numbers-in-json-property-value-conve.patch b/SOURCES/0101-LOK-allow-float-numbers-in-json-property-value-conve.patch new file mode 100644 index 0000000..f2bbef0 --- /dev/null +++ b/SOURCES/0101-LOK-allow-float-numbers-in-json-property-value-conve.patch @@ -0,0 +1,28 @@ +From fd8569e37467bf1d1bdc7fb3a680b1ef793cd598 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Fri, 4 Sep 2015 11:55:47 +0300 +Subject: [PATCH 101/398] LOK: allow float numbers in json -> property value + conversion + +Change-Id: I866a44fcb71044d27a9bf06e2f55ca2e4135c23b +(cherry picked from commit d3c93279667badf0c0feb927e9c46af97a538d84) +--- + desktop/source/lib/init.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 44a9e197d77a..f15417c92d0b 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -772,6 +772,8 @@ static void jsonToPropertyValues(const char* pJSON, uno::Sequence +Date: Fri, 4 Sep 2015 15:45:51 +0300 +Subject: [PATCH 102/398] Revert "LOK: added a general getCommandValues method" + +This reverts commit 9640dcea46dd3201aa4c27f6a3918f7419288a2a. + +(cherry picked from commit 262e7be01461887202f629d1ccc57751b1a085c5) +--- + desktop/source/lib/init.cxx | 24 ++++-------------------- + include/LibreOfficeKit/LibreOfficeKit.h | 2 +- + include/LibreOfficeKit/LibreOfficeKit.hxx | 9 +++------ + libreofficekit/qa/unit/tiledrendering.cxx | 8 ++------ + 4 files changed, 10 insertions(+), 33 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index f15417c92d0b..c7f3aabb58b7 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -235,7 +235,7 @@ static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + int nX, + int nY); + static void doc_resetSelection (LibreOfficeKitDocument* pThis); +-static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand); ++static char* doc_getStyles(LibreOfficeKitDocument* pThis); + + struct LibLODocument_Impl : public _LibreOfficeKitDocument + { +@@ -270,7 +270,7 @@ struct LibLODocument_Impl : public _LibreOfficeKitDocument + m_pDocumentClass->getTextSelection = doc_getTextSelection; + m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection; + m_pDocumentClass->resetSelection = doc_resetSelection; +- m_pDocumentClass->getCommandValues = doc_getCommandValues; ++ m_pDocumentClass->getStyles = doc_getStyles; + + gDocumentClass = m_pDocumentClass; + } +@@ -870,17 +870,15 @@ static void doc_resetSelection(LibreOfficeKitDocument* pThis) + pDoc->resetSelection(); + } + +-static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) ++static char* doc_getStyles(LibreOfficeKitDocument* pThis) + { + LibLODocument_Impl* pDocument = static_cast(pThis); + + boost::property_tree::ptree aTree; +- aTree.put("commandName", pCommand); + uno::Reference xStyleFamiliesSupplier(pDocument->mxComponent, uno::UNO_QUERY); + uno::Reference xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); + uno::Sequence aStyleFamilies = xStyleFamilies->getElementNames(); + +- boost::property_tree::ptree aValues; + for (sal_Int32 nStyleFam = 0; nStyleFam < aStyleFamilies.getLength(); ++nStyleFam) + { + boost::property_tree::ptree aChildren; +@@ -893,9 +891,8 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + aChild.put("", aStyles[nInd]); + aChildren.push_back(std::make_pair("", aChild)); + } +- aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren); ++ aTree.add_child(sStyleFam.toUtf8().getStr(), aChildren); + } +- aTree.add_child("commandValues", aValues); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + char* pJson = static_cast(malloc(aStream.str().size() + 1)); +@@ -903,19 +900,6 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + pJson[aStream.str().size()] = '\0'; + return pJson; + } +- +-static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand) +-{ +- if (!strcmp(pCommand, ".uno:StyleApply")) +- { +- return getStyles(pThis, pCommand); +- } +- else { +- gImpl->maLastExceptionMsg = "Unknown command, no values returned"; +- return NULL; +- } +-} +- + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 8060f0e6ec7c..af7155c4db67 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -161,7 +161,7 @@ struct _LibreOfficeKitDocumentClass + void (*resetSelection) (LibreOfficeKitDocument* pThis); + + /// @see lok::Document:getStyles +- char* (*getCommandValues) (LibreOfficeKitDocument* pThis, const char* pCommand); ++ char* (*getStyles) (LibreOfficeKitDocument* pThis); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 44599948e659..c526bda95593 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -248,14 +248,11 @@ public: + } + + /** +- * Returns a json mapping of the possible values for the given command +- * e.g. {commandName: ".uno:StyleApply", commandValues: {"familyName1" : ["list of style names in the family1"], etc.}} +- * @param pCommand a uno command for which the possible values are requested +- * @return {commandName: unoCmd, commandValues: {possible_values}} ++ * Returns a json map, {"familyName1" : ["list of style names in the family1"], etc.} + */ +- inline char* getCommandValues(const char* pCommand) ++ inline char* getStyles() + { +- return mpDoc->pClass->getCommandValues(mpDoc, pCommand); ++ return mpDoc->pClass->getStyles(mpDoc); + } + #endif // LOK_USE_UNSTABLE_API + }; +diff --git a/libreofficekit/qa/unit/tiledrendering.cxx b/libreofficekit/qa/unit/tiledrendering.cxx +index f4a721b3e164..a0f4bcb5b8eb 100644 +--- a/libreofficekit/qa/unit/tiledrendering.cxx ++++ b/libreofficekit/qa/unit/tiledrendering.cxx +@@ -195,16 +195,12 @@ void TiledRenderingTest::testGetStyles( Office* pOffice ) + scoped_ptr< Document> pDocument( pOffice->documentLoad( sDocPath.c_str() ) ); + + boost::property_tree::ptree aTree; +- char* pJSON = pDocument->getCommandValues(".uno:StyleApply"); ++ char* pJSON = pDocument->getStyles(); + std::stringstream aStream(pJSON); + boost::property_tree::read_json(aStream, aTree); + CPPUNIT_ASSERT( aTree.size() > 0 ); +- CPPUNIT_ASSERT( aTree.get_value("commandName") == ".uno:StyleApply" ); + +- +- boost::property_tree::ptree aValues = aTree.get_child("commandValues"); +- CPPUNIT_ASSERT( aValues.size() > 0 ); +- for (const std::pair& rPair : aValues) ++ for (const std::pair& rPair : aTree) + { + CPPUNIT_ASSERT( rPair.second.size() > 0); + if (rPair.first != "CharacterStyles" && +-- +2.12.0 + diff --git a/SOURCES/0103-LOK-moved-the-decalaration-of-LibLODocument_Impl-to-.patch b/SOURCES/0103-LOK-moved-the-decalaration-of-LibLODocument_Impl-to-.patch new file mode 100644 index 0000000..65f9563 --- /dev/null +++ b/SOURCES/0103-LOK-moved-the-decalaration-of-LibLODocument_Impl-to-.patch @@ -0,0 +1,571 @@ +From 578ff092c9726fb2fd18b1a21a5846855a641508 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Wed, 9 Sep 2015 15:08:26 +0300 +Subject: [PATCH 103/398] LOK: moved the decalaration of LibLODocument_Impl to + make it visible + +We needed a better way to test LOK methods that are not app specific, +but are defined in /desktop/source/lib/init.cxx. So the decalaration +needs to be visible. + +I also moved the `getStyles` test in the new test file + +Change-Id: I98d97dc17a66e72732ca7bd848c131610790f48e +(cherry picked from commit 2290efa4a22d42cd9099b63b9138e4ff994c07f9) +--- + desktop/CppunitTest_desktop_lib.mk | 68 ++++++++++++++++ + desktop/Module_desktop.mk | 4 + + desktop/inc/lib/init.hxx | 27 +++++++ + desktop/qa/data/blank_text.odt | Bin 0 -> 8295 bytes + desktop/qa/desktop_lib/test_desktop_lib.cxx | 116 ++++++++++++++++++++++++++++ + desktop/source/lib/init.cxx | 79 +++++++++---------- + libreofficekit/qa/unit/tiledrendering.cxx | 34 -------- + 7 files changed, 252 insertions(+), 76 deletions(-) + create mode 100644 desktop/CppunitTest_desktop_lib.mk + create mode 100644 desktop/inc/lib/init.hxx + create mode 100644 desktop/qa/data/blank_text.odt + create mode 100644 desktop/qa/desktop_lib/test_desktop_lib.cxx + +diff --git a/desktop/CppunitTest_desktop_lib.mk b/desktop/CppunitTest_desktop_lib.mk +new file mode 100644 +index 000000000000..be394600ddf0 +--- /dev/null ++++ b/desktop/CppunitTest_desktop_lib.mk +@@ -0,0 +1,68 @@ ++# -*- 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,desktop_lib)) ++ ++$(eval $(call gb_CppunitTest_add_exception_objects,desktop_lib, \ ++ desktop/qa/desktop_lib/test_desktop_lib \ ++)) ++ ++$(eval $(call gb_CppunitTest_use_libraries,desktop_lib, \ ++ comphelper \ ++ cppu \ ++ cppuhelper \ ++ sal \ ++ sfx \ ++ sofficeapp \ ++ subsequenttest \ ++ sw \ ++ test \ ++ unotest \ ++ vcl \ ++ $(gb_UWINAPI) \ ++)) ++ ++$(eval $(call gb_CppunitTest_use_external,desktop_lib,boost_headers)) ++ ++$(eval $(call gb_CppunitTest_use_api,desktop_lib,\ ++ offapi \ ++ udkapi \ ++)) ++ ++$(eval $(call gb_CppunitTest_use_ure,desktop_lib)) ++ ++$(eval $(call gb_CppunitTest_use_vcl,desktop_lib)) ++ ++$(eval $(call gb_CppunitTest_use_components,desktop_lib,\ ++ comphelper/util/comphelp \ ++ configmgr/source/configmgr \ ++ filter/source/config/cache/filterconfig1 \ ++ filter/source/storagefilterdetect/storagefd \ ++ framework/util/fwk \ ++ i18npool/util/i18npool \ ++ package/source/xstor/xstor \ ++ package/util/package2 \ ++ sax/source/expatwrap/expwrap \ ++ sfx2/util/sfx \ ++ svl/source/fsstor/fsstorage \ ++ svtools/util/svt \ ++ sw/util/sw \ ++ sw/util/swd \ ++ toolkit/util/tk \ ++ ucb/source/core/ucb1 \ ++ ucb/source/ucp/file/ucpfile1 \ ++ unoxml/source/service/unoxml \ ++ xmloff/util/xo \ ++)) ++ ++$(eval $(call gb_CppunitTest_use_configuration,desktop_lib)) ++ ++# vim: set noet sw=4 ts=4: +diff --git a/desktop/Module_desktop.mk b/desktop/Module_desktop.mk +index ab04152731ce..c725a268721e 100644 +--- a/desktop/Module_desktop.mk ++++ b/desktop/Module_desktop.mk +@@ -130,4 +130,8 @@ $(eval $(call gb_Module_add_check_targets,desktop, \ + CppunitTest_desktop_version \ + )) + ++$(eval $(call gb_Module_add_check_targets,desktop, \ ++ CppunitTest_desktop_lib \ ++)) ++ + # vim: set ts=4 sw=4 et: +diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx +new file mode 100644 +index 000000000000..b17f82566daf +--- /dev/null ++++ b/desktop/inc/lib/init.hxx +@@ -0,0 +1,27 @@ ++/* -*- 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 "../../source/inc/desktopdllapi.h" ++ ++using namespace css; ++using namespace boost; ++ ++namespace desktop { ++ struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public _LibreOfficeKitDocument ++ { ++ uno::Reference mxComponent; ++ shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; ++ ++ explicit LibLODocument_Impl(const uno::Reference &xComponent); ++ ~LibLODocument_Impl(); ++ }; ++} +diff --git a/desktop/qa/data/blank_text.odt b/desktop/qa/data/blank_text.odt +new file mode 100644 +index 0000000000000000000000000000000000000000..00b92d785acd15b68c927aa3b2f1a5d3f1614425 +GIT binary patch +literal 8295 +zcmeHMbzD^4)*hNsQc^-jKmmy%1rd-Ak(8lp=$L__8>A5dW28Gpx)G!i6qJrZIz_ru +zg>QK8^~KkV_s{RIyXJS8eTMTqXV-f6UVEu3Vqud50QdkvlH{qhVLLAY3jhE(yU;%Y +z;MQ<+XAguq6oG(Qn?jwf?d`y>c4l1mP$z3AE_;NzoteF<3*6k!nakPS-C6Y?WGF;v +z{|F`kaCT9n$uz87;3jrZYnT(*`Dc*}VQ2YRRauVk63r#_BZLa_((35%b^rhafRDxj +zEbpaI0RWh(3epl9?n!I?r9c2TK~o9Q(doi2P%2%X%6)Tn-M_nzXj(9a(Spt7e}Deh +z2mk-`fGSrD_oOVdwFf<80SYq8(nXTS0sry_e0==BTu4maO|d^VuRm+wd?}~?N)wPBml%=s{hI+|cA8&#A{z`RT+}Bz +zKq}i;*M!}EKwC7=acz=dHcTOdH8x-8`_7Ws5zSQhy$6sOhZglb`FK8SvW%?YDbkW` +zg_Q{%eVh1Our~@fy5ki%6(G&?{?Q>{2U8)%)Nje^m#)#3agL2Pn1#X}w#rUB(6_JK +zAx34b0S~1-bB!4cK@C%~NkSkK8gsPST2?~w51viIv5~l1 +zFLm9?Z-fEA5b;^L^GV~ux;fVKd!SMZWuIan9Jmrz9m;5QSq$A}x}8sidL}Sj@6;MN +zHbXyfg1(+5n!a5R>(JW8Pds@)*UCfXJbAzo3a<&bGTd#jh$K3?|5`SWX%J_5AqqFJ +zC-;P?cSy!PyT)Aj5%LKl0LNOSXxm8{Yn%jw5lS1IqcnS0E{>=Le`t(wq*r;Mk%58I +ztjp0Gdk57FjBPjZ*o|-#;D65Z4i +zOHwm8XuI>CI^-jbl*2j{BoC_&Y1#r?8a$qJ(}6;*JE_&@N9OnP;-%tm-O$IhKu!9? +z^tihwC@E87syKplz=M8q<2^-9lKJUQH;L#oYx;Hg?%$~K#}1HGlc6aY+mTot^Zlal +zz?zV(D`HLlF0NEGmRRN9voXbS_aKatdu;BM5wk}#gsKO`feFC`lb8x2Kt)!jmQSx- +z!1ghj$74$=ZEmZ?ClJ}o99`T|X-*7?J5+CVz5}T`y)TRJNzzrqgkfbSS405yZ5rco +z)COV){;lHM&`3)0kHS4-IQt}NkSO!ZY6!)&AND0*#5SftMC;>$c5ra%Mh>Y9MUyXmEG2KN;|uq@5*-{A69NoHU%xy&T|htGf?j+97vNZ8(c#YZw#(V)k03Zi~v0AyqvoXG#MNbj +z?PCfDc5M0E&cV1W!@};xo${lFt9c5Qu1-!5UF=bcQZG%#?r1=&jtg%|kF%CBm?b)N +za&`AiLCR0rS@M+{c)Da3eBq&cTO0OTm&)$F8W)Gboyt66)vj9CqxZCkb|QyveQWr3 +zlxSZerrHz|r!j2*i8oykb0N#o&sT4P!r{#bQA8wh4OoPCpgsT$w&${W4?HFC=ACF< +z8=a!kifzjx&Jo&>lIFqfVndSk>e0xCVa64V(?(13(8E8g3ZXVBm_8uIEF>8?PWUZ4 +z*kVaJK%)Y~Cjh4@Rh!%e=uLY$J-s1W2U{5JN2)f1cv`OwTa;E?+ZXfBwjqz1Hv`_x +zY2Wo7OcZ-yES0H=jJGkKA}7R6xx2d>12j*fsEHK@T}zbI;xjjMTVvu9Zie&6jNLJa +z*~OhLsK}bERD2SQJ9JWy>b|_*P>2Tt@sm`Ni?WvNi4so*C{C_W7_J$KS8i?EB#6pW +z@M$ETW)Wfm*N(ZQdW9 +zg9X92EG)uQtVJ-XHWqB@%hY16_+BR>mLyK(Mm_npZ9Mxjn75!puUcX^8LTZ0OqKT1 +zM#eF;k2+Hp!s2!!)Q%<($3s)12i{{YE-W5{EF}4LGQ83xZ}Gn5LZKRXx81r~eF-uc +z1BfuV785~1dwxeY#|d&i@8GIgnWVr110%|U`#p{lUrAfsR1Y1X!cC0#4*SSOfc$$V +z;UmPk;vpJJ*FDuLG%DZqmr^qDz$jQq_S~)17i3zo#M0BntG3}uE^?>KMHQPH5;}M~ +zgDl{5az*0VF){_a^g5J(1WiCke9qz5k=qH6xhbM(kIJA7VY{Dqfe~t&VE@E6TchKK +ztkKP_{uJd#gjA(Q&I5jqisP2+yw*ZHkiZlH?OOmF{L4F%tDvoR9A^d?N1b}>SPm{| +zO0JC*9H!4k&&-i!O5kAiF&Rgj7_@G7;BbOpGSL`2A6FEn4o}E +zd7|h{Ru5~R8q;QV_Du*33kfe~GAst85gSp&_yA9MTJ)N;sG{_7yt$Iz +zF+n-u6%wj+<=W7Mv6eNt`0`XKRUyd;(?F-4+*?qtA?8m@6az0F=IEhJ&cjM(WR^bAhEo=;r1Mm{~J}a7AsT-L_M$q(K +z_Z&QECC4$Z2MeUau=by{Z-*%q>RhSzYQdu}*Kl82&sZHTyL-)claJP+*@ny>-+{3X +zdtJ*ShcM5&YV)n`UVg}e)qU?lIEw&d`6uQhs$`tvlZpLR_oe~*bo0ej?5L3(mWoie +zD||JA!$ZkNL699^cDGZ8vz6h;Ql9BF4mx&02QhzM8UBiH%$=cUt3o7F;%Oo`N$|!G +zim?4lRlpm@7+$YEbzjF84(ge$VvGkwMgWhF1emj6w?k7nCcWnlEI77f6{kEbxibgz +zHWk8rh{;isc{!VY4L-!`r`g|MuGGfR<@S0nOMFhl`zV6SllA1JI58t1g1uyd6ofw4 +zRo(;G*rt0W6v=8W^egPW+SIef3-1-_neoQ2v?l2&BPbjqr1;)Vh+NXVkHDtqAYx*? +zEDjR4y4+VB@sGxM2D+jWIvSI6=0a2o$*k?MFNjE;F`fS`jv732r +zWH)AD^74o#gw}YN)ZaFQw}qK#lSk;8V1RXyb%d1ngK`dKvKN^w^eDac9syk~+QRwC +zJUvYp5`-w5-l5$x?nNxs<~Y>(^dJ!v8g +zEu>sxvOx%n8_yoyMYu8paS2@L{czMCn?`e|3{{Js?sWCNb(88jdAkt|D@dpQK@jT|H;|i%_@ewz1_MaW&P-%aGNUXm!{f +zN+vxng>F+nQO=Gsiuc{_t|1uetI(Gnq>EAfXb7UcBqB4$;#4d +zPLC^(z8R;je|fd9B}5tZX&v_XspD6(Hm}=M@X+Fd_=(Rva-r!+3b66AvdTzrhn&QZ +zpd-?cmzWh4pD^7xYORmGuLBF1MhHa^m-EcM1?d-~{Bwpc$q5*#Ip)>OvNnAXlJA!vl(h-*L|vrBM!k;aGrsbP7y|h{V2jqV3qMkz^uMF9dysmtS7gvj}vrM +zyl2Uu7A4tBJ=jRlp8nihNxpGagOsJsn2)gfZYqyve%{SE?4f047Nm!<@7?jx{8c<< +z<}XBE&e5Wh{CT97I#gCoRJctubM==Ve(Z|wtA9a-@g8TcOq2PlVHzOWI@$2`Co4Zs +zwmkEREunQY92X0WEE??EMwY|PY&Xq2#dnP-93OE>Jyq&^V3%Agd_4&}{FO2-LgAst +zQ4!ZSAiEPcW>xqlac>T8mhhn5l&U+(Y1ymhsn^R!+3A3mOPuc>xX%38LW%czL)O#N +zAnHj5cFXmZdb%yfcNJBGeo)J4)cKg+R}&TCZH#t2m^?UC+4Z_}{K%2ilZjO%2F$eU +zyx|jh>1KmN+^0u^!pPU|Kj^!gAIK9rfF#|U_gtn(b6?S9_u<9G>=sQ}(4_$^uXgqb +zU1DU)HS~J-m?)El74J52{~Ftfh?Ky43h+V^@|loVjB?U*ZLr`mhFYympH!n=Y#lhq +zv^N$o^u~ItfRjgARUyB<=YEm%go8#F^EQY5-WXU&gN6&pAKoc;{f<{t3FIMeeRFL2 +z(FA5!{qsDL#2{7OhcN>#S0o}>U`_xvG4`zPv81DAHvyR}Rtr3a3JUGx_g?nAM6D3{ +zZRO*o7hKTBgLKiB23A$jPKX-iTvFS~9lfb9vqH(Sc~k +zt52Z93k~Bb!Bicl1-I2*_z{Jr_jT!^dI9(*!Kz!RV%M&s-G-7Ja%$rb(N24_kP&&q +zS-$M!`z%4xIhVJAUuPLD;UwHSchYMe`Sr_Xg +zeUCre*12n53mJ?UU7H*_#1YJT#n@J}pQfTlhjpS$WkAf@AzygX#0~Bgd67+;yA0F@ +zx(423=)t0G^nH*9nzwo0;ogwKmB1mY5{=mlQ{O#xKXH3sPHQ(ZT;xjNm~{Qcx8*lh +zSPq`e8ZQ~)r6No^4+J;J)xsyZd8x?s+97tiZvwlp0>UyRb8~&yTf{6whiAF_JNxk> +zE*q86$GjFk%IENgLER+C#uz}aOx~FmS8Ho8sxf2d;vEf|p|a~3c*2wG)+z9?_OfH9 +z3hx)Gqs$NSvHTve_`!6%m(^EF%VMq*3E+X)ca{CzUfIe^jqtJ!Ik@wt6j&r!bl)Ql +z68Ub#I67%&EBN)=b(AP(2A=bkr;xOi?F_Om&Dh4qSbM56599}xBAKCOii1VL0ZmCG +zMfg%AsSi%+K!TjDUba%#!7h^`Uo|QuA#*A`r|#C>gm=Eo>2F_PS9J$uAd#|6vEP%J +zf2@9AQL5i_6z1P^Mm;krQ_LO>zG*}lx)>nJk+2dg-Z<`n|EBnmZ^ks_@WL!y?-qZMH6%mSA>Y +z9`fQg`K@aM;S+!?+@{{zKz2SO(PR*7kHB``1I>qHy>FRshS{w&#|qn*)&nK%pyJB9;+yI)rynfiJ0;?O48_UP1!!AJKXqVbSm*>CY**<-zW?A!A(r5zYK +zy#f)hYQ)#196{{^w5{%wfm?O7b4RwuB5!#js6?s3wLFG(xa~W%t%pT;b8qb;HVm=m +z+9IKKtIh78Be%8%xEs(9YKc-8qaUotZU2bom#mOd&sOL=CXV<3aVZWOj)iBQ;k +z`w<8=&-eH|#iW~usOqax8?m_|`dV$J_m +zH|Joz$(t;FihkIwd(50lB>E*T?!sue>~`3SiX235(OW$uTfpc=?t9QPpq!s#3F_Ki +zgrKm$SC8`H#uJWR;W%BCeu5*Y^tj&;PE$GS?vHu-wjWd{Gt0etRkxxl`UaRvBSuT(~OR@$g4)E*lzEw8>SL(*_= +zNgRak*`H#b?K`f{j5Uj+_lj}g|F-WqJ7$1G?W`@#ot(KG%`Cc*U3P)oBtaV@!RFl~ +z;$R#cN7l|7o75(O5N#arcEXj(hA5<_T2|h2>fl_FEZZ2g?80xkYO=?KM@OpI84~EXYyz`WZ`Hcl-MV8G6U-?{0P88wV0BN}5mBjQY#tJF +zkSA!bh{6Y6i)8c&{A_=NqgpT01|yNA^bY6>=Lv}y*{)G^xR)O68NAq +z$T^U%R#~x)FJ?#WPILO&?0e(-fxrwA<4yLco{`Bgf}91z>H3m&{lF>jXe-ZkQ%{$H +zwyi0qm&QrF>nh7{?|Pgro^bV?UY#wjaFvFMcV}82KU=KWW`M{QpLJiwfmJ^adfOKG +z_qOe4rUBh!e;Wh3BxP@BVQuN+_*ag>i5F}QhgzCDfhDb-;ZTGVdJp((n&NLHxiBQuMW?rC$&ufy3pF)0hnb^mZ|?{;b#Zk3 +z_sK36db5gm7HR;_av5j#=Z2i6NPefafZ0Qx&3{(rqQ1MR`A*JIXO~|ZaS`sKx1Dv{ +zdDAaKUGz4DJ;DWnP64_6m(ITEZD)}4w_ViH6zCpNlF^XhR8W=$|LtGsfUWXnvt28Q +zAY{WQJZy!0#4|y)|JtoJU@e~UJB8;>(#CoFYjSy&9sK4t73&tJJEy7Ks&JKVN;&*K +z_kz!t{VZ_O_9L5%EH=JXZ%4xg^E=u2Ii+8q(ms6Sp6pM^e$=0Dl_9+Vy5HY_@F)`1 +zf$`$|Bp9q*4Z|$4NQCelSGG&WAB66VOx(2nXxNu-VWMoN@7hZZ>8}Y*c->Gf%ial} +z4I^v>?69%02$7O0QtyY(i>Y3v#W9eYG!<+$PFfZx*puNJWg_%GqO%ObbL4qRwImDb +zY>gtOaur|Rs&KB_BrY(r72#i_*J5!K<=h|ffGNec$S@WK_tS9958|ai#BU@%us3uQ +z3ynjFPj?_hA=IDPx8{gPy#G=y`bRrDbZEB|!#e?7E4%YmGm9$FxN$%y<8{57UO6Weophx^YH-rteG29AF@;@{9o +zG!Z(x`PT`+@2Fp8|179Hw{oIiL(JcCzv|sT>&cGJV*Wja(M!ZnTnM@tv)UY^_31w8*$&wnxf9QiZkPYFEJ&vUza^*@{U +z2Q~d~eRifW=Z3g|^ju5-+{iP1JGYz*Sbo*kKlA*vHj@|doNMi$S^ilYa`f%*^WazQ +z{WH%$YxCd&o^vh!7t7CK`&CHJ)cD*2&@2~fv#KHv+9d%1QuGIb)}I;Lv%CKTSWiMf + +literal 0 +HcmV?d00001 + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +new file mode 100644 +index 000000000000..c88a53f41edb +--- /dev/null ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -0,0 +1,116 @@ ++/* -*- 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 "../../inc/lib/init.hxx" ++ ++using namespace com::sun::star; ++using namespace desktop; ++ ++class DesktopLOKTest : public UnoApiTest ++{ ++public: ++ DesktopLOKTest() : UnoApiTest("/desktop/qa/data/") ++ { ++ } ++ ++ virtual ~DesktopLOKTest() ++ { ++ } ++ ++ virtual void setUp() SAL_OVERRIDE ++ { ++ UnoApiTest::setUp(); ++ mxDesktop.set(frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory()))); ++ }; ++ ++ virtual void tearDown() SAL_OVERRIDE ++ { ++ closeDoc(); ++ UnoApiTest::tearDown(); ++ }; ++ ++ LibLODocument_Impl* loadDoc(const char* pName); ++ void closeDoc(); ++ ++ void runAllTests(); ++ void testGetStyles(); ++ ++ CPPUNIT_TEST_SUITE(DesktopLOKTest); ++ CPPUNIT_TEST(runAllTests); ++ CPPUNIT_TEST_SUITE_END(); ++ ++ uno::Reference mxComponent; ++}; ++ ++LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName) ++{ ++ OUString aFileURL; ++ createFileURL(OUString::createFromAscii(pName), aFileURL); ++ mxComponent = loadFromDesktop(aFileURL, "com.sun.star.text.TextDocument"); ++ if (!mxComponent.is()) ++ { ++ CPPUNIT_ASSERT(false); ++ } ++ return new LibLODocument_Impl(mxComponent); ++} ++ ++void DesktopLOKTest::closeDoc() ++{ ++ if (mxComponent.is()) ++ { ++ closeDocument(mxComponent); ++ mxComponent.clear(); ++ } ++} ++ ++void DesktopLOKTest::runAllTests() ++{ ++ testGetStyles(); ++} ++ ++void DesktopLOKTest::testGetStyles() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ boost::property_tree::ptree aTree; ++ char* pJSON = pDocument->m_pDocumentClass->getStyles(pDocument); ++ std::stringstream aStream(pJSON); ++ boost::property_tree::read_json(aStream, aTree); ++ CPPUNIT_ASSERT( aTree.size() > 0 ); ++ ++ for (const std::pair& rPair : aTree) ++ { ++ CPPUNIT_ASSERT( rPair.second.size() > 0); ++ if (rPair.first != "CharacterStyles" && ++ rPair.first != "ParagraphStyles" && ++ rPair.first != "FrameStyles" && ++ rPair.first != "PageStyles" && ++ rPair.first != "NumberingStyles" && ++ rPair.first != "CellStyles" && ++ rPair.first != "ShapeStyles") ++ { ++ CPPUNIT_FAIL("Unknown style family: " + rPair.first); ++ } ++ } ++ closeDoc(); ++} ++ ++CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); ++ ++CPPUNIT_PLUGIN_IMPLEMENT(); ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index c7f3aabb58b7..a20decd3afbe 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -64,6 +64,7 @@ + // We also need to hackily be able to start the main libreoffice thread: + #include "../app/sofficemain.h" + #include "../app/officeipcthread.hxx" ++#include "../../inc/lib/init.hxx" + + using namespace css; + using namespace vcl; +@@ -72,7 +73,6 @@ using namespace utl; + + using namespace boost; + +-struct LibLODocument_Impl; + struct LibLibreOffice_Impl; + + static LibLibreOffice_Impl *gImpl = NULL; +@@ -237,51 +237,46 @@ static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + static void doc_resetSelection (LibreOfficeKitDocument* pThis); + static char* doc_getStyles(LibreOfficeKitDocument* pThis); + +-struct LibLODocument_Impl : public _LibreOfficeKitDocument +-{ +- uno::Reference mxComponent; +- shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; + +- explicit LibLODocument_Impl(const uno::Reference &xComponent) : +- mxComponent( xComponent ) ++LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : ++ mxComponent( xComponent ) ++{ ++ if (!(m_pDocumentClass = gDocumentClass.lock())) + { +- if (!(m_pDocumentClass = gDocumentClass.lock())) +- { +- m_pDocumentClass.reset(new LibreOfficeKitDocumentClass); +- +- m_pDocumentClass->nSize = sizeof(LibreOfficeKitDocument); +- +- m_pDocumentClass->destroy = doc_destroy; +- m_pDocumentClass->saveAs = doc_saveAs; +- m_pDocumentClass->getDocumentType = doc_getDocumentType; +- m_pDocumentClass->getParts = doc_getParts; +- m_pDocumentClass->getPart = doc_getPart; +- m_pDocumentClass->setPart = doc_setPart; +- m_pDocumentClass->getPartName = doc_getPartName; +- m_pDocumentClass->setPartMode = doc_setPartMode; +- m_pDocumentClass->paintTile = doc_paintTile; +- m_pDocumentClass->getDocumentSize = doc_getDocumentSize; +- m_pDocumentClass->initializeForRendering = doc_initializeForRendering; +- m_pDocumentClass->registerCallback = doc_registerCallback; +- m_pDocumentClass->postKeyEvent = doc_postKeyEvent; +- m_pDocumentClass->postMouseEvent = doc_postMouseEvent; +- m_pDocumentClass->postUnoCommand = doc_postUnoCommand; +- m_pDocumentClass->setTextSelection = doc_setTextSelection; +- m_pDocumentClass->getTextSelection = doc_getTextSelection; +- m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection; +- m_pDocumentClass->resetSelection = doc_resetSelection; +- m_pDocumentClass->getStyles = doc_getStyles; +- +- gDocumentClass = m_pDocumentClass; +- } +- pClass = m_pDocumentClass.get(); ++ m_pDocumentClass.reset(new LibreOfficeKitDocumentClass); ++ ++ m_pDocumentClass->nSize = sizeof(LibreOfficeKitDocument); ++ ++ m_pDocumentClass->destroy = doc_destroy; ++ m_pDocumentClass->saveAs = doc_saveAs; ++ m_pDocumentClass->getDocumentType = doc_getDocumentType; ++ m_pDocumentClass->getParts = doc_getParts; ++ m_pDocumentClass->getPart = doc_getPart; ++ m_pDocumentClass->setPart = doc_setPart; ++ m_pDocumentClass->getPartName = doc_getPartName; ++ m_pDocumentClass->setPartMode = doc_setPartMode; ++ m_pDocumentClass->paintTile = doc_paintTile; ++ m_pDocumentClass->getDocumentSize = doc_getDocumentSize; ++ m_pDocumentClass->initializeForRendering = doc_initializeForRendering; ++ m_pDocumentClass->registerCallback = doc_registerCallback; ++ m_pDocumentClass->postKeyEvent = doc_postKeyEvent; ++ m_pDocumentClass->postMouseEvent = doc_postMouseEvent; ++ m_pDocumentClass->postUnoCommand = doc_postUnoCommand; ++ m_pDocumentClass->setTextSelection = doc_setTextSelection; ++ m_pDocumentClass->getTextSelection = doc_getTextSelection; ++ m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection; ++ m_pDocumentClass->resetSelection = doc_resetSelection; ++ m_pDocumentClass->getStyles = doc_getStyles; ++ ++ gDocumentClass = m_pDocumentClass; + } ++ pClass = m_pDocumentClass.get(); ++} + +- ~LibLODocument_Impl() +- { +- mxComponent->dispose(); +- } +-}; ++LibLODocument_Impl::~LibLODocument_Impl() ++{ ++ mxComponent->dispose(); ++} + + static void doc_destroy(LibreOfficeKitDocument *pThis) + { +diff --git a/libreofficekit/qa/unit/tiledrendering.cxx b/libreofficekit/qa/unit/tiledrendering.cxx +index a0f4bcb5b8eb..aa68c724f0f3 100644 +--- a/libreofficekit/qa/unit/tiledrendering.cxx ++++ b/libreofficekit/qa/unit/tiledrendering.cxx +@@ -68,7 +68,6 @@ public: + void testDocumentTypes( Office* pOffice ); + void testImpressSlideNames( Office* pOffice ); + void testCalcSheetNames( Office* pOffice ); +- void testGetStyles( Office* pOffice ); + #if 0 + void testOverlay( Office* pOffice ); + #endif +@@ -95,7 +94,6 @@ void TiledRenderingTest::runAllTests() + testDocumentTypes( pOffice.get() ); + testImpressSlideNames( pOffice.get() ); + testCalcSheetNames( pOffice.get() ); +- testGetStyles( pOffice.get() ); + #if 0 + testOverlay( pOffice.get() ); + #endif +@@ -184,38 +182,6 @@ void TiledRenderingTest::testCalcSheetNames( Office* pOffice ) + CPPUNIT_ASSERT( strcmp( pDocument->getPartName( 2 ), "Sheet3" ) == 0 ); + } + +-void TiledRenderingTest::testGetStyles( Office* pOffice ) +-{ +- const string sDocPath = m_sSrcRoot + "/libreofficekit/qa/data/blank_text.odt"; +- const string sLockFile = m_sSrcRoot +"/libreofficekit/qa/data/.~lock.blank_text.odt#"; +- +- // FIXME: LOK will fail when trying to open a locked file +- remove( sLockFile.c_str() ); +- +- scoped_ptr< Document> pDocument( pOffice->documentLoad( sDocPath.c_str() ) ); +- +- boost::property_tree::ptree aTree; +- char* pJSON = pDocument->getStyles(); +- std::stringstream aStream(pJSON); +- boost::property_tree::read_json(aStream, aTree); +- CPPUNIT_ASSERT( aTree.size() > 0 ); +- +- for (const std::pair& rPair : aTree) +- { +- CPPUNIT_ASSERT( rPair.second.size() > 0); +- if (rPair.first != "CharacterStyles" && +- rPair.first != "ParagraphStyles" && +- rPair.first != "FrameStyles" && +- rPair.first != "PageStyles" && +- rPair.first != "NumberingStyles" && +- rPair.first != "CellStyles" && +- rPair.first != "ShapeStyles") +- { +- CPPUNIT_FAIL("Unknown style family: " + rPair.first); +- } +- } +-} +- + #if 0 + static void dumpRGBABitmap( const OUString& rPath, const unsigned char* pBuffer, + const int nWidth, const int nHeight ) +-- +2.12.0 + diff --git a/SOURCES/0104-desktop-enable-CppunitTest_desktop_lib-only-on-Linux.patch b/SOURCES/0104-desktop-enable-CppunitTest_desktop_lib-only-on-Linux.patch new file mode 100644 index 0000000..ec544ef --- /dev/null +++ b/SOURCES/0104-desktop-enable-CppunitTest_desktop_lib-only-on-Linux.patch @@ -0,0 +1,41 @@ +From a72e78faa93c71cce4f479a99f4b6b9961a3968d Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 10 Sep 2015 09:38:02 +0200 +Subject: [PATCH 104/398] desktop: enable CppunitTest_desktop_lib only on Linux + +Since the test would fail to link on Windows, due to + +ifeq ($(GUIBASE),unx) +$(eval $(call gb_Library_add_exception_objects,sofficeapp,\ + desktop/source/lib/init \ +)) +endif + +in Library_sofficeapp.mk. Given that +CppunitTest_libreofficekit_tiledrendering is marked as Linux-only as +well, be consistent and have this test as Linux-only, too. + +Change-Id: I6c8884398eba5dcf8a74c9cdc96c869b6108fb7e +(cherry picked from commit ac882c305da2c5d9c30756da8ac2976f9047622d) +--- + desktop/Module_desktop.mk | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/desktop/Module_desktop.mk b/desktop/Module_desktop.mk +index c725a268721e..d74d40629a28 100644 +--- a/desktop/Module_desktop.mk ++++ b/desktop/Module_desktop.mk +@@ -130,8 +130,10 @@ $(eval $(call gb_Module_add_check_targets,desktop, \ + CppunitTest_desktop_version \ + )) + ++ifeq ($(OS),LINUX) + $(eval $(call gb_Module_add_check_targets,desktop, \ + CppunitTest_desktop_lib \ + )) ++endif + + # vim: set ts=4 sw=4 et: +-- +2.12.0 + diff --git a/SOURCES/0105-LOK-added-a-general-getCommandValues-method.patch b/SOURCES/0105-LOK-added-a-general-getCommandValues-method.patch new file mode 100644 index 0000000..35e199c --- /dev/null +++ b/SOURCES/0105-LOK-added-a-general-getCommandValues-method.patch @@ -0,0 +1,153 @@ +From ba461282993202188ef16adb99220cf403356c57 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Thu, 10 Sep 2015 09:21:45 +0300 +Subject: [PATCH 105/398] LOK: added a general getCommandValues method + +This method returns a JSON mapping of the posible values for the given +command (e.g. .uno:StyleApply, etc). + +returns: +{commandName: "cmdName", commandValues: {json_of_cmd_values}} +I've fixed the unit test this time + +Change-Id: I30b0fba8ba1db33dd79f4b46026d293b9ea72402 +(cherry picked from commit 39975c477a38be613e9e162acb6de241999f0ae1) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 7 +++++-- + desktop/source/lib/init.cxx | 24 ++++++++++++++++++++---- + include/LibreOfficeKit/LibreOfficeKit.h | 2 +- + include/LibreOfficeKit/LibreOfficeKit.hxx | 9 ++++++--- + 4 files changed, 32 insertions(+), 10 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index c88a53f41edb..842d209f8fb3 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -87,12 +87,15 @@ void DesktopLOKTest::testGetStyles() + { + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); + boost::property_tree::ptree aTree; +- char* pJSON = pDocument->m_pDocumentClass->getStyles(pDocument); ++ char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:StyleApply"); + std::stringstream aStream(pJSON); + boost::property_tree::read_json(aStream, aTree); + CPPUNIT_ASSERT( aTree.size() > 0 ); ++ CPPUNIT_ASSERT( aTree.get_child("commandName").get_value() == ".uno:StyleApply" ); + +- for (const std::pair& rPair : aTree) ++ boost::property_tree::ptree aValues = aTree.get_child("commandValues"); ++ CPPUNIT_ASSERT( aValues.size() > 0 ); ++ for (const std::pair& rPair : aValues) + { + CPPUNIT_ASSERT( rPair.second.size() > 0); + if (rPair.first != "CharacterStyles" && +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index a20decd3afbe..7a020d142ddc 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -235,7 +235,7 @@ static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + int nX, + int nY); + static void doc_resetSelection (LibreOfficeKitDocument* pThis); +-static char* doc_getStyles(LibreOfficeKitDocument* pThis); ++static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand); + + + LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : +@@ -266,7 +266,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference getTextSelection = doc_getTextSelection; + m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection; + m_pDocumentClass->resetSelection = doc_resetSelection; +- m_pDocumentClass->getStyles = doc_getStyles; ++ m_pDocumentClass->getCommandValues = doc_getCommandValues; + + gDocumentClass = m_pDocumentClass; + } +@@ -865,15 +865,17 @@ static void doc_resetSelection(LibreOfficeKitDocument* pThis) + pDoc->resetSelection(); + } + +-static char* doc_getStyles(LibreOfficeKitDocument* pThis) ++static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + { + LibLODocument_Impl* pDocument = static_cast(pThis); + + boost::property_tree::ptree aTree; ++ aTree.put("commandName", pCommand); + uno::Reference xStyleFamiliesSupplier(pDocument->mxComponent, uno::UNO_QUERY); + uno::Reference xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); + uno::Sequence aStyleFamilies = xStyleFamilies->getElementNames(); + ++ boost::property_tree::ptree aValues; + for (sal_Int32 nStyleFam = 0; nStyleFam < aStyleFamilies.getLength(); ++nStyleFam) + { + boost::property_tree::ptree aChildren; +@@ -886,8 +888,9 @@ static char* doc_getStyles(LibreOfficeKitDocument* pThis) + aChild.put("", aStyles[nInd]); + aChildren.push_back(std::make_pair("", aChild)); + } +- aTree.add_child(sStyleFam.toUtf8().getStr(), aChildren); ++ aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren); + } ++ aTree.add_child("commandValues", aValues); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + char* pJson = static_cast(malloc(aStream.str().size() + 1)); +@@ -895,6 +898,19 @@ static char* doc_getStyles(LibreOfficeKitDocument* pThis) + pJson[aStream.str().size()] = '\0'; + return pJson; + } ++ ++static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand) ++{ ++ if (!strcmp(pCommand, ".uno:StyleApply")) ++ { ++ return getStyles(pThis, pCommand); ++ } ++ else { ++ gImpl->maLastExceptionMsg = "Unknown command, no values returned"; ++ return NULL; ++ } ++} ++ + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index af7155c4db67..8060f0e6ec7c 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -161,7 +161,7 @@ struct _LibreOfficeKitDocumentClass + void (*resetSelection) (LibreOfficeKitDocument* pThis); + + /// @see lok::Document:getStyles +- char* (*getStyles) (LibreOfficeKitDocument* pThis); ++ char* (*getCommandValues) (LibreOfficeKitDocument* pThis, const char* pCommand); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index c526bda95593..44599948e659 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -248,11 +248,14 @@ public: + } + + /** +- * Returns a json map, {"familyName1" : ["list of style names in the family1"], etc.} ++ * Returns a json mapping of the possible values for the given command ++ * e.g. {commandName: ".uno:StyleApply", commandValues: {"familyName1" : ["list of style names in the family1"], etc.}} ++ * @param pCommand a uno command for which the possible values are requested ++ * @return {commandName: unoCmd, commandValues: {possible_values}} + */ +- inline char* getStyles() ++ inline char* getCommandValues(const char* pCommand) + { +- return mpDoc->pClass->getStyles(mpDoc); ++ return mpDoc->pClass->getCommandValues(mpDoc, pCommand); + } + #endif // LOK_USE_UNSTABLE_API + }; +-- +2.12.0 + diff --git a/SOURCES/0106-LOK-getFonts-method.patch b/SOURCES/0106-LOK-getFonts-method.patch new file mode 100644 index 0000000..2a4c462 --- /dev/null +++ b/SOURCES/0106-LOK-getFonts-method.patch @@ -0,0 +1,142 @@ +From 1c485d2af28ed27f8cdb174d82f4a6199a23e72e Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Thu, 10 Sep 2015 11:31:48 +0300 +Subject: [PATCH 106/398] LOK: getFonts method + +Returns a json mapping of the available fonts to their possible font +sizes + +Change-Id: I80c0bdd79e3ef2d814f64b8d38143d6c2b9ca720 +(cherry picked from commit 1806882317af1162edce5c2389c9c5eeb18455ac) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 22 +++++++++++++ + desktop/source/lib/init.cxx | 48 ++++++++++++++++++++++++++++- + 2 files changed, 69 insertions(+), 1 deletion(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 842d209f8fb3..a08961403aac 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -49,6 +49,7 @@ public: + + void runAllTests(); + void testGetStyles(); ++ void testGetFonts(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(runAllTests); +@@ -81,6 +82,7 @@ void DesktopLOKTest::closeDoc() + void DesktopLOKTest::runAllTests() + { + testGetStyles(); ++ testGetFonts(); + } + + void DesktopLOKTest::testGetStyles() +@@ -112,6 +114,26 @@ void DesktopLOKTest::testGetStyles() + closeDoc(); + } + ++void DesktopLOKTest::testGetFonts() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ boost::property_tree::ptree aTree; ++ char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:CharFontName"); ++ std::stringstream aStream(pJSON); ++ boost::property_tree::read_json(aStream, aTree); ++ CPPUNIT_ASSERT( aTree.size() > 0 ); ++ CPPUNIT_ASSERT( aTree.get_child("commandName").get_value() == ".uno:CharFontName" ); ++ ++ boost::property_tree::ptree aValues = aTree.get_child("commandValues"); ++ CPPUNIT_ASSERT( aValues.size() > 0 ); ++ for (const std::pair& rPair : aValues) ++ { ++ // check that we have font sizes available for each font ++ CPPUNIT_ASSERT( rPair.second.size() > 0); ++ } ++ closeDoc(); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 7a020d142ddc..be1a01867cf5 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -45,10 +45,15 @@ + #include + #include + ++#include ++#include ++#include ++#include + #include + #include + #include + #include ++#include + #include + #include + #include +@@ -864,6 +869,43 @@ static void doc_resetSelection(LibreOfficeKitDocument* pThis) + + pDoc->resetSelection(); + } ++static char* getFonts (const char* pCommand) ++{ ++ SfxObjectShell* pDocSh = SfxObjectShell::Current(); ++ const SvxFontListItem* pFonts = static_cast( ++ pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST)); ++ const FontList* pList = pFonts ? pFonts->GetFontList() : 0; ++ ++ boost::property_tree::ptree aTree; ++ aTree.put("commandName", pCommand); ++ boost::property_tree::ptree aValues; ++ if ( pList ) ++ { ++ sal_uInt16 nFontCount = pList->GetFontNameCount(); ++ for (sal_uInt16 i = 0; i < nFontCount; ++i) ++ { ++ boost::property_tree::ptree aChildren; ++ const vcl::FontInfo& rInfo = pList->GetFontName(i); ++ const sal_IntPtr* pAry = pList->GetSizeAry(rInfo); ++ sal_uInt16 nSizeCount = 0; ++ while (pAry[nSizeCount]) ++ { ++ boost::property_tree::ptree aChild; ++ aChild.put("", (float)pAry[nSizeCount] / 10); ++ aChildren.push_back(std::make_pair("", aChild)); ++ nSizeCount++; ++ } ++ aValues.add_child(rInfo.GetName().toUtf8().getStr(), aChildren); ++ } ++ } ++ aTree.add_child("commandValues", aValues); ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ char* pJson = static_cast(malloc(aStream.str().size() + 1)); ++ strcpy(pJson, aStream.str().c_str()); ++ pJson[aStream.str().size()] = '\0'; ++ return pJson; ++} + + static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + { +@@ -901,7 +943,11 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + + static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand) + { +- if (!strcmp(pCommand, ".uno:StyleApply")) ++ if (!strcmp(pCommand, ".uno:CharFontName")) ++ { ++ return getFonts(pCommand); ++ } ++ else if (!strcmp(pCommand, ".uno:StyleApply")) + { + return getStyles(pThis, pCommand); + } +-- +2.12.0 + diff --git a/SOURCES/0107-lokdocview-GTK-calls-should-be-made-from-the-main-th.patch b/SOURCES/0107-lokdocview-GTK-calls-should-be-made-from-the-main-th.patch new file mode 100644 index 0000000..31d41b3 --- /dev/null +++ b/SOURCES/0107-lokdocview-GTK-calls-should-be-made-from-the-main-th.patch @@ -0,0 +1,54 @@ +From e53d6dd2ee9dd5bf8aed0f84cc9ef198b7ccd606 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 11 Sep 2015 11:27:08 +0200 +Subject: [PATCH 107/398] lokdocview: GTK+ calls should be made from the main + thread + +Change-Id: Ia76ef111170700ef507550222ca917986d4fe00e +(cherry picked from commit 88b6dd3ea77ca9f6d5fac2965cea6ff0634e6ba5) +--- + libreofficekit/source/gtk/lokdocview.cxx | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 83bb8b5e0aa5..27d2e1df983a 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -368,6 +368,16 @@ hyperlinkClicked(LOKDocView* pDocView, const std::string& rString) + g_signal_emit(pDocView, doc_view_signals[HYPERLINK_CLICKED], 0, rString.c_str()); + } + ++/// Trigger a redraw, invoked on the main thread by other functions running in a thread. ++static gboolean queueDraw(gpointer pData) ++{ ++ GtkWidget* pWidget = static_cast(pData); ++ ++ gtk_widget_queue_draw(pWidget); ++ ++ return G_SOURCE_REMOVE; ++} ++ + /// Implementation of the global callback handler, invoked by globalCallback(); + static gboolean + globalCallback (gpointer pData) +@@ -1249,7 +1259,7 @@ setEditInThread(gpointer data) + } + priv->m_bEdit = bEdit; + g_signal_emit(pDocView, doc_view_signals[EDIT_CHANGED], 0, bWasEdit); +- gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ gdk_threads_add_idle(queueDraw, GTK_WIDGET(pDocView)); + } + + static void +@@ -1305,7 +1315,7 @@ paintTileInThread (gpointer data) + //create a mapping for it + buffer.m_mTiles[index].setPixbuf(pPixBuf); + buffer.m_mTiles[index].valid = true; +- gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ gdk_threads_add_idle(queueDraw, GTK_WIDGET(pDocView)); + } + + +-- +2.12.0 + diff --git a/SOURCES/0108-LOK-don-t-use-unstable-API-unconditionally-when-incl.patch b/SOURCES/0108-LOK-don-t-use-unstable-API-unconditionally-when-incl.patch new file mode 100644 index 0000000..941a183 --- /dev/null +++ b/SOURCES/0108-LOK-don-t-use-unstable-API-unconditionally-when-incl.patch @@ -0,0 +1,40 @@ +From 6e8ac71304481d1e844dab199d2e5477ca9eeb7f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 11 Sep 2015 14:47:17 +0200 +Subject: [PATCH 108/398] LOK: don't use unstable API unconditionally when + including the GTK header + +Change-Id: I679ddfdadbf4746d3fba64d3d5157ec070b4f6dd +(cherry picked from commit 88c51cd55d1a9b29e62269c53b3923770253ab07) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 1 - + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 1 + + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 02789ad3f585..01009fb9eb40 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -13,7 +13,6 @@ + #include + #include + +-#define LOK_USE_UNSTABLE_API + #include + + G_BEGIN_DECLS +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 57d0c113d6ac..ab33fc703731 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -16,6 +16,7 @@ + #include + #include + ++#define LOK_USE_UNSTABLE_API + #include + #include + +-- +2.12.0 + diff --git a/SOURCES/0109-LOK-Implement-an-own-trivial-InteractionHandler.patch b/SOURCES/0109-LOK-Implement-an-own-trivial-InteractionHandler.patch new file mode 100644 index 0000000..39c2dba --- /dev/null +++ b/SOURCES/0109-LOK-Implement-an-own-trivial-InteractionHandler.patch @@ -0,0 +1,248 @@ +From fd6adbabe3debe2e41f3f39816a1e92e9c1850e1 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Fri, 11 Sep 2015 18:46:53 +0200 +Subject: [PATCH 109/398] LOK: Implement an own trivial InteractionHandler. + +So far it just selects 'Approve' for any interaction that is done through +that, later we want to route the information via callbacks to the caller. + +Change-Id: I7ae3e2dcc04877b8b0197b0396299126e1217a2a +(cherry picked from commit f1f179ba0ff3d293e81c7b95554f8e6b140340d7) +--- + desktop/Library_sofficeapp.mk | 2 + + desktop/source/lib/init.cxx | 19 ++++++- + desktop/source/lib/lokinteractionhandler.cxx | 83 ++++++++++++++++++++++++++++ + desktop/source/lib/lokinteractionhandler.hxx | 70 +++++++++++++++++++++++ + 4 files changed, 173 insertions(+), 1 deletion(-) + create mode 100644 desktop/source/lib/lokinteractionhandler.cxx + create mode 100644 desktop/source/lib/lokinteractionhandler.hxx + +diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk +index 467fecc8ffc2..ccad5a7ea5ca 100644 +--- a/desktop/Library_sofficeapp.mk ++++ b/desktop/Library_sofficeapp.mk +@@ -123,6 +123,7 @@ endif + ifneq ($(filter $(OS),ANDROID IOS),) + $(eval $(call gb_Library_add_exception_objects,sofficeapp,\ + desktop/source/lib/init \ ++ desktop/source/lib/lokinteractionhandler \ + $(if $(filter $(OS),ANDROID), \ + desktop/source/lib/lokandroid) \ + )) +@@ -130,6 +131,7 @@ else + ifeq ($(GUIBASE),unx) + $(eval $(call gb_Library_add_exception_objects,sofficeapp,\ + desktop/source/lib/init \ ++ desktop/source/lib/lokinteractionhandler \ + )) + endif + endif +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index be1a01867cf5..fb8ec3ea361a 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -71,6 +71,8 @@ + #include "../app/officeipcthread.hxx" + #include "../../inc/lib/init.hxx" + ++#include "lokinteractionhandler.hxx" ++ + using namespace css; + using namespace vcl; + using namespace desktop; +@@ -385,11 +387,26 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, + + try + { +- uno::Sequence aFilterOptions(1); ++ uno::Sequence aFilterOptions(2); + aFilterOptions[0] = css::beans::PropertyValue( OUString("FilterOptions"), + 0, + uno::makeAny(OUString::createFromAscii(pOptions)), + beans::PropertyState_DIRECT_VALUE); ++ ++ uno::Reference xInteraction(new LOKInteractionHandler(::comphelper::getProcessComponentContext())); ++ aFilterOptions[1].Name = "InteractionHandler"; ++ aFilterOptions[1].Value <<= xInteraction; ++ ++ /* TODO ++ sal_Int16 nMacroExecMode = document::MacroExecMode::USE_CONFIG; ++ aFilterOptions[2].Name = "MacroExecutionMode"; ++ aFilterOptions[2].Value <<= nMacroExecMode; ++ ++ sal_Int16 nUpdateDoc = document::UpdateDocMode::ACCORDING_TO_CONFIG; ++ aFilterOptions[3].Name = "UpdateDocMode"; ++ aFilterOptions[3].Value <<= nUpdateDoc; ++ */ ++ + uno::Reference xComponent; + xComponent = xComponentLoader->loadComponentFromURL( + aURL, OUString("_blank"), 0, +diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx +new file mode 100644 +index 000000000000..1d20b0219e28 +--- /dev/null ++++ b/desktop/source/lib/lokinteractionhandler.cxx +@@ -0,0 +1,83 @@ ++/* -*- 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/. ++ * ++ * This file incorporates work covered by the following license notice: ++ * ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed ++ * with this work for additional information regarding copyright ++ * ownership. The ASF licenses this file to you under the Apache ++ * License, Version 2.0 (the "License"); you may not use this file ++ * except in compliance with the License. You may obtain a copy of ++ * the License at http://www.apache.org/licenses/LICENSE-2.0 . ++ */ ++ ++#include "lokinteractionhandler.hxx" ++ ++#include ++ ++#include ++ ++using namespace com::sun::star; ++ ++LOKInteractionHandler::LOKInteractionHandler(uno::Reference const & /*rxContext*/) ++{ ++} ++ ++LOKInteractionHandler::~LOKInteractionHandler() ++{ ++} ++ ++OUString SAL_CALL LOKInteractionHandler::getImplementationName() throw (uno::RuntimeException, std::exception) ++{ ++ return OUString("com.sun.star.comp.uui.LOKInteractionHandler"); ++} ++ ++sal_Bool SAL_CALL LOKInteractionHandler::supportsService(OUString const & rServiceName) throw (uno::RuntimeException, std::exception) ++{ ++ return cppu::supportsService(this, rServiceName); ++} ++ ++uno::Sequence< OUString > SAL_CALL LOKInteractionHandler::getSupportedServiceNames() throw (uno::RuntimeException, std::exception) ++{ ++ uno::Sequence< OUString > aNames(3); ++ aNames[0] = "com.sun.star.task.InteractionHandler"; ++ // added to indicate support for configuration.backend.MergeRecoveryRequest ++ aNames[1] = "com.sun.star.configuration.backend.InteractionHandler"; ++ aNames[2] = "com.sun.star.uui.InteractionHandler"; ++ // for backwards compatibility ++ return aNames; ++} ++ ++void SAL_CALL LOKInteractionHandler::initialize(uno::Sequence const & /*rArguments*/) throw (uno::Exception, std::exception) ++{ ++} ++ ++void SAL_CALL LOKInteractionHandler::handle(uno::Reference const & rRequest) throw (uno::RuntimeException, std::exception) ++{ ++ // just do the same thing in both cases ++ handleInteractionRequest(rRequest); ++} ++ ++sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(const uno::Reference& rRequest) throw ( uno::RuntimeException, std::exception ) ++{ ++ uno::Sequence> const &rContinuations = rRequest->getContinuations(); ++ ++ // TODO: add LOK api that allows handling this for real, for the moment we ++ // just set the interaction as 'Approved' ++ for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i) ++ { ++ uno::Reference xApprove(rContinuations[i], uno::UNO_QUERY); ++ if (xApprove.is()) ++ xApprove->select(); ++ } ++ ++ return sal_True; ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/desktop/source/lib/lokinteractionhandler.hxx b/desktop/source/lib/lokinteractionhandler.hxx +new file mode 100644 +index 000000000000..6d4aa8231daf +--- /dev/null ++++ b/desktop/source/lib/lokinteractionhandler.hxx +@@ -0,0 +1,70 @@ ++/* -*- 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/. ++ * ++ * This file incorporates work covered by the following license notice: ++ * ++ * Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed ++ * with this work for additional information regarding copyright ++ * ownership. The ASF licenses this file to you under the Apache ++ * License, Version 2.0 (the "License"); you may not use this file ++ * except in compliance with the License. You may obtain a copy of ++ * the License at http://www.apache.org/licenses/LICENSE-2.0 . ++ */ ++ ++#ifndef INCLUDED_DESKTOP_SOURCE_LIB_LOKINTERACTIONHANDLER_HXX ++#define INCLUDED_DESKTOP_SOURCE_LIB_LOKINTERACTIONHANDLER_HXX ++ ++#include ++ ++#include ++#include ++#include ++ ++/** InteractionHandler is an interface that provides the user with various dialogs / error messages. ++ ++We need an own implementation for the LibreOfficeKit so that we can route the ++information easily via callbacks. ++ ++TODO: the callbacks are not implemented yet, we just approve any interaction ++that we get. ++*/ ++class LOKInteractionHandler: public cppu::WeakImplHelper ++{ ++ LOKInteractionHandler(const LOKInteractionHandler&) SAL_DELETED_FUNCTION; ++ LOKInteractionHandler& operator=(const LOKInteractionHandler&) SAL_DELETED_FUNCTION; ++ ++public: ++ explicit LOKInteractionHandler(com::sun::star::uno::Reference const & rxContext); ++ ++ virtual ~LOKInteractionHandler(); ++ ++ virtual OUString SAL_CALL getImplementationName() ++ throw (com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) ++ throw (com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ virtual com::sun::star::uno::Sequence SAL_CALL getSupportedServiceNames() ++ throw (com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ virtual void SAL_CALL initialize(com::sun::star::uno::Sequence const & rArguments) ++ throw (com::sun::star::uno::Exception, std::exception) SAL_OVERRIDE; ++ ++ virtual void SAL_CALL handle(com::sun::star::uno::Reference const & rRequest) ++ throw (com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; ++ ++ virtual sal_Bool SAL_CALL handleInteractionRequest(const ::com::sun::star::uno::Reference<::com::sun::star::task::XInteractionRequest>& _Request) ++ throw (com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; ++}; ++ ++#endif ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0110-create_tree.sh-Generate-g-i-files.patch b/SOURCES/0110-create_tree.sh-Generate-g-i-files.patch new file mode 100644 index 0000000..5030829 --- /dev/null +++ b/SOURCES/0110-create_tree.sh-Generate-g-i-files.patch @@ -0,0 +1,165 @@ +From 839e15f8019b8eb4b4986367aef5c77c58ed3412 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 15 Aug 2015 18:48:53 +0530 +Subject: [PATCH 110/398] create_tree.sh: Generate g-i files + +Change-Id: I1749b5b02018cfe6f85a13aed8de4b31a09788e3 +Reviewed-on: https://gerrit.libreoffice.org/18494 +Reviewed-by: Miklos Vajna +Tested-by: Miklos Vajna +(cherry picked from commit 8f2aace934eb2a91a273b6104de6383108b5c82a) +--- + configure.ac | 6 +++ + m4/introspection.m4 | 94 ++++++++++++++++++++++++++++++++++++++ + sysui/desktop/share/create_tree.sh | 13 ++++++ + 3 files changed, 113 insertions(+) + create mode 100644 m4/introspection.m4 + +diff --git a/configure.ac b/configure.ac +index 4e27231f6a5f..b1ec23a5afa3 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -181,6 +181,11 @@ SRC_ROOT=`pwd` + cd $BUILDDIR + x_Cygwin=[\#] + ++dnl ====================================== ++dnl Required GObject introspection version ++dnl ====================================== ++INTROSPECTION_REQUIRED_VERSION=1.32.0 ++ + dnl =================================================================== + dnl Search all the common names for GNU Make + dnl =================================================================== +@@ -9903,6 +9908,7 @@ if test "x$enable_gtk3" = "xyes"; then + PKG_CHECK_MODULES(GTK3, gtk+-3.0 >= 3.8 gtk+-unix-print-3.0 gmodule-no-export-2.0 glib-2.0 >= 2.38 cairo, ENABLE_GTK3="TRUE", ENABLE_GTK3="") + if test "x$ENABLE_GTK3" = "xTRUE"; then + R="gtk3" ++ GOBJECT_INTROSPECTION_CHECK(INTROSPECTION_REQUIRED_VERSION) + else + AC_MSG_ERROR([gtk3 or dependent libraries of the correct versions, not found]) + fi +diff --git a/m4/introspection.m4 b/m4/introspection.m4 +new file mode 100644 +index 000000000000..532bad82addf +--- /dev/null ++++ b/m4/introspection.m4 +@@ -0,0 +1,94 @@ ++dnl -*- mode: autoconf -*- ++dnl Copyright 2009 Johan Dahlin ++dnl ++dnl This file is free software; the author(s) gives unlimited ++dnl permission to copy and/or distribute it, with or without ++dnl modifications, as long as this notice is preserved. ++dnl ++ ++# serial 1 ++ ++m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL], ++[ ++ AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first ++ AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first ++ AC_BEFORE([LT_INIT],[$0])dnl setup libtool first ++ ++ dnl enable/disable introspection ++ m4_if([$2], [require], ++ [dnl ++ enable_introspection=yes ++ ],[dnl ++ AC_ARG_ENABLE(introspection, ++ AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]], ++ [Enable introspection for this build]),, ++ [enable_introspection=auto]) ++ ])dnl ++ ++ AC_MSG_CHECKING([for gobject-introspection]) ++ ++ dnl presence/version checking ++ AS_CASE([$enable_introspection], ++ [no], [dnl ++ found_introspection="no (disabled, use --enable-introspection to enable)" ++ ],dnl ++ [yes],[dnl ++ PKG_CHECK_EXISTS([gobject-introspection-1.0],, ++ AC_MSG_ERROR([gobject-introspection-1.0 is not installed])) ++ PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], ++ found_introspection=yes, ++ AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME])) ++ ],dnl ++ [auto],[dnl ++ PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no) ++ dnl Canonicalize enable_introspection ++ enable_introspection=$found_introspection ++ ],dnl ++ [dnl ++ AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@]) ++ ])dnl ++ ++ AC_MSG_RESULT([$found_introspection]) ++ ++ INTROSPECTION_SCANNER= ++ INTROSPECTION_COMPILER= ++ INTROSPECTION_GENERATE= ++ INTROSPECTION_GIRDIR= ++ INTROSPECTION_TYPELIBDIR= ++ if test "x$found_introspection" = "xyes"; then ++ INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` ++ INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` ++ INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` ++ INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` ++ INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" ++ INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` ++ INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` ++ INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection ++ fi ++ AC_SUBST(INTROSPECTION_SCANNER) ++ AC_SUBST(INTROSPECTION_COMPILER) ++ AC_SUBST(INTROSPECTION_GENERATE) ++ AC_SUBST(INTROSPECTION_GIRDIR) ++ AC_SUBST(INTROSPECTION_TYPELIBDIR) ++ AC_SUBST(INTROSPECTION_CFLAGS) ++ AC_SUBST(INTROSPECTION_LIBS) ++ AC_SUBST(INTROSPECTION_MAKEFILE) ++]) ++ ++ ++dnl Usage: ++dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version]) ++ ++AC_DEFUN([GOBJECT_INTROSPECTION_CHECK], ++[ ++ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1]) ++]) ++ ++dnl Usage: ++dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version]) ++ ++ ++AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE], ++[ ++ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require]) ++]) +diff --git a/sysui/desktop/share/create_tree.sh b/sysui/desktop/share/create_tree.sh +index c6be0bb2a688..45b7c6cb09db 100755 +--- a/sysui/desktop/share/create_tree.sh ++++ b/sysui/desktop/share/create_tree.sh +@@ -87,3 +87,16 @@ for i in base calc draw impress writer; do + cp "${APPDATA_SOURCE_DIR}/libreoffice-${i}.appdata.xml" "${DESTDIR}/${PREFIXDIR}/share/appdata/${PREFIX}-${i}.appdata.xml" + done + ++# Generate gobject-introspection files ++mkdir -p "${DESTDIR}/${PREFIXDIR}/share/gir-1.0" ++g-ir-scanner "${SRCDIR}/include/LibreOfficeKit/LibreOfficeKitGtk.h" "${SRCDIR}/libreofficekit/source/gtk/lokdocview.cxx" \ ++ `${PKG_CONFIG} --cflags gobject-introspection-1.0 gtk+-3.0` -I"${SRCDIR}/include/" \ ++ --include=GLib-2.0 --include=GObject-2.0 --include=Gio-2.0 \ ++ --library=libreofficekitgtk --library-path="${DESTDIR}/${INSTALLDIR}/program" \ ++ --include=Gdk-3.0 --include=GdkPixbuf-2.0 --include=Gtk-3.0 \ ++ --namespace=LOKDocView --nsversion=0.1 --identifier-prefix=LOKDoc --symbol-prefix=lok_doc \ ++ --output="${DESTDIR}/${PREFIXDIR}/share/gir-1.0/LOKDocView-0.1.gir" --warn-all --no-libtool ++ ++mkdir -p "${DESTDIR}/${LIBDIR}/girepository-1.0" ++g-ir-compiler "${DESTDIR}/${PREFIXDIR}/share/gir-1.0/LOKDocView-0.1.gir" \ ++ --output="${DESTDIR}/${LIBDIR}/girepository-1.0/LOKDocView-0.1.typelib" +-- +2.12.0 + diff --git a/SOURCES/0111-get-feedback-for-style-font-font-size-in-tiledrender.patch b/SOURCES/0111-get-feedback-for-style-font-font-size-in-tiledrender.patch new file mode 100644 index 0000000..4d303f2 --- /dev/null +++ b/SOURCES/0111-get-feedback-for-style-font-font-size-in-tiledrender.patch @@ -0,0 +1,96 @@ +From 11a1920fb4fca1624efb2210cbb1f51fb74f6264 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Mon, 14 Sep 2015 20:06:07 +0300 +Subject: [PATCH 111/398] get feedback for style / font / font size in + tiledrendering + +Change-Id: I92fd5022a4a5736a6323732141e9ea7bafec2a44 +(cherry picked from commit 6023b797c4570b69d0511b0a45bcf67932f32ba6) +--- + sfx2/source/control/unoctitm.cxx | 45 +++++++++++++++++++++++++++++++++------- + 1 file changed, 38 insertions(+), 7 deletions(-) + +diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx +index bba52c6f9722..bb5d6720029f 100644 +--- a/sfx2/source/control/unoctitm.cxx ++++ b/sfx2/source/control/unoctitm.cxx +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -37,8 +38,10 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + #include +@@ -1059,22 +1062,50 @@ void SfxDispatchController_Impl::InterceptLOKStateChangeEvent(const SfxObjectShe + if (!objSh || !objSh->isTiledRendering()) + return; + ++ OUStringBuffer aBuffer; ++ aBuffer.append(aEvent.FeatureURL.Complete); ++ aBuffer.append("="); ++ + if (aEvent.FeatureURL.Path == "Bold" || + aEvent.FeatureURL.Path == "Italic" || + aEvent.FeatureURL.Path == "Underline" || +- aEvent.FeatureURL.Path == "Strikeout") ++ aEvent.FeatureURL.Path == "Strikeout" || ++ aEvent.FeatureURL.Path == "DefaultBullet" || ++ aEvent.FeatureURL.Path == "DefaultNumbering" || ++ aEvent.FeatureURL.Path == "LeftPara" || ++ aEvent.FeatureURL.Path == "CenterPara" || ++ aEvent.FeatureURL.Path == "RightPara" || ++ aEvent.FeatureURL.Path == "JustifyPara") + { +- +- OUStringBuffer aBuffer; +- aBuffer.append(aEvent.FeatureURL.Complete); +- aBuffer.append("="); + bool bTemp = false; + aEvent.State >>= bTemp; + aBuffer.append(bTemp); + +- OUString payload = aBuffer.makeStringAndClear(); +- objSh->libreOfficeKitCallback(LOK_CALLBACK_STATE_CHANGED, payload.toUtf8().getStr()); + } ++ else if (aEvent.FeatureURL.Path == "CharFontName") ++ { ++ ::com::sun::star::awt::FontDescriptor aFontDesc; ++ aEvent.State >>= aFontDesc; ++ aBuffer.append(aFontDesc.Name); ++ } ++ else if (aEvent.FeatureURL.Path == "FontHeight") ++ { ++ ::com::sun::star::frame::status::FontHeight aFontHeight; ++ aEvent.State >>= aFontHeight; ++ aBuffer.append(aFontHeight.Height); ++ } ++ else if (aEvent.FeatureURL.Path == "StyleApply") ++ { ++ ::com::sun::star::frame::status::Template aTemplate; ++ aEvent.State >>= aTemplate; ++ aBuffer.append(aTemplate.StyleName); ++ } ++ else ++ { ++ return; ++ } ++ OUString payload = aBuffer.makeStringAndClear(); ++ objSh->libreOfficeKitCallback(LOK_CALLBACK_STATE_CHANGED, payload.toUtf8().getStr()); + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0112-lok-initialize-UNO-url-command-dispatch.patch b/SOURCES/0112-lok-initialize-UNO-url-command-dispatch.patch new file mode 100644 index 0000000..a5643c5 --- /dev/null +++ b/SOURCES/0112-lok-initialize-UNO-url-command-dispatch.patch @@ -0,0 +1,108 @@ +From bb949259f1ca2a384b68616b8c2ae953ea7eba17 Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Mon, 14 Sep 2015 20:14:34 -0400 +Subject: [PATCH 112/398] lok: initialize UNO url command dispatch + +In the tiled rendering case, the desktop is headless, so the toolbar +is not created. The toolbar usually initializes all UNO url commands +for each tool item attached. + +This causes that SfxControllerItem that monitor a state, it is not +intercepted by InterceptLOKStateChangeEvent so no callback status changes. + +Change-Id: I5937cda66ef24d31dd92a1edd8c1440081c4b1a4 +(cherry picked from commit d3a2c0f60365d6092e5061b1d061d6e3e53eb9cf) +--- + desktop/source/lib/init.cxx | 58 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index fb8ec3ea361a..f17493761529 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -44,10 +44,15 @@ + #include + #include + #include ++#include + + #include + #include + #include ++#include ++#include ++#include ++#include + #include + #include + #include +@@ -526,6 +531,58 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha + return false; + } + ++static void doc_iniUnoCommands () ++{ ++ OUString sUnoCommands[] = ++ { ++ OUString(".uno:Bold"), ++ OUString(".uno:Italic"), ++ OUString(".uno:Underline"), ++ OUString(".uno:Strikeout"), ++ OUString(".uno:LeftPara"), ++ OUString(".uno:CenterPara"), ++ OUString(".uno:RightPara"), ++ OUString(".uno:JustifyPara"), ++ OUString(".uno:IncrementIndent"), ++ OUString(".uno:DecrementIndent") ++ }; ++ ++ util::URL aCommandURL; ++ const SfxSlot* pSlot = NULL; ++ SfxViewShell* pViewShell = SfxViewShell::Current(); ++ SfxViewFrame* pViewFrame = (pViewShell ? pViewShell->GetViewFrame() : NULL); ++ ++ // check if Frame-Controller were created. ++ if (!pViewShell && !pViewFrame) ++ { ++ SAL_WARN("lok", "iniUnoCommands: No Frame-Controller created."); ++ return; ++ } ++ ++ SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pViewFrame ); ++ uno::Reference xParser = ++ util::URLTransformer::create(xContext); ++ ++ for ( ++ sal_uInt32 nIterator = 0; ++ nIterator < SAL_N_ELEMENTS(sUnoCommands); ++ nIterator++ ++ ) ++ { ++ aCommandURL.Complete = sUnoCommands[nIterator]; ++ xParser->parseStrict(aCommandURL); ++ pSlot = rSlotPool.GetUnoSlot(aCommandURL.Path); ++ ++ // Initialize slot to dispatch Uno Command. ++ uno::Reference xDispatch = ++ pViewFrame->GetBindings().GetDispatch( pSlot, aCommandURL, false ); ++ if (!xDispatch.is()) ++ { ++ SAL_WARN("lok", "iniUnoCommands: No XDispatch interface : " + aCommandURL.Complete); ++ } ++ } ++} ++ + static int doc_getDocumentType (LibreOfficeKitDocument* pThis) + { + LibLODocument_Impl* pDocument = static_cast(pThis); +@@ -739,6 +796,7 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis) + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (pDoc) + { ++ doc_iniUnoCommands(); + pDoc->initializeForTiledRendering(); + } + } +-- +2.12.0 + diff --git a/SOURCES/0113-LOK-Sync-the-list-of-commands-we-initialize-with-tho.patch b/SOURCES/0113-LOK-Sync-the-list-of-commands-we-initialize-with-tho.patch new file mode 100644 index 0000000..bc169c6 --- /dev/null +++ b/SOURCES/0113-LOK-Sync-the-list-of-commands-we-initialize-with-tho.patch @@ -0,0 +1,40 @@ +From 6dae4fa9f39f043b2b541d3f10e2be81347acb76 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 15 Sep 2015 12:00:25 +0200 +Subject: [PATCH 113/398] LOK: Sync the list of commands we initialize with + those we handle. + +A better solution is needed, outlined in tdf#94233. + +Change-Id: Ie2a58c9c5f5c46566da105ef84d736d7290f4634 +(cherry picked from commit 93cdcfac48a3b8cbbd9700ee79f650c6f17d16a4) +--- + desktop/source/lib/init.cxx | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index f17493761529..e56284cdb7cb 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -539,12 +539,17 @@ static void doc_iniUnoCommands () + OUString(".uno:Italic"), + OUString(".uno:Underline"), + OUString(".uno:Strikeout"), ++ OUString(".uno:DefaultBullet"), ++ OUString(".uno:DefaultNumbering"), + OUString(".uno:LeftPara"), + OUString(".uno:CenterPara"), + OUString(".uno:RightPara"), + OUString(".uno:JustifyPara"), + OUString(".uno:IncrementIndent"), +- OUString(".uno:DecrementIndent") ++ OUString(".uno:DecrementIndent"), ++ OUString(".uno:CharFontName"), ++ OUString(".uno:FontHeight"), ++ OUString(".uno:StyleApply") + }; + + util::URL aCommandURL; +-- +2.12.0 + diff --git a/SOURCES/0114-LOK-Avoid-crash-when-the-command-is-not-available-in.patch b/SOURCES/0114-LOK-Avoid-crash-when-the-command-is-not-available-in.patch new file mode 100644 index 0000000..2b858e7 --- /dev/null +++ b/SOURCES/0114-LOK-Avoid-crash-when-the-command-is-not-available-in.patch @@ -0,0 +1,65 @@ +From a673fc9e4b1d04c26a486caa8babf7bd003d5b38 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 15 Sep 2015 17:04:58 +0200 +Subject: [PATCH 114/398] LOK: Avoid crash when the command is not available in + the given component. + +In that case we get a NULL pSlot. + +Change-Id: I38783ed198b1ab9860398f59ef872a295cbae6f8 +(cherry picked from commit a191076e3b4063a074ebf1a4ef4cded25cebdb8c) +--- + desktop/source/lib/init.cxx | 23 +++++++++-------------- + 1 file changed, 9 insertions(+), 14 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index e56284cdb7cb..87471454b5d2 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -555,7 +555,7 @@ static void doc_iniUnoCommands () + util::URL aCommandURL; + const SfxSlot* pSlot = NULL; + SfxViewShell* pViewShell = SfxViewShell::Current(); +- SfxViewFrame* pViewFrame = (pViewShell ? pViewShell->GetViewFrame() : NULL); ++ SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): NULL; + + // check if Frame-Controller were created. + if (!pViewShell && !pViewFrame) +@@ -564,26 +564,21 @@ static void doc_iniUnoCommands () + return; + } + +- SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( pViewFrame ); +- uno::Reference xParser = +- util::URLTransformer::create(xContext); ++ SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool(pViewFrame); ++ uno::Reference xParser(util::URLTransformer::create(xContext)); + +- for ( +- sal_uInt32 nIterator = 0; +- nIterator < SAL_N_ELEMENTS(sUnoCommands); +- nIterator++ +- ) ++ for (sal_uInt32 nIterator = 0; nIterator < SAL_N_ELEMENTS(sUnoCommands); nIterator++) + { + aCommandURL.Complete = sUnoCommands[nIterator]; + xParser->parseStrict(aCommandURL); + pSlot = rSlotPool.GetUnoSlot(aCommandURL.Path); + +- // Initialize slot to dispatch Uno Command. +- uno::Reference xDispatch = +- pViewFrame->GetBindings().GetDispatch( pSlot, aCommandURL, false ); +- if (!xDispatch.is()) ++ // when null, this command is not supported by the given component ++ // (like eg. Calc does not have ".uno:DefaultBullet" etc.) ++ if (pSlot) + { +- SAL_WARN("lok", "iniUnoCommands: No XDispatch interface : " + aCommandURL.Complete); ++ // Initialize slot to dispatch .uno: Command. ++ pViewFrame->GetBindings().GetDispatch(pSlot, aCommandURL, false); + } + } + } +-- +2.12.0 + diff --git a/SOURCES/0115-tdf-94237-tiled-rendering-Use-the-entire-document-as.patch b/SOURCES/0115-tdf-94237-tiled-rendering-Use-the-entire-document-as.patch new file mode 100644 index 0000000..8fc7fe0 --- /dev/null +++ b/SOURCES/0115-tdf-94237-tiled-rendering-Use-the-entire-document-as.patch @@ -0,0 +1,65 @@ +From 70b567511fb61ff12e9b2b68913a81a4a25ebd59 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 15 Sep 2015 20:22:08 +0200 +Subject: [PATCH 115/398] tdf#94237 tiled rendering: Use the entire document as + the visual area. + +Many places were already adapted for the tiled rendering, and the conditions +checking for the VisArea() were changed so that the checks are ignored when +tiled rendering is active. + +Unfortunately there are still some places left, and they are causing that +various areas are invalidated only partially. Let's sort it out for good, and +report the entire document as the VisArea() when the tiled rendering is +active, and if there are performance problems, let's profile that & act +accordingly. + +Change-Id: I53f18915ed0aec898704dd1350a9534cfc3f001b +(cherry picked from commit 12e3b51abe883202af09769873f87b27d7de118b) +--- + sw/inc/viewsh.hxx | 3 ++- + sw/source/core/view/viewsh.cxx | 7 +++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx +index 763af506b210..1ba064f0c16c 100644 +--- a/sw/inc/viewsh.hxx ++++ b/sw/inc/viewsh.hxx +@@ -31,6 +31,7 @@ + #include + #include + #include ++ + #define LOK_USE_UNSTABLE_API + #include + +@@ -269,7 +270,7 @@ public: + bool SmoothScroll( long lXDiff, long lYDiff, const Rectangle* );//Browser + void EnableSmooth( bool b ) { mbEnableSmooth = b; } + +- const SwRect& VisArea() const { return maVisArea; } ++ const SwRect& VisArea() const; + + // If necessary scroll until passed Rect is situated in visible sector. + void MakeVisible( const SwRect & ); +diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx +index 3d565aea254c..92480b242089 100644 +--- a/sw/source/core/view/viewsh.cxx ++++ b/sw/source/core/view/viewsh.cxx +@@ -569,6 +569,13 @@ void SwViewShell::InvalidateWindows( const SwRect &rRect ) + } + } + ++const SwRect& SwViewShell::VisArea() const ++{ ++ // when using the tiled rendering, consider the entire document as our ++ // visible area ++ return isTiledRendering()? GetLayout()->Frm(): maVisArea; ++} ++ + void SwViewShell::MakeVisible( const SwRect &rRect ) + { + if ( !VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareWin(*this) ) +-- +2.12.0 + diff --git a/SOURCES/0116-sysui-depend-on-libreofficekitgtk-for-introspection.patch b/SOURCES/0116-sysui-depend-on-libreofficekitgtk-for-introspection.patch new file mode 100644 index 0000000..7e258a4 --- /dev/null +++ b/SOURCES/0116-sysui-depend-on-libreofficekitgtk-for-introspection.patch @@ -0,0 +1,30 @@ +From d876fa68f90b10608e77f34a71d37e772df8184b Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 17 Sep 2015 20:13:38 +0200 +Subject: [PATCH 116/398] sysui: depend on libreofficekitgtk for introspection + +Change-Id: I028d4e6d3c5fd57ae412fcfca5184722e4283524 +Reviewed-on: https://gerrit.libreoffice.org/18671 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit 9b3495b4af679bd868e03e707100948bc4ba6019) +--- + sysui/CustomTarget_share.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysui/CustomTarget_share.mk b/sysui/CustomTarget_share.mk +index e4dde6fbaaaf..84907d1003c4 100644 +--- a/sysui/CustomTarget_share.mk ++++ b/sysui/CustomTarget_share.mk +@@ -175,7 +175,7 @@ $(share_WORKDIR)/%/openoffice.sh: $(share_SRCDIR)/share/openoffice.sh + + $(share_WORKDIR)/%/create_tree.sh: $(share_SRCDIR)/share/create_tree.sh $(share_WORKDIR)/%/mimelnklist \ + $(share_WORKDIR)/%/openoffice.org.xml $(share_WORKDIR)/%/openoffice.applications $(share_WORKDIR)/%/openoffice.mime \ +- $(share_WORKDIR)/%/openoffice.keys $(share_WORKDIR)/%/launcherlist ++ $(share_WORKDIR)/%/openoffice.keys $(share_WORKDIR)/%/launcherlist $(if $(INTROSPECTION_SCANNER),$(call gb_Library_get_target,libreofficekitgtk)) + mkdir -p $(dir $@) + $(call gb_Output_announce,$(subst $(WORKDIR)/,,$@),$(true),CAT,1) + echo "#!/bin/sh" > $@ +-- +2.12.0 + diff --git a/SOURCES/0117-vcl-ITiledRenderable-add-getCurrentViewShell-and-imp.patch b/SOURCES/0117-vcl-ITiledRenderable-add-getCurrentViewShell-and-imp.patch new file mode 100644 index 0000000..015f8dd --- /dev/null +++ b/SOURCES/0117-vcl-ITiledRenderable-add-getCurrentViewShell-and-imp.patch @@ -0,0 +1,76 @@ +From 7f7c2c952d264e515923a533d2e36dd4a42bcd92 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Sep 2015 12:50:48 +0200 +Subject: [PATCH 117/398] vcl::ITiledRenderable: add getCurrentViewShell() and + implement it for Writer + +Change-Id: Ic936746f3d473e15f5a1589cba35173778b442c6 +(cherry picked from commit 7b0de91faaaf9a051e082ec7ea5024474f4a1299) +--- + include/vcl/ITiledRenderable.hxx | 10 ++++++++++ + sw/inc/unotxdoc.hxx | 2 ++ + sw/source/uibase/uno/unotxdoc.cxx | 5 +++++ + 3 files changed, 17 insertions(+) + +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 8824361f9f70..a31d808437af 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -16,6 +16,8 @@ + #include + #include + ++class SfxViewShell; ++ + namespace vcl + { + +@@ -139,8 +141,16 @@ public: + * @see lok::Document::resetSelection(). + */ + virtual void resetSelection() = 0; ++ ++ /// Get the currently active view shell of the document. ++ virtual SfxViewShell* getCurrentViewShell() ++ { ++ return 0; ++ } + }; + + } // namespace vcl + + #endif // INCLUDED_VCL_ITILEDRENDERABLE_HXX ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index 9f0b03b3af38..71dbb4f2fd5a 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -431,6 +431,8 @@ public: + virtual void setGraphicSelection(int nType, int nX, int nY) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::resetSelection(). + virtual void resetSelection() SAL_OVERRIDE; ++ /// @see vcl::ITiledRenderable::getCurrentViewShell(). ++ virtual SfxViewShell* getCurrentViewShell() SAL_OVERRIDE; + + // ::com::sun::star::tiledrendering::XTiledRenderable + virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) SAL_OVERRIDE; +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index d6315d2964ae..8dce9b5589d6 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3410,6 +3410,11 @@ void SwXTextDocument::resetSelection() + pWrtShell->ResetSelect(0, false); + } + ++SfxViewShell* SwXTextDocument::getCurrentViewShell() ++{ ++ return pDocShell->GetView(); ++} ++ + void SAL_CALL SwXTextDocument::paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) + { + SystemGraphicsData aData; +-- +2.12.0 + diff --git a/SOURCES/0118-sfx2-add-SfxLokHelper.patch b/SOURCES/0118-sfx2-add-SfxLokHelper.patch new file mode 100644 index 0000000..0604baf --- /dev/null +++ b/SOURCES/0118-sfx2-add-SfxLokHelper.patch @@ -0,0 +1,95 @@ +From 5bb7ebf9192f57c0de9eb58652dca638b34d2fe3 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Sep 2015 14:36:38 +0200 +Subject: [PATCH 118/398] sfx2: add SfxLokHelper + +This is meant to be a class that is visible outside sfx2 (so e.g. +desktop can use it later), but has access to various sfx2 internals. + +Change-Id: I83204963492b11c1c4a621e86528a64fba27acf3 +(cherry picked from commit 58b5c13b00cd4d881e1d6313316cc621198a4b04) +--- + include/sfx2/lokhelper.hxx | 21 +++++++++++++++++++++ + sfx2/Library_sfx.mk | 1 + + sfx2/source/view/lokhelper.cxx | 29 +++++++++++++++++++++++++++++ + 3 files changed, 51 insertions(+) + create mode 100644 include/sfx2/lokhelper.hxx + create mode 100644 sfx2/source/view/lokhelper.cxx + +diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx +new file mode 100644 +index 000000000000..d439bcedce19 +--- /dev/null ++++ b/include/sfx2/lokhelper.hxx +@@ -0,0 +1,21 @@ ++/* -*- 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 ++ ++class SfxViewShell; ++ ++class SFX2_DLLPUBLIC SfxLokHelper ++{ ++public: ++ /// Create a new view shell for pViewShell's object shell. ++ static int createView(SfxViewShell* pViewShell); ++}; ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk +index 0a1100e1f51a..40dedd502ba0 100644 +--- a/sfx2/Library_sfx.mk ++++ b/sfx2/Library_sfx.mk +@@ -290,6 +290,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\ + sfx2/source/view/frame2 \ + sfx2/source/view/frmload \ + sfx2/source/view/ipclient \ ++ sfx2/source/view/lokhelper \ + sfx2/source/view/printer \ + sfx2/source/view/sfxbasecontroller \ + sfx2/source/view/userinputinterception \ +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +new file mode 100644 +index 000000000000..4f500e0388ef +--- /dev/null ++++ b/sfx2/source/view/lokhelper.cxx +@@ -0,0 +1,29 @@ ++/* -*- 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 ++ ++int SfxLokHelper::createView(SfxViewShell* pViewShell) ++{ ++ SfxViewFrame* pViewFrame = pViewShell->GetViewFrame(); ++ SfxRequest aRequest(pViewFrame, SID_NEWWINDOW); ++ pViewFrame->ExecView_Impl(aRequest); ++ ++ // The SfxViewShell ctor always puts the view shell to the end of the vector. ++ SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); ++ return rViewArr.size() - 1; ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0119-lok-Document-add-createView.patch b/SOURCES/0119-lok-Document-add-createView.patch new file mode 100644 index 0000000..e0d8b59 --- /dev/null +++ b/SOURCES/0119-lok-Document-add-createView.patch @@ -0,0 +1,135 @@ +From 4692ad2debc22ba83d79b6c13e22e694f33b5a03 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Sep 2015 14:36:56 +0200 +Subject: [PATCH 119/398] lok::Document: add createView() + +Change-Id: Ic871ec41992b611b10958799b2dc12375a91efe4 +(cherry picked from commit 655c7877a0650b7bfd04a3294cdf92bc7ab94055) +--- + desktop/source/lib/init.cxx | 19 +++++++++++++++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 3 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 10 ++++++++++ + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 14 ++++++++++++++ + 4 files changed, 46 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 87471454b5d2..ea5de4df1a5c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -53,6 +53,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -249,6 +250,7 @@ static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + static void doc_resetSelection (LibreOfficeKitDocument* pThis); + static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand); + ++static int doc_createView(LibreOfficeKitDocument* pThis); + + LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : + mxComponent( xComponent ) +@@ -280,6 +282,8 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference resetSelection = doc_resetSelection; + m_pDocumentClass->getCommandValues = doc_getCommandValues; + ++ m_pDocumentClass->createView = doc_createView; ++ + gDocumentClass = m_pDocumentClass; + } + pClass = m_pDocumentClass.get(); +@@ -1032,6 +1036,21 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + } + } + ++static int doc_createView(LibreOfficeKitDocument* pThis) ++{ ++ SolarMutexGuard aGuard; ++ ++ ITiledRenderable* pDoc = getTiledRenderable(pThis); ++ if (!pDoc) ++ { ++ gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; ++ return -1; ++ } ++ ++ SfxViewShell* pViewShell = pDoc->getCurrentViewShell(); ++ return SfxLokHelper::createView(pViewShell); ++} ++ + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 8060f0e6ec7c..eae35374e032 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -162,6 +162,9 @@ struct _LibreOfficeKitDocumentClass + + /// @see lok::Document:getStyles + char* (*getCommandValues) (LibreOfficeKitDocument* pThis, const char* pCommand); ++ ++ /// @see lok::Document::createView(). ++ int (*createView) (LibreOfficeKitDocument* pThis); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 44599948e659..1a8b002ecba6 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -257,6 +257,16 @@ public: + { + return mpDoc->pClass->getCommandValues(mpDoc, pCommand); + } ++ ++ /** ++ * Create a new view for an existing document. ++ * By default a loaded document has 1 view. ++ * @return the ID of the new view. ++ */ ++ int createView() ++ { ++ return mpDoc->pClass->createView(mpDoc); ++ } + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index ab33fc703731..60c5281974f4 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -147,6 +147,14 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + } + } + ++/// Calls lok::Document::createView(). ++static void createView(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++{ ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); ++ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); ++ pDocument->pClass->createView(pDocument); ++} ++ + /// Our GtkClipboardGetFunc implementation for HTML. + static void htmlGetFunc(GtkClipboard* /*pClipboard*/, GtkSelectionData* pSelectionData, guint /*info*/, gpointer pUserData) + { +@@ -554,6 +562,12 @@ int main( int argc, char* argv[] ) + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pFindButton, -1); + g_signal_connect(G_OBJECT(pFindButton), "clicked", G_CALLBACK(toggleFindbar), NULL); + ++ GtkToolItem* pNewViewButton = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pNewViewButton), "view-continuous-symbolic"); ++ gtk_tool_item_set_tooltip_text(pNewViewButton, "New View"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pNewViewButton, -1); ++ g_signal_connect(G_OBJECT(pNewViewButton), "clicked", G_CALLBACK(createView), NULL); ++ + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + + pBold = gtk_toggle_tool_button_new(); +-- +2.12.0 + diff --git a/SOURCES/0120-gtktiledviewer-add-button-tooltips.patch b/SOURCES/0120-gtktiledviewer-add-button-tooltips.patch new file mode 100644 index 0000000..12942ff --- /dev/null +++ b/SOURCES/0120-gtktiledviewer-add-button-tooltips.patch @@ -0,0 +1,88 @@ +From 34b72ed4941d44455c324e03ed19469ab21c01c8 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Sep 2015 15:10:22 +0200 +Subject: [PATCH 120/398] gtktiledviewer: add button tooltips + +Change-Id: Ifad67adf80761118bbbfb110cbadd493214fee93 +(cherry picked from commit 179a0d0ea0ec4251152fe4c5e0fb3fd53f6f7967) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 60c5281974f4..dd369f5e7fb1 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -512,16 +512,19 @@ int main( int argc, char* argv[] ) + + GtkToolItem* pZoomIn = gtk_tool_button_new( NULL, NULL ); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomIn), "zoom-in-symbolic"); ++ gtk_tool_item_set_tooltip_text(pZoomIn, "Zoom In"); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoomIn, 0); + g_signal_connect( G_OBJECT(pZoomIn), "clicked", G_CALLBACK(changeZoom), NULL ); + + GtkToolItem* pZoom1 = gtk_tool_button_new( NULL, NULL ); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoom1), "zoom-original-symbolic"); ++ gtk_tool_item_set_tooltip_text(pZoom1, "Normal Size"); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoom1, -1); + g_signal_connect( G_OBJECT(pZoom1), "clicked", G_CALLBACK(changeZoom), NULL ); + + GtkToolItem* pZoomOut = gtk_tool_button_new( NULL, NULL ); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomOut), "zoom-out-symbolic"); ++ gtk_tool_item_set_tooltip_text(pZoomOut, "Zoom Out"); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoomOut, -1); + g_signal_connect( G_OBJECT(pZoomOut), "clicked", G_CALLBACK(changeZoom), NULL ); + +@@ -548,17 +551,20 @@ int main( int argc, char* argv[] ) + // Cut, copy & paste. + GtkToolItem* pCopyButton = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pCopyButton), "edit-copy-symbolic"); ++ gtk_tool_item_set_tooltip_text(pCopyButton, "Copy"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pCopyButton, -1); + g_signal_connect(G_OBJECT(pCopyButton), "clicked", G_CALLBACK(doCopy), NULL); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + + pEnableEditing = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pEnableEditing), "insert-text-symbolic"); ++ gtk_tool_item_set_tooltip_text(pEnableEditing, "Edit"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pEnableEditing, -1); + g_signal_connect(G_OBJECT(pEnableEditing), "toggled", G_CALLBACK(toggleEditing), NULL); + + GtkToolItem* pFindButton = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindButton), "edit-find-symbolic"); ++ gtk_tool_item_set_tooltip_text(pFindButton, "Find"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pFindButton, -1); + g_signal_connect(G_OBJECT(pFindButton), "clicked", G_CALLBACK(toggleFindbar), NULL); + +@@ -572,24 +578,28 @@ int main( int argc, char* argv[] ) + + pBold = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pBold), "format-text-bold-symbolic"); ++ gtk_tool_item_set_tooltip_text(pBold, "Bold"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pBold, -1); + g_signal_connect(G_OBJECT(pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pBold, ".uno:Bold"); + + pItalic = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pItalic), "format-text-italic-symbolic"); ++ gtk_tool_item_set_tooltip_text(pItalic, "Italic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pItalic, -1); + g_signal_connect(G_OBJECT(pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pItalic, ".uno:Italic"); + + pUnderline = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pUnderline), "format-text-underline-symbolic"); ++ gtk_tool_item_set_tooltip_text(pUnderline, "Underline"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pUnderline, -1); + g_signal_connect(G_OBJECT(pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pUnderline, ".uno:Underline"); + + pStrikethrough = gtk_toggle_tool_button_new (); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pStrikethrough), "format-text-strikethrough-symbolic"); ++ gtk_tool_item_set_tooltip_text(pStrikethrough, "Strikethrough"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pStrikethrough, -1); + g_signal_connect(G_OBJECT(pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(pStrikethrough, ".uno:Strikeout"); +-- +2.12.0 + diff --git a/SOURCES/0121-lok-Office-add-getViews.patch b/SOURCES/0121-lok-Office-add-getViews.patch new file mode 100644 index 0000000..c2f6d8a --- /dev/null +++ b/SOURCES/0121-lok-Office-add-getViews.patch @@ -0,0 +1,160 @@ +From f0e5649a3d463f89903ad337a5f33f3a33e27478 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Sep 2015 15:43:17 +0200 +Subject: [PATCH 121/398] lok::Office: add getViews() + +Change-Id: Iabfb0f2a19106dc4a6bdae45f9e85d76c68a973e +(cherry picked from commit 2e523afe61f76d9b065a771e558683afb701b93b) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 13 +++++++++++++ + desktop/source/lib/init.cxx | 7 +++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 3 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 10 ++++++++++ + include/sfx2/lokhelper.hxx | 3 +++ + sfx2/source/view/lokhelper.cxx | 6 ++++++ + 6 files changed, 42 insertions(+) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index a08961403aac..d5616d566f6a 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + + #include "../../inc/lib/init.hxx" +@@ -50,6 +51,7 @@ public: + void runAllTests(); + void testGetStyles(); + void testGetFonts(); ++ void testCreateView(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(runAllTests); +@@ -83,6 +85,7 @@ void DesktopLOKTest::runAllTests() + { + testGetStyles(); + testGetFonts(); ++ testCreateView(); + } + + void DesktopLOKTest::testGetStyles() +@@ -134,6 +137,16 @@ void DesktopLOKTest::testGetFonts() + closeDoc(); + } + ++void DesktopLOKTest::testCreateView() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ CPPUNIT_ASSERT_EQUAL(1, SfxLokHelper::getViews()); ++ ++ pDocument->m_pDocumentClass->createView(pDocument); ++ CPPUNIT_ASSERT_EQUAL(2, SfxLokHelper::getViews()); ++ closeDoc(); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index ea5de4df1a5c..3554d46573bf 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -310,6 +310,7 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions (LibreOfficeKit* pThi + static void lo_registerCallback (LibreOfficeKit* pThis, + LibreOfficeKitCallback pCallback, + void* pData); ++static int lo_getViews(LibreOfficeKit* pThis); + + struct LibLibreOffice_Impl : public _LibreOfficeKit + { +@@ -333,6 +334,7 @@ struct LibLibreOffice_Impl : public _LibreOfficeKit + m_pOfficeClass->getError = lo_getError; + m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions; + m_pOfficeClass->registerCallback = lo_registerCallback; ++ m_pOfficeClass->getViews = lo_getViews; + + gOfficeClass = m_pOfficeClass; + } +@@ -450,6 +452,11 @@ static void lo_registerCallback (LibreOfficeKit* pThis, + pLib->mpCallbackData = pData; + } + ++static int lo_getViews(LibreOfficeKit* /*pThis*/) ++{ ++ return SfxLokHelper::getViews(); ++} ++ + static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const char* pFormat, const char* pFilterOptions) + { + LibLODocument_Impl* pDocument = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index eae35374e032..b59d3f8c9f5d 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -54,6 +54,9 @@ struct _LibreOfficeKitClass + void (*registerCallback) (LibreOfficeKit* pThis, + LibreOfficeKitCallback pCallback, + void* pData); ++ ++ /// @see lok::Office::getViews(). ++ int (*getViews) (LibreOfficeKit* pThis); + #endif + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 1a8b002ecba6..32f190227719 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -313,6 +313,16 @@ public: + { + return mpThis->pClass->getError(mpThis); + } ++ ++#ifdef LOK_USE_UNSTABLE_API ++ /** ++ * Get number of total views. ++ */ ++ inline int getViews() ++ { ++ return mpThis->pClass->getViews(mpThis); ++ } ++#endif + }; + + /// Factory method to create a lok::Office instance. +diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx +index d439bcedce19..bc3f43010c41 100644 +--- a/include/sfx2/lokhelper.hxx ++++ b/include/sfx2/lokhelper.hxx +@@ -16,6 +16,9 @@ class SFX2_DLLPUBLIC SfxLokHelper + public: + /// Create a new view shell for pViewShell's object shell. + static int createView(SfxViewShell* pViewShell); ++ ++ /// Total number of view shells. ++ static int getViews(); + }; + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +index 4f500e0388ef..1bb43d0ea02f 100644 +--- a/sfx2/source/view/lokhelper.cxx ++++ b/sfx2/source/view/lokhelper.cxx +@@ -26,4 +26,10 @@ int SfxLokHelper::createView(SfxViewShell* pViewShell) + return rViewArr.size() - 1; + } + ++int SfxLokHelper::getViews() ++{ ++ SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); ++ return rViewArr.size(); ++} ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0122-CppunitTest_desktop_lib-fix-reported-name-of-failed-.patch b/SOURCES/0122-CppunitTest_desktop_lib-fix-reported-name-of-failed-.patch new file mode 100644 index 0000000..f64dadd --- /dev/null +++ b/SOURCES/0122-CppunitTest_desktop_lib-fix-reported-name-of-failed-.patch @@ -0,0 +1,50 @@ +From 5f48949ddd73d547607e0e2b502146775efae75f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 14 Sep 2015 15:56:34 +0200 +Subject: [PATCH 122/398] CppunitTest_desktop_lib: fix reported name of failed + test + +Change-Id: Iaa9effdcf6d6c6b2292e3fc7b666afdb3678694d +(cherry picked from commit 4f62c14748c0e62ad0212e831d606ac32e694eca) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 12 +++--------- + 1 file changed, 3 insertions(+), 9 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index d5616d566f6a..8642f4491f9f 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -48,13 +48,14 @@ public: + LibLODocument_Impl* loadDoc(const char* pName); + void closeDoc(); + +- void runAllTests(); + void testGetStyles(); + void testGetFonts(); + void testCreateView(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); +- CPPUNIT_TEST(runAllTests); ++ CPPUNIT_TEST(testGetStyles); ++ CPPUNIT_TEST(testGetFonts); ++ CPPUNIT_TEST(testCreateView); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -81,13 +82,6 @@ void DesktopLOKTest::closeDoc() + } + } + +-void DesktopLOKTest::runAllTests() +-{ +- testGetStyles(); +- testGetFonts(); +- testCreateView(); +-} +- + void DesktopLOKTest::testGetStyles() + { + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); +-- +2.12.0 + diff --git a/SOURCES/0123-lok-Document-add-destroyView.patch b/SOURCES/0123-lok-Document-add-destroyView.patch new file mode 100644 index 0000000..0bdad34 --- /dev/null +++ b/SOURCES/0123-lok-Document-add-destroyView.patch @@ -0,0 +1,139 @@ +From 7da9e9d07f129c274f1d29db92be237a3e6f2e7f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 09:31:49 +0200 +Subject: [PATCH 123/398] lok::Document: add destroyView() + +Change-Id: Id9e92593217541b4123e95279019cec3c958056c +(cherry picked from commit 10a0cad9d6990abac507899a34fbcdeb466187f7) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 5 ++++- + desktop/source/lib/init.cxx | 9 +++++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 2 ++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 9 +++++++++ + include/sfx2/lokhelper.hxx | 2 ++ + sfx2/source/view/lokhelper.cxx | 12 ++++++++++++ + 6 files changed, 38 insertions(+), 1 deletion(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 8642f4491f9f..6baaa32239c9 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -136,8 +136,11 @@ void DesktopLOKTest::testCreateView() + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); + CPPUNIT_ASSERT_EQUAL(1, SfxLokHelper::getViews()); + +- pDocument->m_pDocumentClass->createView(pDocument); ++ int nId = pDocument->m_pDocumentClass->createView(pDocument); + CPPUNIT_ASSERT_EQUAL(2, SfxLokHelper::getViews()); ++ ++ pDocument->m_pDocumentClass->destroyView(pDocument, nId); ++ CPPUNIT_ASSERT_EQUAL(1, SfxLokHelper::getViews()); + closeDoc(); + } + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 3554d46573bf..3b1286e5944d 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -251,6 +251,7 @@ static void doc_resetSelection (LibreOfficeKitDocument* pThis); + static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand); + + static int doc_createView(LibreOfficeKitDocument* pThis); ++static void doc_destroyView(LibreOfficeKitDocument* pThis, int nId); + + LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : + mxComponent( xComponent ) +@@ -283,6 +284,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference getCommandValues = doc_getCommandValues; + + m_pDocumentClass->createView = doc_createView; ++ m_pDocumentClass->destroyView = doc_destroyView; + + gDocumentClass = m_pDocumentClass; + } +@@ -1058,6 +1060,13 @@ static int doc_createView(LibreOfficeKitDocument* pThis) + return SfxLokHelper::createView(pViewShell); + } + ++static void doc_destroyView(LibreOfficeKitDocument* /*pThis*/, int nId) ++{ ++ SolarMutexGuard aGuard; ++ ++ SfxLokHelper::destroyView(nId); ++} ++ + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index b59d3f8c9f5d..7f41d13ff393 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -168,6 +168,8 @@ struct _LibreOfficeKitDocumentClass + + /// @see lok::Document::createView(). + int (*createView) (LibreOfficeKitDocument* pThis); ++ /// @see lok::Document::destroyView(). ++ void (*destroyView) (LibreOfficeKitDocument* pThis, int nId); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 32f190227719..3e1a0ac20b07 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -267,6 +267,15 @@ public: + { + return mpDoc->pClass->createView(mpDoc); + } ++ ++ /** ++ * Destroy a view of an existring document. ++ * @param nId a view ID, returned by createView(). ++ */ ++ void destroyView(int nId) ++ { ++ mpDoc->pClass->destroyView(mpDoc, nId); ++ } + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx +index bc3f43010c41..9430cd5665d8 100644 +--- a/include/sfx2/lokhelper.hxx ++++ b/include/sfx2/lokhelper.hxx +@@ -16,6 +16,8 @@ class SFX2_DLLPUBLIC SfxLokHelper + public: + /// Create a new view shell for pViewShell's object shell. + static int createView(SfxViewShell* pViewShell); ++ /// Destroy a view shell from the global shell list. ++ static void destroyView(size_t nId); + + /// Total number of view shells. + static int getViews(); +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +index 1bb43d0ea02f..557478a78ae6 100644 +--- a/sfx2/source/view/lokhelper.cxx ++++ b/sfx2/source/view/lokhelper.cxx +@@ -26,6 +26,18 @@ int SfxLokHelper::createView(SfxViewShell* pViewShell) + return rViewArr.size() - 1; + } + ++void SfxLokHelper::destroyView(size_t nId) ++{ ++ SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); ++ if (nId > rViewArr.size() - 1) ++ return; ++ ++ SfxViewShell* pViewShell = rViewArr[nId]; ++ SfxViewFrame* pViewFrame = pViewShell->GetViewFrame(); ++ SfxRequest aRequest(pViewFrame, SID_CLOSEWIN); ++ pViewFrame->Exec_Impl(aRequest); ++} ++ + int SfxLokHelper::getViews() + { + SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); +-- +2.12.0 + diff --git a/SOURCES/0124-sfx2-add-missing-header-guard.patch b/SOURCES/0124-sfx2-add-missing-header-guard.patch new file mode 100644 index 0000000..828d655 --- /dev/null +++ b/SOURCES/0124-sfx2-add-missing-header-guard.patch @@ -0,0 +1,35 @@ +From a4680c754fd012d803f2c86144593275d3640f9a Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 10:31:20 +0200 +Subject: [PATCH 124/398] sfx2: add missing header guard + +Change-Id: Ide261670be475f5d54d9d12c701ad82470396aeb +(cherry picked from commit d990a8762e5e67747e169103bc8b9a40605afa81) +--- + include/sfx2/lokhelper.hxx | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx +index 9430cd5665d8..b57cb7d75b23 100644 +--- a/include/sfx2/lokhelper.hxx ++++ b/include/sfx2/lokhelper.hxx +@@ -7,6 +7,9 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + ++#ifndef INCLUDED_SFX2_LOKHELPER_HXX ++#define INCLUDED_SFX2_LOKHELPER_HXX ++ + #include + + class SfxViewShell; +@@ -23,4 +26,6 @@ public: + static int getViews(); + }; + ++#endif ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0125-gtktiledviewer-these-globals-can-be-static.patch b/SOURCES/0125-gtktiledviewer-these-globals-can-be-static.patch new file mode 100644 index 0000000..01fe697 --- /dev/null +++ b/SOURCES/0125-gtktiledviewer-these-globals-can-be-static.patch @@ -0,0 +1,42 @@ +From 08fa99f5d2eba0159b34d401b179f294ac483125 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 10:59:58 +0200 +Subject: [PATCH 125/398] gtktiledviewer: these globals can be static + +Change-Id: Ife0a4bb1102f6135e297dc69ba5b52b89a5dd9dd +(cherry picked from commit 20df29e660139fc27d50fe006202f7ea78a3903a) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index dd369f5e7fb1..2bafd24f8b08 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -38,17 +38,17 @@ static GtkToolItem* pItalic; + static GtkToolItem* pUnderline; + static GtkToolItem* pStrikethrough; + static GtkWidget* pScrolledWindow; +-std::map g_aToolItemCommandNames; +-std::map g_aCommandNameToolItems; +-bool g_bToolItemBroadcast = true; ++static std::map g_aToolItemCommandNames; ++static std::map g_aCommandNameToolItems; ++static bool g_bToolItemBroadcast = true; + static GtkWidget* pVBox; + static GtkComboBoxText* pPartSelector; + static GtkWidget* pPartModeComboBox; + /// Should the part selector avoid calling lok::Document::setPart()? + static bool g_bPartSelectorBroadcast = true; +-GtkWidget* pFindbar; +-GtkWidget* pFindbarEntry; +-GtkWidget* pFindbarLabel; ++static GtkWidget* pFindbar; ++static GtkWidget* pFindbarEntry; ++static GtkWidget* pFindbarLabel; + + static void lcl_registerToolItem(GtkToolItem* pItem, const std::string& rName) + { +-- +2.12.0 + diff --git a/SOURCES/0126-gtktiledviewer-allow-multiple-DocView-instances.patch b/SOURCES/0126-gtktiledviewer-allow-multiple-DocView-instances.patch new file mode 100644 index 0000000..b0c9429 --- /dev/null +++ b/SOURCES/0126-gtktiledviewer-allow-multiple-DocView-instances.patch @@ -0,0 +1,321 @@ +From f5e3ccb7b5ccdc9b1064938cc4ce65b677255e3e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 11:55:09 +0200 +Subject: [PATCH 126/398] gtktiledviewer: allow multiple DocView instances + +Change-Id: I4e8a08d71a94445e8fd30563867a2741cad862e5 +(cherry picked from commit f6ef6af23db8b718ef75f66680f696396fa74eaf) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 109 +++++++++++++-------- + 1 file changed, 70 insertions(+), 39 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 2bafd24f8b08..096458a93dce 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -30,7 +30,6 @@ static int help() + return 1; + } + +-static GtkWidget* pDocView; + static GtkWidget* pStatusBar; + static GtkToolItem* pEnableEditing; + static GtkToolItem* pBold; +@@ -50,6 +49,24 @@ static GtkWidget* pFindbar; + static GtkWidget* pFindbarEntry; + static GtkWidget* pFindbarLabel; + ++class TiledWindow ++{ ++public: ++ GtkWidget* m_pDocView; ++ ++ TiledWindow() ++ : m_pDocView(0) ++ { ++ } ++}; ++ ++static std::map g_aWindows; ++ ++static TiledWindow& lcl_getTiledWindow(GtkWidget* pWidget) ++{ ++ return g_aWindows[gtk_widget_get_toplevel(pWidget)]; ++} ++ + static void lcl_registerToolItem(GtkToolItem* pItem, const std::string& rName) + { + g_aToolItemCommandNames[pItem] = rName; +@@ -60,7 +77,7 @@ const float fZooms[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 5.0 }; + + + /// Get the visible area of the scrolled window +-static void getVisibleAreaTwips(GdkRectangle* pArea) ++static void getVisibleAreaTwips(GtkWidget* pDocView, GdkRectangle* pArea) + { + #if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); +@@ -79,6 +96,9 @@ static void getVisibleAreaTwips(GdkRectangle* pArea) + + static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + { ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ GtkWidget* pDocView = rWindow.m_pDocView; ++ + const char *sName = gtk_tool_button_get_icon_name( GTK_TOOL_BUTTON(pButton) ); + + float fZoom = 0; +@@ -125,9 +145,11 @@ static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + } + + /// User clicked on the button -> inform LOKDocView. +-static void toggleEditing(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++static void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/) + { +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + bool bActive = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pEnableEditing)); + if (bool(lok_doc_view_get_edit(pLOKDocView)) != bActive) + lok_doc_view_set_edit(pLOKDocView, bActive); +@@ -148,9 +170,10 @@ static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) + } + + /// Calls lok::Document::createView(). +-static void createView(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++static void createView(GtkWidget* pButton, gpointer /*pItem*/) + { +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); + pDocument->pClass->createView(pDocument); + } +@@ -185,14 +208,15 @@ static void clipboardSetHtml(GtkClipboard* pClipboard, const char* pSelection) + } + + /// Handler for the copy button: write clipboard. +-static void doCopy(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++static void doCopy(GtkWidget* pButton, gpointer /*pItem*/) + { +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); + char* pUsedFormat = 0; + char* pSelection = pDocument->pClass->getTextSelection(pDocument, "text/html", &pUsedFormat); + +- GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(pDocView), GDK_SELECTION_CLIPBOARD); ++ GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(rWindow.m_pDocView), GDK_SELECTION_CLIPBOARD); + std::string aUsedFormat(pUsedFormat); + if (aUsedFormat == "text/plain;charset=utf-8") + gtk_clipboard_set_text(pClipboard, pSelection, -1); +@@ -204,7 +228,7 @@ static void doCopy(GtkWidget* /*pButton*/, gpointer /*pItem*/) + + + /// Searches for the next or previous text of pFindbarEntry. +-static void doSearch(bool bBackwards) ++static void doSearch(GtkWidget* pButton, bool bBackwards) + { + GtkEntry* pEntry = GTK_ENTRY(pFindbarEntry); + const char* pText = gtk_entry_get_text(pEntry); +@@ -214,9 +238,10 @@ static void doSearch(bool bBackwards) + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards); + +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + GdkRectangle aArea; +- getVisibleAreaTwips(&aArea); ++ getVisibleAreaTwips(rWindow.m_pDocView, &aArea); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/type", '/'), "long"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/value", '/'), aArea.x); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/type", '/'), "long"); +@@ -229,19 +254,19 @@ static void doSearch(bool bBackwards) + } + + /// Click handler for the search next button. +-static void signalSearchNext(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++static void signalSearchNext(GtkWidget* pButton, gpointer /*pItem*/) + { +- doSearch(/*bBackwards=*/false); ++ doSearch(pButton, /*bBackwards=*/false); + } + + /// Click handler for the search previous button. +-static void signalSearchPrev(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++static void signalSearchPrev(GtkWidget* pButton, gpointer /*pItem*/) + { +- doSearch(/*bBackwards=*/true); ++ doSearch(pButton, /*bBackwards=*/true); + } + + /// Handles the key-press-event of the search entry widget. +-static gboolean signalFindbar(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpointer /*pData*/) ++static gboolean signalFindbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer /*pData*/) + { + gtk_label_set_text(GTK_LABEL(pFindbarLabel), ""); + switch(pEvent->keyval) +@@ -249,7 +274,7 @@ static gboolean signalFindbar(GtkWidget* /*pWidget*/, GdkEventKey* pEvent, gpoin + case GDK_KEY_Return: + { + // Search forward. +- doSearch(/*bBackwards=*/false); ++ doSearch(pWidget, /*bBackwards=*/false); + return TRUE; + } + case GDK_KEY_Escape: +@@ -330,7 +355,7 @@ static void signalHyperlink(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointe + } + + /// Cursor position changed +-static void cursorChanged(LOKDocView* /*pDocView*/, gint nX, gint nY, ++static void cursorChanged(LOKDocView* pDocView, gint nX, gint nY, + gint /*nWidth*/, gint /*nHeight*/, gpointer /*pData*/) + { + GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); +@@ -339,7 +364,7 @@ static void cursorChanged(LOKDocView* /*pDocView*/, gint nX, gint nY, + gdouble upper; + gint x = -1, y = -1; + +- getVisibleAreaTwips(&visArea); ++ getVisibleAreaTwips(GTK_WIDGET(pDocView), &visArea); + + // check vertically + if (nY < visArea.y) +@@ -381,7 +406,8 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + { + if (g_bToolItemBroadcast) + { +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(pDocView); ++ TiledWindow& rWindow = lcl_getTiledWindow(pWidget); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + GtkToolItem* pItem = GTK_TOOL_ITEM(pWidget); + const std::string& rString = g_aToolItemCommandNames[pItem]; + g_info("toggleToolItem: lok_doc_view_post_command('%s')", rString.c_str()); +@@ -389,13 +415,13 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + } + } + +-static void populatePartSelector() ++static void populatePartSelector(LOKDocView* pLOKDocView) + { + gtk_list_store_clear( GTK_LIST_STORE( + gtk_combo_box_get_model( + GTK_COMBO_BOX(pPartSelector) )) ); + +- if ( !pDocView ) ++ if (!pLOKDocView) + { + return; + } +@@ -403,35 +429,35 @@ static void populatePartSelector() + const int nMaxLength = 50; + char sText[nMaxLength]; + +- int nParts = lok_doc_view_get_parts( LOK_DOC_VIEW(pDocView) ); ++ int nParts = lok_doc_view_get_parts(pLOKDocView); + for ( int i = 0; i < nParts; i++ ) + { +- char* pName = lok_doc_view_get_part_name( LOK_DOC_VIEW(pDocView), i ); ++ char* pName = lok_doc_view_get_part_name(pLOKDocView, i); + assert( pName ); + snprintf( sText, nMaxLength, "%i (%s)", i+1, pName ); + free( pName ); + + gtk_combo_box_text_append_text( pPartSelector, sText ); + } +- gtk_combo_box_set_active( GTK_COMBO_BOX(pPartSelector), +- lok_doc_view_get_part( LOK_DOC_VIEW(pDocView) ) ); ++ gtk_combo_box_set_active(GTK_COMBO_BOX(pPartSelector), lok_doc_view_get_part(pLOKDocView)); + } + +-static void signalSize(LOKDocView* /*pLOKDocView*/, gpointer /*pData*/) ++static void signalSize(LOKDocView* pLOKDocView, gpointer /*pData*/) + { + g_bPartSelectorBroadcast = false; +- populatePartSelector(); ++ populatePartSelector(pLOKDocView); + g_bPartSelectorBroadcast = true; + } + + static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + { + int nPart = gtk_combo_box_get_active( GTK_COMBO_BOX(pSelector) ); ++ TiledWindow& rWindow = lcl_getTiledWindow(pSelector); + +- if (g_bPartSelectorBroadcast && pDocView) ++ if (g_bPartSelectorBroadcast && rWindow.m_pDocView) + { +- lok_doc_view_set_part( LOK_DOC_VIEW(pDocView), nPart ); +- lok_doc_view_reset_view( LOK_DOC_VIEW(pDocView) ); ++ lok_doc_view_set_part( LOK_DOC_VIEW(rWindow.m_pDocView), nPart ); ++ lok_doc_view_reset_view( LOK_DOC_VIEW(rWindow.m_pDocView) ); + } + } + +@@ -453,32 +479,33 @@ static void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ ) + // I.e. the ordering above should match the enum member ordering. + LibreOfficeKitPartMode ePartMode = + LibreOfficeKitPartMode( gtk_combo_box_get_active( GTK_COMBO_BOX(pSelector) ) ); ++ TiledWindow& rWindow = lcl_getTiledWindow(pSelector); + +- if ( pDocView ) ++ if ( rWindow.m_pDocView ) + { +- lok_doc_view_set_partmode( LOK_DOC_VIEW(pDocView), ePartMode ); ++ lok_doc_view_set_partmode( LOK_DOC_VIEW(rWindow.m_pDocView), ePartMode ); + } + } + + static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpointer /*userdata*/) + { +- LOKDocView* pDocView1 = LOK_DOC_VIEW (source_object); ++ LOKDocView* pDocView = LOK_DOC_VIEW (source_object); + GError* error = NULL; + GList *focusChain = NULL; + +- if (!lok_doc_view_open_document_finish(pDocView1, res, &error)) ++ if (!lok_doc_view_open_document_finish(pDocView, res, &error)) + { + g_warning ("Error occurred while opening the document : %s", error->message); + g_error_free (error); + } + +- populatePartSelector(); ++ populatePartSelector(pDocView); + populatePartModeSelector( GTK_COMBO_BOX_TEXT(pPartModeComboBox) ); + // Connect these signals after populating the selectors, to avoid re-rendering on setting the default part/partmode. + g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0); + g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0); + +- focusChain = g_list_append( focusChain, pDocView1 ); ++ focusChain = g_list_append( focusChain, pDocView ); + gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain ); + + gtk_widget_hide (pStatusBar); +@@ -639,7 +666,7 @@ int main( int argc, char* argv[] ) + gtk_box_pack_end(GTK_BOX(pVBox), pFindbar, FALSE, FALSE, 0); + + // Docview +- pDocView = lok_doc_view_new (argv[1], NULL, NULL); ++ GtkWidget* pDocView = lok_doc_view_new (argv[1], NULL, NULL); + #if GLIB_CHECK_VERSION(2,40,0) + g_assert_nonnull(pDocView); + #endif +@@ -674,6 +701,10 @@ int main( int argc, char* argv[] ) + // Hide the findbar by default. + gtk_widget_hide(pFindbar); + ++ TiledWindow aWindow; ++ aWindow.m_pDocView = pDocView; ++ g_aWindows[pWindow] = aWindow; ++ + lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView ); + + gtk_main(); +-- +2.12.0 + diff --git a/SOURCES/0127-gtktiledviewer-allow-multiple-status-bars.patch b/SOURCES/0127-gtktiledviewer-allow-multiple-status-bars.patch new file mode 100644 index 0000000..6d6ba0a --- /dev/null +++ b/SOURCES/0127-gtktiledviewer-allow-multiple-status-bars.patch @@ -0,0 +1,92 @@ +From dbf2d5061ddcf8528b1e6e9944ea159fe5ea6afd Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 12:10:03 +0200 +Subject: [PATCH 127/398] gtktiledviewer: allow multiple status bars + +Change-Id: I84c4102937deee662814c41607ee8de380a067f2 +(cherry picked from commit 36fa8d443a9ad87ee7077be7263870fab9dd6261) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 096458a93dce..2559d124c72a 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -30,7 +30,6 @@ static int help() + return 1; + } + +-static GtkWidget* pStatusBar; + static GtkToolItem* pEnableEditing; + static GtkToolItem* pBold; + static GtkToolItem* pItalic; +@@ -49,13 +48,16 @@ static GtkWidget* pFindbar; + static GtkWidget* pFindbarEntry; + static GtkWidget* pFindbarLabel; + ++/// Represents all the state that is specific to one GtkWindow of this app. + class TiledWindow + { + public: + GtkWidget* m_pDocView; ++ GtkWidget* m_pStatusBar; + + TiledWindow() +- : m_pDocView(0) ++ : m_pDocView(0), ++ m_pStatusBar(0) + { + } + }; +@@ -461,8 +463,10 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + } + } + +-static void removeChildrenFromStatusbar(GtkWidget* children, gpointer) ++static void removeChildrenFromStatusbar(GtkWidget* children, gpointer pData) + { ++ GtkWidget* pStatusBar = static_cast(pData); ++ + gtk_container_remove(GTK_CONTAINER(pStatusBar), children); + } + +@@ -490,6 +494,7 @@ static void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ ) + static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpointer /*userdata*/) + { + LOKDocView* pDocView = LOK_DOC_VIEW (source_object); ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pDocView)); + GError* error = NULL; + GList *focusChain = NULL; + +@@ -508,7 +513,7 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo + focusChain = g_list_append( focusChain, pDocView ); + gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain ); + +- gtk_widget_hide (pStatusBar); ++ gtk_widget_hide(rWindow.m_pStatusBar); + } + + int main( int argc, char* argv[] ) +@@ -691,8 +696,8 @@ int main( int argc, char* argv[] ) + GtkWidget* pProgressBar = gtk_progress_bar_new (); + g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); + +- pStatusBar = gtk_statusbar_new (); +- gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, NULL); ++ GtkWidget* pStatusBar = gtk_statusbar_new (); ++ gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, pStatusBar); + gtk_container_add (GTK_CONTAINER(pVBox), pStatusBar); + gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); + gtk_widget_set_hexpand(pProgressBar, true); +@@ -703,6 +708,7 @@ int main( int argc, char* argv[] ) + + TiledWindow aWindow; + aWindow.m_pDocView = pDocView; ++ aWindow.m_pStatusBar = pStatusBar; + g_aWindows[pWindow] = aWindow; + + lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView ); +-- +2.12.0 + diff --git a/SOURCES/0128-gtktiledviwer-allow-GtkToolItems-in-multiple-windows.patch b/SOURCES/0128-gtktiledviwer-allow-GtkToolItems-in-multiple-windows.patch new file mode 100644 index 0000000..114c33d --- /dev/null +++ b/SOURCES/0128-gtktiledviwer-allow-GtkToolItems-in-multiple-windows.patch @@ -0,0 +1,181 @@ +From cc49e8fbf166ddea4944d1a5330f9d8442bee2e1 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 12:21:10 +0200 +Subject: [PATCH 128/398] gtktiledviwer: allow GtkToolItems in multiple windows + +Change-Id: I6c19a9bdd34163d12047929170e5cfa7bb9a5820 +(cherry picked from commit 91d67ec9a5cc2064b90a888ed962d215bee5dc2d) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 88 ++++++++++++---------- + 1 file changed, 48 insertions(+), 40 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 2559d124c72a..09f16da396af 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -30,11 +30,6 @@ static int help() + return 1; + } + +-static GtkToolItem* pEnableEditing; +-static GtkToolItem* pBold; +-static GtkToolItem* pItalic; +-static GtkToolItem* pUnderline; +-static GtkToolItem* pStrikethrough; + static GtkWidget* pScrolledWindow; + static std::map g_aToolItemCommandNames; + static std::map g_aCommandNameToolItems; +@@ -54,10 +49,20 @@ class TiledWindow + public: + GtkWidget* m_pDocView; + GtkWidget* m_pStatusBar; ++ GtkToolItem* m_pEnableEditing; ++ GtkToolItem* m_pBold; ++ GtkToolItem* m_pItalic; ++ GtkToolItem* m_pUnderline; ++ GtkToolItem* m_pStrikethrough; + + TiledWindow() + : m_pDocView(0), +- m_pStatusBar(0) ++ m_pStatusBar(0), ++ m_pEnableEditing(0), ++ m_pBold(0), ++ m_pItalic(0), ++ m_pUnderline(0), ++ m_pStrikethrough(0) + { + } + }; +@@ -152,7 +157,7 @@ static void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/) + TiledWindow& rWindow = lcl_getTiledWindow(pButton); + + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); +- bool bActive = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pEnableEditing)); ++ bool bActive = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(rWindow.m_pEnableEditing)); + if (bool(lok_doc_view_get_edit(pLOKDocView)) != bActive) + lok_doc_view_set_edit(pLOKDocView, bActive); + } +@@ -292,10 +297,12 @@ static gboolean signalFindbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer + /// LOKDocView changed edit state -> inform the tool button. + static void signalEdit(LOKDocView* pLOKDocView, gboolean bWasEdit, gpointer /*pData*/) + { ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); ++ + gboolean bEdit = lok_doc_view_get_edit(pLOKDocView); + g_info("signalEdit: %d -> %d", bWasEdit, lok_doc_view_get_edit(pLOKDocView)); +- if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pEnableEditing)) != bEdit) +- gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(pEnableEditing), bEdit); ++ if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(rWindow.m_pEnableEditing)) != bEdit) ++ gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(rWindow.m_pEnableEditing), bEdit); + } + + /// LOKDocView changed command state -> inform the tool button. +@@ -531,6 +538,7 @@ int main( int argc, char* argv[] ) + gtk_init( &argc, &argv ); + + GtkWidget *pWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL ); ++ TiledWindow aWindow; + gtk_window_set_title( GTK_WINDOW(pWindow), "LibreOfficeKit GTK Tiled Viewer" ); + gtk_window_set_default_size(GTK_WINDOW(pWindow), 1024, 768); + g_signal_connect( pWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL ); +@@ -588,7 +596,8 @@ int main( int argc, char* argv[] ) + g_signal_connect(G_OBJECT(pCopyButton), "clicked", G_CALLBACK(doCopy), NULL); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + +- pEnableEditing = gtk_toggle_tool_button_new(); ++ GtkToolItem* pEnableEditing = gtk_toggle_tool_button_new(); ++ aWindow.m_pEnableEditing = pEnableEditing; + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pEnableEditing), "insert-text-symbolic"); + gtk_tool_item_set_tooltip_text(pEnableEditing, "Edit"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pEnableEditing, -1); +@@ -608,33 +617,33 @@ int main( int argc, char* argv[] ) + + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + +- pBold = gtk_toggle_tool_button_new(); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pBold), "format-text-bold-symbolic"); +- gtk_tool_item_set_tooltip_text(pBold, "Bold"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pBold, -1); +- g_signal_connect(G_OBJECT(pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(pBold, ".uno:Bold"); +- +- pItalic = gtk_toggle_tool_button_new(); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pItalic), "format-text-italic-symbolic"); +- gtk_tool_item_set_tooltip_text(pItalic, "Italic"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pItalic, -1); +- g_signal_connect(G_OBJECT(pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(pItalic, ".uno:Italic"); +- +- pUnderline = gtk_toggle_tool_button_new(); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pUnderline), "format-text-underline-symbolic"); +- gtk_tool_item_set_tooltip_text(pUnderline, "Underline"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pUnderline, -1); +- g_signal_connect(G_OBJECT(pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(pUnderline, ".uno:Underline"); +- +- pStrikethrough = gtk_toggle_tool_button_new (); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pStrikethrough), "format-text-strikethrough-symbolic"); +- gtk_tool_item_set_tooltip_text(pStrikethrough, "Strikethrough"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pStrikethrough, -1); +- g_signal_connect(G_OBJECT(pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(pStrikethrough, ".uno:Strikeout"); ++ aWindow.m_pBold = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pBold), "format-text-bold-symbolic"); ++ gtk_tool_item_set_tooltip_text(aWindow.m_pBold, "Bold"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pBold, -1); ++ g_signal_connect(G_OBJECT(aWindow.m_pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(aWindow.m_pBold, ".uno:Bold"); ++ ++ aWindow.m_pItalic = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pItalic), "format-text-italic-symbolic"); ++ gtk_tool_item_set_tooltip_text(aWindow.m_pItalic, "Italic"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pItalic, -1); ++ g_signal_connect(G_OBJECT(aWindow.m_pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(aWindow.m_pItalic, ".uno:Italic"); ++ ++ aWindow.m_pUnderline = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pUnderline), "format-text-underline-symbolic"); ++ gtk_tool_item_set_tooltip_text(aWindow.m_pUnderline, "Underline"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pUnderline, -1); ++ g_signal_connect(G_OBJECT(aWindow.m_pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(aWindow.m_pUnderline, ".uno:Underline"); ++ ++ aWindow.m_pStrikethrough = gtk_toggle_tool_button_new (); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(aWindow.m_pStrikethrough), "format-text-strikethrough-symbolic"); ++ gtk_tool_item_set_tooltip_text(aWindow.m_pStrikethrough, "Strikethrough"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pStrikethrough, -1); ++ g_signal_connect(G_OBJECT(aWindow.m_pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(aWindow.m_pStrikethrough, ".uno:Strikeout"); + + gtk_box_pack_start( GTK_BOX(pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. + +@@ -672,6 +681,7 @@ int main( int argc, char* argv[] ) + + // Docview + GtkWidget* pDocView = lok_doc_view_new (argv[1], NULL, NULL); ++ aWindow.m_pDocView = pDocView; + #if GLIB_CHECK_VERSION(2,40,0) + g_assert_nonnull(pDocView); + #endif +@@ -697,6 +707,7 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); + + GtkWidget* pStatusBar = gtk_statusbar_new (); ++ aWindow.m_pStatusBar = pStatusBar; + gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, pStatusBar); + gtk_container_add (GTK_CONTAINER(pVBox), pStatusBar); + gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); +@@ -706,9 +717,6 @@ int main( int argc, char* argv[] ) + // Hide the findbar by default. + gtk_widget_hide(pFindbar); + +- TiledWindow aWindow; +- aWindow.m_pDocView = pDocView; +- aWindow.m_pStatusBar = pStatusBar; + g_aWindows[pWindow] = aWindow; + + lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView ); +-- +2.12.0 + diff --git a/SOURCES/0129-gtktiledviwer-tool-item-registration-is-per-window.patch b/SOURCES/0129-gtktiledviwer-tool-item-registration-is-per-window.patch new file mode 100644 index 0000000..b9aa574 --- /dev/null +++ b/SOURCES/0129-gtktiledviwer-tool-item-registration-is-per-window.patch @@ -0,0 +1,198 @@ +From 44a5de2fbdee39d81bb0fdbd74ba6179b40d77d9 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 12:36:49 +0200 +Subject: [PATCH 129/398] gtktiledviwer: tool item registration is per-window + +Change-Id: I11a6cda7b9b8949c48c201c4bd467b49f2f43ca5 +(cherry picked from commit bec8a1b74f91ffc579567f44a65b903bc854ec4f) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 71 +++++++++++++--------- + 1 file changed, 41 insertions(+), 30 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 09f16da396af..ef3aee008cae 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -30,10 +30,6 @@ static int help() + return 1; + } + +-static GtkWidget* pScrolledWindow; +-static std::map g_aToolItemCommandNames; +-static std::map g_aCommandNameToolItems; +-static bool g_bToolItemBroadcast = true; + static GtkWidget* pVBox; + static GtkComboBoxText* pPartSelector; + static GtkWidget* pPartModeComboBox; +@@ -54,6 +50,10 @@ public: + GtkToolItem* m_pItalic; + GtkToolItem* m_pUnderline; + GtkToolItem* m_pStrikethrough; ++ GtkWidget* m_pScrolledWindow; ++ std::map m_aToolItemCommandNames; ++ std::map m_aCommandNameToolItems; ++ bool m_bToolItemBroadcast; + + TiledWindow() + : m_pDocView(0), +@@ -62,7 +62,9 @@ public: + m_pBold(0), + m_pItalic(0), + m_pUnderline(0), +- m_pStrikethrough(0) ++ m_pStrikethrough(0), ++ m_pScrolledWindow(0), ++ m_bToolItemBroadcast(true) + { + } + }; +@@ -71,13 +73,15 @@ static std::map g_aWindows; + + static TiledWindow& lcl_getTiledWindow(GtkWidget* pWidget) + { +- return g_aWindows[gtk_widget_get_toplevel(pWidget)]; ++ GtkWidget* pToplevel = gtk_widget_get_toplevel(pWidget); ++ assert(g_aWindows.find(pToplevel) != g_aWindows.end()); ++ return g_aWindows[pToplevel]; + } + +-static void lcl_registerToolItem(GtkToolItem* pItem, const std::string& rName) ++static void lcl_registerToolItem(TiledWindow& rWindow, GtkToolItem* pItem, const std::string& rName) + { +- g_aToolItemCommandNames[pItem] = rName; +- g_aCommandNameToolItems[rName] = pItem; ++ rWindow.m_aToolItemCommandNames[pItem] = rName; ++ rWindow.m_aCommandNameToolItems[rName] = pItem; + } + + const float fZooms[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 5.0 }; +@@ -87,8 +91,10 @@ const float fZooms[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 5.0 }; + static void getVisibleAreaTwips(GtkWidget* pDocView, GdkRectangle* pArea) + { + #if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() +- GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); +- GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ TiledWindow& rWindow = lcl_getTiledWindow(pDocView); ++ ++ GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); ++ GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); + + pArea->x = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), + gtk_adjustment_get_value(pHAdjustment)); +@@ -306,8 +312,10 @@ static void signalEdit(LOKDocView* pLOKDocView, gboolean bWasEdit, gpointer /*pD + } + + /// LOKDocView changed command state -> inform the tool button. +-static void signalCommand(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer /*pData*/) ++static void signalCommand(LOKDocView* pLOKDocView, char* pPayload, gpointer /*pData*/) + { ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); ++ + std::string aPayload(pPayload); + size_t nPosition = aPayload.find("="); + if (nPosition != std::string::npos) +@@ -316,16 +324,16 @@ static void signalCommand(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer + std::string aValue = aPayload.substr(nPosition + 1); + g_info("signalCommand: '%s' is '%s'", aKey.c_str(), aValue.c_str()); + +- if (g_aCommandNameToolItems.find(aKey) != g_aCommandNameToolItems.end()) ++ if (rWindow.m_aCommandNameToolItems.find(aKey) != rWindow.m_aCommandNameToolItems.end()) + { +- GtkToolItem* pItem = g_aCommandNameToolItems[aKey]; ++ GtkToolItem* pItem = rWindow.m_aCommandNameToolItems[aKey]; + gboolean bEdit = aValue == "true"; + if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(pItem)) != bEdit) + { + // Avoid invoking lok_doc_view_post_command(). +- g_bToolItemBroadcast = false; ++ rWindow.m_bToolItemBroadcast = false; + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(pItem), bEdit); +- g_bToolItemBroadcast = true; ++ rWindow.m_bToolItemBroadcast = true; + } + } + } +@@ -367,8 +375,10 @@ static void signalHyperlink(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointe + static void cursorChanged(LOKDocView* pDocView, gint nX, gint nY, + gint /*nWidth*/, gint /*nHeight*/, gpointer /*pData*/) + { +- GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); +- GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(pScrolledWindow)); ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pDocView)); ++ ++ GtkAdjustment* vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); ++ GtkAdjustment* hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); + GdkRectangle visArea; + gdouble upper; + gint x = -1, y = -1; +@@ -413,12 +423,13 @@ static void cursorChanged(LOKDocView* pDocView, gint nX, gint nY, + + static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + { +- if (g_bToolItemBroadcast) ++ TiledWindow& rWindow = lcl_getTiledWindow(pWidget); ++ ++ if (rWindow.m_bToolItemBroadcast) + { +- TiledWindow& rWindow = lcl_getTiledWindow(pWidget); + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + GtkToolItem* pItem = GTK_TOOL_ITEM(pWidget); +- const std::string& rString = g_aToolItemCommandNames[pItem]; ++ const std::string& rString = rWindow.m_aToolItemCommandNames[pItem]; + g_info("toggleToolItem: lok_doc_view_post_command('%s')", rString.c_str()); + lok_doc_view_post_command(pLOKDocView, rString.c_str(), 0); + } +@@ -622,28 +633,28 @@ int main( int argc, char* argv[] ) + gtk_tool_item_set_tooltip_text(aWindow.m_pBold, "Bold"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pBold, -1); + g_signal_connect(G_OBJECT(aWindow.m_pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow.m_pBold, ".uno:Bold"); ++ lcl_registerToolItem(aWindow, aWindow.m_pBold, ".uno:Bold"); + + aWindow.m_pItalic = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pItalic), "format-text-italic-symbolic"); + gtk_tool_item_set_tooltip_text(aWindow.m_pItalic, "Italic"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pItalic, -1); + g_signal_connect(G_OBJECT(aWindow.m_pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow.m_pItalic, ".uno:Italic"); ++ lcl_registerToolItem(aWindow, aWindow.m_pItalic, ".uno:Italic"); + + aWindow.m_pUnderline = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pUnderline), "format-text-underline-symbolic"); + gtk_tool_item_set_tooltip_text(aWindow.m_pUnderline, "Underline"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pUnderline, -1); + g_signal_connect(G_OBJECT(aWindow.m_pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow.m_pUnderline, ".uno:Underline"); ++ lcl_registerToolItem(aWindow, aWindow.m_pUnderline, ".uno:Underline"); + + aWindow.m_pStrikethrough = gtk_toggle_tool_button_new (); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(aWindow.m_pStrikethrough), "format-text-strikethrough-symbolic"); + gtk_tool_item_set_tooltip_text(aWindow.m_pStrikethrough, "Strikethrough"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pStrikethrough, -1); + g_signal_connect(G_OBJECT(aWindow.m_pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow.m_pStrikethrough, ".uno:Strikeout"); ++ lcl_registerToolItem(aWindow, aWindow.m_pStrikethrough, ".uno:Strikeout"); + + gtk_box_pack_start( GTK_BOX(pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. + +@@ -696,12 +707,12 @@ int main( int argc, char* argv[] ) + + + // Scrolled window for DocView +- pScrolledWindow = gtk_scrolled_window_new(0, 0); +- gtk_widget_set_hexpand (pScrolledWindow, TRUE); +- gtk_widget_set_vexpand (pScrolledWindow, TRUE); +- gtk_container_add(GTK_CONTAINER(pVBox), pScrolledWindow); ++ aWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); ++ gtk_widget_set_hexpand (aWindow.m_pScrolledWindow, TRUE); ++ gtk_widget_set_vexpand (aWindow.m_pScrolledWindow, TRUE); ++ gtk_container_add(GTK_CONTAINER(pVBox), aWindow.m_pScrolledWindow); + +- gtk_container_add(GTK_CONTAINER(pScrolledWindow), pDocView); ++ gtk_container_add(GTK_CONTAINER(aWindow.m_pScrolledWindow), pDocView); + + GtkWidget* pProgressBar = gtk_progress_bar_new (); + g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); +-- +2.12.0 + diff --git a/SOURCES/0130-gtktiledviewer-allow-part-selector-in-multiple-windo.patch b/SOURCES/0130-gtktiledviewer-allow-part-selector-in-multiple-windo.patch new file mode 100644 index 0000000..96025d6 --- /dev/null +++ b/SOURCES/0130-gtktiledviewer-allow-part-selector-in-multiple-windo.patch @@ -0,0 +1,199 @@ +From 81d430bc619caa24366cc35de67d34c5017acfcb Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 12:45:58 +0200 +Subject: [PATCH 130/398] gtktiledviewer: allow part selector in multiple + windows + +Change-Id: Ib31fca3d8b4119704fb1a5c3cee885e7c239c247 +(cherry picked from commit d8bf31e129c4e791bfb02c8d0ccbaedb53d9b300) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 65 ++++++++++++---------- + 1 file changed, 36 insertions(+), 29 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index ef3aee008cae..3e72c13470a8 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -30,11 +30,6 @@ static int help() + return 1; + } + +-static GtkWidget* pVBox; +-static GtkComboBoxText* pPartSelector; +-static GtkWidget* pPartModeComboBox; +-/// Should the part selector avoid calling lok::Document::setPart()? +-static bool g_bPartSelectorBroadcast = true; + static GtkWidget* pFindbar; + static GtkWidget* pFindbarEntry; + static GtkWidget* pFindbarLabel; +@@ -54,6 +49,11 @@ public: + std::map m_aToolItemCommandNames; + std::map m_aCommandNameToolItems; + bool m_bToolItemBroadcast; ++ GtkWidget* m_pVBox; ++ GtkComboBoxText* m_pPartSelector; ++ GtkWidget* m_pPartModeComboBox; ++ /// Should the part selector avoid calling lok::Document::setPart()? ++ bool m_bPartSelectorBroadcast; + + TiledWindow() + : m_pDocView(0), +@@ -64,7 +64,11 @@ public: + m_pUnderline(0), + m_pStrikethrough(0), + m_pScrolledWindow(0), +- m_bToolItemBroadcast(true) ++ m_bToolItemBroadcast(true), ++ m_pVBox(0), ++ m_pPartSelector(0), ++ m_pPartModeComboBox(0), ++ m_bPartSelectorBroadcast(true) + { + } + }; +@@ -352,11 +356,12 @@ static void signalSearch(LOKDocView* /*pLOKDocView*/, char* /*pPayload*/, gpoint + } + + +-static void signalPart(LOKDocView* /*pLOKDocView*/, int nPart, gpointer /*pData*/) ++static void signalPart(LOKDocView* pLOKDocView, int nPart, gpointer /*pData*/) + { +- g_bPartSelectorBroadcast = false; +- gtk_combo_box_set_active(GTK_COMBO_BOX(pPartSelector), nPart); +- g_bPartSelectorBroadcast = true; ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); ++ rWindow.m_bPartSelectorBroadcast = false; ++ gtk_combo_box_set_active(GTK_COMBO_BOX(rWindow.m_pPartSelector), nPart); ++ rWindow.m_bPartSelectorBroadcast = true; + } + + /// User clicked on a command button -> inform LOKDocView. +@@ -437,9 +442,10 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + + static void populatePartSelector(LOKDocView* pLOKDocView) + { ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); + gtk_list_store_clear( GTK_LIST_STORE( + gtk_combo_box_get_model( +- GTK_COMBO_BOX(pPartSelector) )) ); ++ GTK_COMBO_BOX(rWindow.m_pPartSelector) )) ); + + if (!pLOKDocView) + { +@@ -457,16 +463,17 @@ static void populatePartSelector(LOKDocView* pLOKDocView) + snprintf( sText, nMaxLength, "%i (%s)", i+1, pName ); + free( pName ); + +- gtk_combo_box_text_append_text( pPartSelector, sText ); ++ gtk_combo_box_text_append_text( rWindow.m_pPartSelector, sText ); + } +- gtk_combo_box_set_active(GTK_COMBO_BOX(pPartSelector), lok_doc_view_get_part(pLOKDocView)); ++ gtk_combo_box_set_active(GTK_COMBO_BOX(rWindow.m_pPartSelector), lok_doc_view_get_part(pLOKDocView)); + } + + static void signalSize(LOKDocView* pLOKDocView, gpointer /*pData*/) + { +- g_bPartSelectorBroadcast = false; ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); ++ rWindow.m_bPartSelectorBroadcast = false; + populatePartSelector(pLOKDocView); +- g_bPartSelectorBroadcast = true; ++ rWindow.m_bPartSelectorBroadcast = true; + } + + static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) +@@ -474,7 +481,7 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + int nPart = gtk_combo_box_get_active( GTK_COMBO_BOX(pSelector) ); + TiledWindow& rWindow = lcl_getTiledWindow(pSelector); + +- if (g_bPartSelectorBroadcast && rWindow.m_pDocView) ++ if (rWindow.m_bPartSelectorBroadcast && rWindow.m_pDocView) + { + lok_doc_view_set_part( LOK_DOC_VIEW(rWindow.m_pDocView), nPart ); + lok_doc_view_reset_view( LOK_DOC_VIEW(rWindow.m_pDocView) ); +@@ -523,13 +530,13 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo + } + + populatePartSelector(pDocView); +- populatePartModeSelector( GTK_COMBO_BOX_TEXT(pPartModeComboBox) ); ++ populatePartModeSelector( GTK_COMBO_BOX_TEXT(rWindow.m_pPartModeComboBox) ); + // Connect these signals after populating the selectors, to avoid re-rendering on setting the default part/partmode. +- g_signal_connect(G_OBJECT(pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0); +- g_signal_connect(G_OBJECT(pPartSelector), "changed", G_CALLBACK(changePart), 0); ++ g_signal_connect(G_OBJECT(rWindow.m_pPartModeComboBox), "changed", G_CALLBACK(changePartMode), 0); ++ g_signal_connect(G_OBJECT(rWindow.m_pPartSelector), "changed", G_CALLBACK(changePart), 0); + + focusChain = g_list_append( focusChain, pDocView ); +- gtk_container_set_focus_chain ( GTK_CONTAINER (pVBox), focusChain ); ++ gtk_container_set_focus_chain ( GTK_CONTAINER (rWindow.m_pVBox), focusChain ); + + gtk_widget_hide(rWindow.m_pStatusBar); + } +@@ -554,8 +561,8 @@ int main( int argc, char* argv[] ) + gtk_window_set_default_size(GTK_WINDOW(pWindow), 1024, 768); + g_signal_connect( pWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL ); + +- pVBox = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 ); +- gtk_container_add( GTK_CONTAINER(pWindow), pVBox ); ++ aWindow.m_pVBox = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 ); ++ gtk_container_add( GTK_CONTAINER(pWindow), aWindow.m_pVBox ); + + // Toolbar + GtkWidget* pToolbar = gtk_toolbar_new(); +@@ -587,14 +594,14 @@ int main( int argc, char* argv[] ) + gtk_container_add( GTK_CONTAINER(pPartSelectorToolItem), pComboBox ); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartSelectorToolItem, -1 ); + +- pPartSelector = GTK_COMBO_BOX_TEXT(pComboBox); ++ aWindow.m_pPartSelector = GTK_COMBO_BOX_TEXT(pComboBox); + + GtkToolItem* pSeparator2 = gtk_separator_tool_item_new(); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pSeparator2, -1); + + GtkToolItem* pPartModeSelectorToolItem = gtk_tool_item_new(); +- pPartModeComboBox = gtk_combo_box_text_new(); +- gtk_container_add( GTK_CONTAINER(pPartModeSelectorToolItem), pPartModeComboBox ); ++ aWindow.m_pPartModeComboBox = gtk_combo_box_text_new(); ++ gtk_container_add(GTK_CONTAINER(pPartModeSelectorToolItem), aWindow.m_pPartModeComboBox); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1 ); + + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); +@@ -656,7 +663,7 @@ int main( int argc, char* argv[] ) + g_signal_connect(G_OBJECT(aWindow.m_pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(aWindow, aWindow.m_pStrikethrough, ".uno:Strikeout"); + +- gtk_box_pack_start( GTK_BOX(pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. ++ gtk_box_pack_start( GTK_BOX(aWindow.m_pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. + + // Findbar + pFindbar = gtk_toolbar_new(); +@@ -688,7 +695,7 @@ int main( int argc, char* argv[] ) + gtk_container_add(GTK_CONTAINER(pFindbarLabelContainer), pFindbarLabel); + gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarLabelContainer, -1); + +- gtk_box_pack_end(GTK_BOX(pVBox), pFindbar, FALSE, FALSE, 0); ++ gtk_box_pack_end(GTK_BOX(aWindow.m_pVBox), pFindbar, FALSE, FALSE, 0); + + // Docview + GtkWidget* pDocView = lok_doc_view_new (argv[1], NULL, NULL); +@@ -710,7 +717,7 @@ int main( int argc, char* argv[] ) + aWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); + gtk_widget_set_hexpand (aWindow.m_pScrolledWindow, TRUE); + gtk_widget_set_vexpand (aWindow.m_pScrolledWindow, TRUE); +- gtk_container_add(GTK_CONTAINER(pVBox), aWindow.m_pScrolledWindow); ++ gtk_container_add(GTK_CONTAINER(aWindow.m_pVBox), aWindow.m_pScrolledWindow); + + gtk_container_add(GTK_CONTAINER(aWindow.m_pScrolledWindow), pDocView); + +@@ -720,7 +727,7 @@ int main( int argc, char* argv[] ) + GtkWidget* pStatusBar = gtk_statusbar_new (); + aWindow.m_pStatusBar = pStatusBar; + gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, pStatusBar); +- gtk_container_add (GTK_CONTAINER(pVBox), pStatusBar); ++ gtk_container_add (GTK_CONTAINER(aWindow.m_pVBox), pStatusBar); + gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); + gtk_widget_set_hexpand(pProgressBar, true); + +-- +2.12.0 + diff --git a/SOURCES/0131-gtktiledviewer-allow-findbar-in-multiple-windows.patch b/SOURCES/0131-gtktiledviewer-allow-findbar-in-multiple-windows.patch new file mode 100644 index 0000000..7d7ad6b --- /dev/null +++ b/SOURCES/0131-gtktiledviewer-allow-findbar-in-multiple-windows.patch @@ -0,0 +1,190 @@ +From 1ce8cd9be395ac818a151a7618121e9b203bc159 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 12:53:24 +0200 +Subject: [PATCH 131/398] gtktiledviewer: allow findbar in multiple windows + +With this, all previously global data is now stored per-window in the +g_aWindows map. + +Change-Id: I45b4449ee7d516106ea0b039d1af97db49edf759 +(cherry picked from commit d51e3f7877afe62b68071a694438d2d6722bb406) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 67 ++++++++++++---------- + 1 file changed, 36 insertions(+), 31 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 3e72c13470a8..efbb90800301 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -30,10 +30,6 @@ static int help() + return 1; + } + +-static GtkWidget* pFindbar; +-static GtkWidget* pFindbarEntry; +-static GtkWidget* pFindbarLabel; +- + /// Represents all the state that is specific to one GtkWindow of this app. + class TiledWindow + { +@@ -54,6 +50,9 @@ public: + GtkWidget* m_pPartModeComboBox; + /// Should the part selector avoid calling lok::Document::setPart()? + bool m_bPartSelectorBroadcast; ++ GtkWidget* m_pFindbar; ++ GtkWidget* m_pFindbarEntry; ++ GtkWidget* m_pFindbarLabel; + + TiledWindow() + : m_pDocView(0), +@@ -68,7 +67,10 @@ public: + m_pVBox(0), + m_pPartSelector(0), + m_pPartModeComboBox(0), +- m_bPartSelectorBroadcast(true) ++ m_bPartSelectorBroadcast(true), ++ m_pFindbar(0), ++ m_pFindbarEntry(0), ++ m_pFindbarLabel(0) + { + } + }; +@@ -173,16 +175,17 @@ static void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/) + } + + /// Toggle the visibility of the findbar. +-static void toggleFindbar(GtkWidget* /*pButton*/, gpointer /*pItem*/) ++static void toggleFindbar(GtkWidget* pButton, gpointer /*pItem*/) + { +- if (gtk_widget_get_visible(pFindbar)) ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ if (gtk_widget_get_visible(rWindow.m_pFindbar)) + { +- gtk_widget_hide(pFindbar); ++ gtk_widget_hide(rWindow.m_pFindbar); + } + else + { +- gtk_widget_show_all(pFindbar); +- gtk_widget_grab_focus(pFindbarEntry); ++ gtk_widget_show_all(rWindow.m_pFindbar); ++ gtk_widget_grab_focus(rWindow.m_pFindbarEntry); + } + } + +@@ -244,10 +247,11 @@ static void doCopy(GtkWidget* pButton, gpointer /*pItem*/) + } + + +-/// Searches for the next or previous text of pFindbarEntry. ++/// Searches for the next or previous text of TiledWindow::m_pFindbarEntry. + static void doSearch(GtkWidget* pButton, bool bBackwards) + { +- GtkEntry* pEntry = GTK_ENTRY(pFindbarEntry); ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ GtkEntry* pEntry = GTK_ENTRY(rWindow.m_pFindbarEntry); + const char* pText = gtk_entry_get_text(pEntry); + boost::property_tree::ptree aTree; + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/type", '/'), "string"); +@@ -255,7 +259,6 @@ static void doSearch(GtkWidget* pButton, bool bBackwards) + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards); + +- TiledWindow& rWindow = lcl_getTiledWindow(pButton); + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + GdkRectangle aArea; + getVisibleAreaTwips(rWindow.m_pDocView, &aArea); +@@ -285,7 +288,8 @@ static void signalSearchPrev(GtkWidget* pButton, gpointer /*pItem*/) + /// Handles the key-press-event of the search entry widget. + static gboolean signalFindbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer /*pData*/) + { +- gtk_label_set_text(GTK_LABEL(pFindbarLabel), ""); ++ TiledWindow& rWindow = lcl_getTiledWindow(pWidget); ++ gtk_label_set_text(GTK_LABEL(rWindow.m_pFindbarLabel), ""); + switch(pEvent->keyval) + { + case GDK_KEY_Return: +@@ -297,7 +301,7 @@ static gboolean signalFindbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer + case GDK_KEY_Escape: + { + // Hide the findbar. +- gtk_widget_hide(pFindbar); ++ gtk_widget_hide(rWindow.m_pFindbar); + return TRUE; + } + } +@@ -350,9 +354,10 @@ static void loadChanged(LOKDocView* /*pLOKDocView*/, gdouble fValue, gpointer pD + } + + /// LOKDocView found no search matches -> set the search label accordingly. +-static void signalSearch(LOKDocView* /*pLOKDocView*/, char* /*pPayload*/, gpointer /*pData*/) ++static void signalSearch(LOKDocView* pLOKDocView, char* /*pPayload*/, gpointer /*pData*/) + { +- gtk_label_set_text(GTK_LABEL(pFindbarLabel), "Search key not found"); ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); ++ gtk_label_set_text(GTK_LABEL(rWindow.m_pFindbarLabel), "Search key not found"); + } + + +@@ -666,36 +671,36 @@ int main( int argc, char* argv[] ) + gtk_box_pack_start( GTK_BOX(aWindow.m_pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. + + // Findbar +- pFindbar = gtk_toolbar_new(); +- gtk_toolbar_set_style(GTK_TOOLBAR(pFindbar), GTK_TOOLBAR_ICONS); ++ aWindow.m_pFindbar = gtk_toolbar_new(); ++ gtk_toolbar_set_style(GTK_TOOLBAR(aWindow.m_pFindbar), GTK_TOOLBAR_ICONS); + + GtkToolItem* pFindbarClose = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarClose), "window-close-symbolic"); +- gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarClose, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarClose, -1); + g_signal_connect(G_OBJECT(pFindbarClose), "clicked", G_CALLBACK(toggleFindbar), NULL); + + GtkToolItem* pEntryContainer = gtk_tool_item_new(); +- pFindbarEntry = gtk_entry_new(); +- gtk_container_add(GTK_CONTAINER(pEntryContainer), pFindbarEntry); +- g_signal_connect(pFindbarEntry, "key-press-event", G_CALLBACK(signalFindbar), 0); +- gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pEntryContainer, -1); ++ aWindow.m_pFindbarEntry = gtk_entry_new(); ++ gtk_container_add(GTK_CONTAINER(pEntryContainer), aWindow.m_pFindbarEntry); ++ g_signal_connect(aWindow.m_pFindbarEntry, "key-press-event", G_CALLBACK(signalFindbar), 0); ++ gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pEntryContainer, -1); + + GtkToolItem* pFindbarNext = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarNext), "go-down-symbolic"); +- gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarNext, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarNext, -1); + g_signal_connect(G_OBJECT(pFindbarNext), "clicked", G_CALLBACK(signalSearchNext), NULL); + + GtkToolItem* pFindbarPrev = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarPrev), "go-up-symbolic"); +- gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarPrev, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarPrev, -1); + g_signal_connect(G_OBJECT(pFindbarPrev), "clicked", G_CALLBACK(signalSearchPrev), NULL); + + GtkToolItem* pFindbarLabelContainer = gtk_tool_item_new(); +- pFindbarLabel = gtk_label_new(""); +- gtk_container_add(GTK_CONTAINER(pFindbarLabelContainer), pFindbarLabel); +- gtk_toolbar_insert(GTK_TOOLBAR(pFindbar), pFindbarLabelContainer, -1); ++ aWindow.m_pFindbarLabel = gtk_label_new(""); ++ gtk_container_add(GTK_CONTAINER(pFindbarLabelContainer), aWindow.m_pFindbarLabel); ++ gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarLabelContainer, -1); + +- gtk_box_pack_end(GTK_BOX(aWindow.m_pVBox), pFindbar, FALSE, FALSE, 0); ++ gtk_box_pack_end(GTK_BOX(aWindow.m_pVBox), aWindow.m_pFindbar, FALSE, FALSE, 0); + + // Docview + GtkWidget* pDocView = lok_doc_view_new (argv[1], NULL, NULL); +@@ -733,7 +738,7 @@ int main( int argc, char* argv[] ) + + gtk_widget_show_all( pWindow ); + // Hide the findbar by default. +- gtk_widget_hide(pFindbar); ++ gtk_widget_hide(aWindow.m_pFindbar); + + g_aWindows[pWindow] = aWindow; + +-- +2.12.0 + diff --git a/SOURCES/0132-lokdocview-allow-not-calling-documentLoad.patch b/SOURCES/0132-lokdocview-allow-not-calling-documentLoad.patch new file mode 100644 index 0000000..6ea7a51 --- /dev/null +++ b/SOURCES/0132-lokdocview-allow-not-calling-documentLoad.patch @@ -0,0 +1,129 @@ +From c00540a0f89da14380cfb4e194206ecfb5ca0e7f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 14:23:53 +0200 +Subject: [PATCH 132/398] lokdocview: allow not calling documentLoad() + +Change-Id: I2ff57c4be11cd3908bc951ebf572a2c02e2c4585 +(cherry picked from commit 4fd59356cb09e89324e8cd8ec84eef22a4c2031b) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 2 ++ + libreofficekit/source/gtk/lokdocview.cxx | 48 ++++++++++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 01009fb9eb40..f17925b4c53a 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -44,6 +44,8 @@ GtkWidget* lok_doc_view_new (const gchar* + GCancellable *cancellable, + GError **error); + ++GtkWidget* lok_doc_view_new_from_widget (LOKDocView* pDocView); ++ + void lok_doc_view_open_document (LOKDocView* pDocView, + const gchar* pPath, + GCancellable* cancellable, +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 27d2e1df983a..3cce40a94217 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -127,7 +127,9 @@ enum + PROP_0, + + PROP_LO_PATH, ++ PROP_LO_POINTER, + PROP_DOC_PATH, ++ PROP_DOC_POINTER, + PROP_EDITABLE, + PROP_LOAD_PROGRESS, + PROP_ZOOM, +@@ -1388,9 +1390,15 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal + case PROP_LO_PATH: + priv->m_aLOPath = g_value_dup_string (value); + break; ++ case PROP_LO_POINTER: ++ priv->m_pOffice = static_cast(g_value_get_pointer(value)); ++ break; + case PROP_DOC_PATH: + priv->m_aDocPath = g_value_dup_string (value); + break; ++ case PROP_DOC_POINTER: ++ priv->m_pDocument = static_cast(g_value_get_pointer(value)); ++ break; + case PROP_EDITABLE: + lok_doc_view_set_edit (pDocView, g_value_get_boolean (value)); + break; +@@ -1418,9 +1426,15 @@ static void lok_doc_view_get_property (GObject* object, guint propId, GValue *va + case PROP_LO_PATH: + g_value_set_string (value, priv->m_aLOPath); + break; ++ case PROP_LO_POINTER: ++ g_value_set_pointer(value, priv->m_pOffice); ++ break; + case PROP_DOC_PATH: + g_value_set_string (value, priv->m_aDocPath); + break; ++ case PROP_DOC_POINTER: ++ g_value_set_pointer(value, priv->m_pDocument); ++ break; + case PROP_EDITABLE: + g_value_set_boolean (value, priv->m_bEdit); + break; +@@ -1531,6 +1545,20 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + | G_PARAM_CONSTRUCT_ONLY))); + + /** ++ * LOKDocView:lopointer: ++ * ++ * A LibreOfficeKit* in case lok_init() is already called ++ * previously. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_LO_POINTER, ++ g_param_spec_pointer("lopointer", ++ "LO Pointer", ++ "A LibreOfficeKit* from lok_init()", ++ static_cast(G_PARAM_READWRITE ++ | G_PARAM_CONSTRUCT_ONLY))); ++ ++ /** + * LOKDocView:docpath: + * + * The path of the document that is currently being viewed. +@@ -1544,6 +1572,19 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + static_cast(G_PARAM_READWRITE))); + + /** ++ * LOKDocView:docpointer: ++ * ++ * A LibreOfficeKitDocument* in case documentLoad() is already called ++ * previously. ++ */ ++ g_object_class_install_property (pGObjectClass, ++ PROP_DOC_POINTER, ++ g_param_spec_pointer("docpointer", ++ "Document Pointer", ++ "A LibreOfficeKitDocument* from documentLoad()", ++ static_cast(G_PARAM_READWRITE))); ++ ++ /** + * LOKDocView:editable: + * + * Whether the document loaded inside of #LOKDocView is editable or not. +@@ -1795,6 +1836,13 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath, NULL)); + } + ++SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pLOKDocView) ++{ ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private(pLOKDocView)); ++ return GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/0, /*error=*/0, ++ "lopath", priv->m_aLOPath, "lopointer", priv->m_pOffice, "docpointer", priv->m_pDocument, NULL)); ++} ++ + /** + * lok_doc_view_open_document_finish: + * @pDocView: The #LOKDocView instance +-- +2.12.0 + diff --git a/SOURCES/0133-gtktiledviewer-factor-out-createWindow-from-main.patch b/SOURCES/0133-gtktiledviewer-factor-out-createWindow-from-main.patch new file mode 100644 index 0000000..f1c042a --- /dev/null +++ b/SOURCES/0133-gtktiledviewer-factor-out-createWindow-from-main.patch @@ -0,0 +1,324 @@ +From c918ee9ef3a098d22162010e8a142dbecf289e72 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 14:51:06 +0200 +Subject: [PATCH 133/398] gtktiledviewer: factor out createWindow() from main() + +Change-Id: Ib7ccd2192247805205b65e5e8da67bcc826f4d31 +(cherry picked from commit 2b69ce33edaed9eaa018821180a00d563ad1ba18) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 228 +++++++++++---------- + 1 file changed, 116 insertions(+), 112 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index efbb90800301..b43f785a300a 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -546,70 +546,58 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo + gtk_widget_hide(rWindow.m_pStatusBar); + } + +-int main( int argc, char* argv[] ) ++/// Creates the GtkWindow that has main widget as children and registers it in the window map. ++static GtkWidget* createWindow(TiledWindow& rWindow) + { +- if( argc < 3 || +- ( argc > 1 && ( !strcmp( argv[1], "--help" ) || !strcmp( argv[1], "-h" ) ) ) ) +- return help(); +- +- if ( argv[1][0] != '/' ) +- { +- fprintf(stderr, "Absolute path required to libreoffice install\n"); +- return 1; +- } +- +- gtk_init( &argc, &argv ); +- +- GtkWidget *pWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL ); +- TiledWindow aWindow; +- gtk_window_set_title( GTK_WINDOW(pWindow), "LibreOfficeKit GTK Tiled Viewer" ); ++ GtkWidget *pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); ++ gtk_window_set_title(GTK_WINDOW(pWindow), "LibreOfficeKit GTK Tiled Viewer"); + gtk_window_set_default_size(GTK_WINDOW(pWindow), 1024, 768); +- g_signal_connect( pWindow, "destroy", G_CALLBACK(gtk_main_quit), NULL ); ++ g_signal_connect(pWindow, "destroy", G_CALLBACK(gtk_main_quit), 0); + +- aWindow.m_pVBox = gtk_box_new( GTK_ORIENTATION_VERTICAL, 0 ); +- gtk_container_add( GTK_CONTAINER(pWindow), aWindow.m_pVBox ); ++ rWindow.m_pVBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); ++ gtk_container_add(GTK_CONTAINER(pWindow), rWindow.m_pVBox); + + // Toolbar + GtkWidget* pToolbar = gtk_toolbar_new(); +- gtk_toolbar_set_style( GTK_TOOLBAR(pToolbar), GTK_TOOLBAR_ICONS ); ++ gtk_toolbar_set_style(GTK_TOOLBAR(pToolbar), GTK_TOOLBAR_ICONS); + +- GtkToolItem* pZoomIn = gtk_tool_button_new( NULL, NULL ); ++ GtkToolItem* pZoomIn = gtk_tool_button_new(NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomIn), "zoom-in-symbolic"); + gtk_tool_item_set_tooltip_text(pZoomIn, "Zoom In"); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoomIn, 0); +- g_signal_connect( G_OBJECT(pZoomIn), "clicked", G_CALLBACK(changeZoom), NULL ); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pZoomIn, 0); ++ g_signal_connect(G_OBJECT(pZoomIn), "clicked", G_CALLBACK(changeZoom), NULL); + +- GtkToolItem* pZoom1 = gtk_tool_button_new( NULL, NULL ); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoom1), "zoom-original-symbolic"); ++ GtkToolItem* pZoom1 = gtk_tool_button_new(NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pZoom1), "zoom-original-symbolic"); + gtk_tool_item_set_tooltip_text(pZoom1, "Normal Size"); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoom1, -1); +- g_signal_connect( G_OBJECT(pZoom1), "clicked", G_CALLBACK(changeZoom), NULL ); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pZoom1, -1); ++ g_signal_connect(G_OBJECT(pZoom1), "clicked", G_CALLBACK(changeZoom), NULL); + +- GtkToolItem* pZoomOut = gtk_tool_button_new( NULL, NULL ); ++ GtkToolItem* pZoomOut = gtk_tool_button_new(NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomOut), "zoom-out-symbolic"); + gtk_tool_item_set_tooltip_text(pZoomOut, "Zoom Out"); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pZoomOut, -1); +- g_signal_connect( G_OBJECT(pZoomOut), "clicked", G_CALLBACK(changeZoom), NULL ); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pZoomOut, -1); ++ g_signal_connect(G_OBJECT(pZoomOut), "clicked", G_CALLBACK(changeZoom), NULL); + + GtkToolItem* pSeparator1 = gtk_separator_tool_item_new(); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pSeparator1, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pSeparator1, -1); + + GtkToolItem* pPartSelectorToolItem = gtk_tool_item_new(); + GtkWidget* pComboBox = gtk_combo_box_text_new(); +- gtk_container_add( GTK_CONTAINER(pPartSelectorToolItem), pComboBox ); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartSelectorToolItem, -1 ); ++ gtk_container_add(GTK_CONTAINER(pPartSelectorToolItem), pComboBox); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pPartSelectorToolItem, -1); + +- aWindow.m_pPartSelector = GTK_COMBO_BOX_TEXT(pComboBox); ++ rWindow.m_pPartSelector = GTK_COMBO_BOX_TEXT(pComboBox); + + GtkToolItem* pSeparator2 = gtk_separator_tool_item_new(); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pSeparator2, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pSeparator2, -1); + + GtkToolItem* pPartModeSelectorToolItem = gtk_tool_item_new(); +- aWindow.m_pPartModeComboBox = gtk_combo_box_text_new(); +- gtk_container_add(GTK_CONTAINER(pPartModeSelectorToolItem), aWindow.m_pPartModeComboBox); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1 ); ++ rWindow.m_pPartModeComboBox = gtk_combo_box_text_new(); ++ gtk_container_add(GTK_CONTAINER(pPartModeSelectorToolItem), rWindow.m_pPartModeComboBox); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1); + +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + + // Cut, copy & paste. + GtkToolItem* pCopyButton = gtk_tool_button_new( NULL, NULL); +@@ -620,7 +608,7 @@ int main( int argc, char* argv[] ) + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + + GtkToolItem* pEnableEditing = gtk_toggle_tool_button_new(); +- aWindow.m_pEnableEditing = pEnableEditing; ++ rWindow.m_pEnableEditing = pEnableEditing; + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pEnableEditing), "insert-text-symbolic"); + gtk_tool_item_set_tooltip_text(pEnableEditing, "Edit"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pEnableEditing, -1); +@@ -638,77 +626,115 @@ int main( int argc, char* argv[] ) + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pNewViewButton, -1); + g_signal_connect(G_OBJECT(pNewViewButton), "clicked", G_CALLBACK(createView), NULL); + +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); +- +- aWindow.m_pBold = gtk_toggle_tool_button_new(); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pBold), "format-text-bold-symbolic"); +- gtk_tool_item_set_tooltip_text(aWindow.m_pBold, "Bold"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pBold, -1); +- g_signal_connect(G_OBJECT(aWindow.m_pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow, aWindow.m_pBold, ".uno:Bold"); +- +- aWindow.m_pItalic = gtk_toggle_tool_button_new(); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pItalic), "format-text-italic-symbolic"); +- gtk_tool_item_set_tooltip_text(aWindow.m_pItalic, "Italic"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pItalic, -1); +- g_signal_connect(G_OBJECT(aWindow.m_pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow, aWindow.m_pItalic, ".uno:Italic"); +- +- aWindow.m_pUnderline = gtk_toggle_tool_button_new(); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (aWindow.m_pUnderline), "format-text-underline-symbolic"); +- gtk_tool_item_set_tooltip_text(aWindow.m_pUnderline, "Underline"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pUnderline, -1); +- g_signal_connect(G_OBJECT(aWindow.m_pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow, aWindow.m_pUnderline, ".uno:Underline"); +- +- aWindow.m_pStrikethrough = gtk_toggle_tool_button_new (); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(aWindow.m_pStrikethrough), "format-text-strikethrough-symbolic"); +- gtk_tool_item_set_tooltip_text(aWindow.m_pStrikethrough, "Strikethrough"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), aWindow.m_pStrikethrough, -1); +- g_signal_connect(G_OBJECT(aWindow.m_pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); +- lcl_registerToolItem(aWindow, aWindow.m_pStrikethrough, ".uno:Strikeout"); +- +- gtk_box_pack_start( GTK_BOX(aWindow.m_pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); ++ ++ rWindow.m_pBold = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pBold), "format-text-bold-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pBold, "Bold"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pBold, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pBold, ".uno:Bold"); ++ ++ rWindow.m_pItalic = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (rWindow.m_pItalic), "format-text-italic-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pItalic, "Italic"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pItalic, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pItalic, ".uno:Italic"); ++ ++ rWindow.m_pUnderline = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (rWindow.m_pUnderline), "format-text-underline-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pUnderline, "Underline"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pUnderline, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pUnderline, ".uno:Underline"); ++ ++ rWindow.m_pStrikethrough = gtk_toggle_tool_button_new (); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pStrikethrough), "format-text-strikethrough-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pStrikethrough, "Strikethrough"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pStrikethrough, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pStrikethrough, ".uno:Strikeout"); ++ ++ gtk_box_pack_start(GTK_BOX(rWindow.m_pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. + + // Findbar +- aWindow.m_pFindbar = gtk_toolbar_new(); +- gtk_toolbar_set_style(GTK_TOOLBAR(aWindow.m_pFindbar), GTK_TOOLBAR_ICONS); ++ rWindow.m_pFindbar = gtk_toolbar_new(); ++ gtk_toolbar_set_style(GTK_TOOLBAR(rWindow.m_pFindbar), GTK_TOOLBAR_ICONS); + + GtkToolItem* pFindbarClose = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarClose), "window-close-symbolic"); +- gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarClose, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarClose, -1); + g_signal_connect(G_OBJECT(pFindbarClose), "clicked", G_CALLBACK(toggleFindbar), NULL); + + GtkToolItem* pEntryContainer = gtk_tool_item_new(); +- aWindow.m_pFindbarEntry = gtk_entry_new(); +- gtk_container_add(GTK_CONTAINER(pEntryContainer), aWindow.m_pFindbarEntry); +- g_signal_connect(aWindow.m_pFindbarEntry, "key-press-event", G_CALLBACK(signalFindbar), 0); +- gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pEntryContainer, -1); ++ rWindow.m_pFindbarEntry = gtk_entry_new(); ++ gtk_container_add(GTK_CONTAINER(pEntryContainer), rWindow.m_pFindbarEntry); ++ g_signal_connect(rWindow.m_pFindbarEntry, "key-press-event", G_CALLBACK(signalFindbar), 0); ++ gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pEntryContainer, -1); + + GtkToolItem* pFindbarNext = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarNext), "go-down-symbolic"); +- gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarNext, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarNext, -1); + g_signal_connect(G_OBJECT(pFindbarNext), "clicked", G_CALLBACK(signalSearchNext), NULL); + + GtkToolItem* pFindbarPrev = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarPrev), "go-up-symbolic"); +- gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarPrev, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarPrev, -1); + g_signal_connect(G_OBJECT(pFindbarPrev), "clicked", G_CALLBACK(signalSearchPrev), NULL); + + GtkToolItem* pFindbarLabelContainer = gtk_tool_item_new(); +- aWindow.m_pFindbarLabel = gtk_label_new(""); +- gtk_container_add(GTK_CONTAINER(pFindbarLabelContainer), aWindow.m_pFindbarLabel); +- gtk_toolbar_insert(GTK_TOOLBAR(aWindow.m_pFindbar), pFindbarLabelContainer, -1); ++ rWindow.m_pFindbarLabel = gtk_label_new(""); ++ gtk_container_add(GTK_CONTAINER(pFindbarLabelContainer), rWindow.m_pFindbarLabel); ++ gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarLabelContainer, -1); ++ ++ gtk_box_pack_end(GTK_BOX(rWindow.m_pVBox), rWindow.m_pFindbar, FALSE, FALSE, 0); ++ ++ // Scrolled window for DocView ++ rWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); ++ gtk_widget_set_hexpand(rWindow.m_pScrolledWindow, TRUE); ++ gtk_widget_set_vexpand(rWindow.m_pScrolledWindow, TRUE); ++ gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), rWindow.m_pScrolledWindow); + +- gtk_box_pack_end(GTK_BOX(aWindow.m_pVBox), aWindow.m_pFindbar, FALSE, FALSE, 0); ++ gtk_container_add(GTK_CONTAINER(rWindow.m_pScrolledWindow), rWindow.m_pDocView); ++ ++ GtkWidget* pProgressBar = gtk_progress_bar_new (); ++ g_signal_connect(rWindow.m_pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); ++ ++ GtkWidget* pStatusBar = gtk_statusbar_new(); ++ rWindow.m_pStatusBar = pStatusBar; ++ gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, pStatusBar); ++ gtk_container_add (GTK_CONTAINER(rWindow.m_pVBox), pStatusBar); ++ gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); ++ gtk_widget_set_hexpand(pProgressBar, true); ++ ++ gtk_widget_show_all(pWindow); ++ // Hide the findbar by default. ++ gtk_widget_hide(rWindow.m_pFindbar); ++ ++ g_aWindows[pWindow] = rWindow; ++ return pWindow; ++} ++ ++int main( int argc, char* argv[] ) ++{ ++ if( argc < 3 || ++ ( argc > 1 && ( !strcmp( argv[1], "--help" ) || !strcmp( argv[1], "-h" ) ) ) ) ++ return help(); ++ ++ if ( argv[1][0] != '/' ) ++ { ++ fprintf(stderr, "Absolute path required to libreoffice install\n"); ++ return 1; ++ } ++ ++ gtk_init( &argc, &argv ); + + // Docview + GtkWidget* pDocView = lok_doc_view_new (argv[1], NULL, NULL); +- aWindow.m_pDocView = pDocView; + #if GLIB_CHECK_VERSION(2,40,0) + g_assert_nonnull(pDocView); + #endif +- + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); +@@ -717,32 +743,10 @@ int main( int argc, char* argv[] ) + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); + g_signal_connect(pDocView, "cursor-changed", G_CALLBACK(cursorChanged), NULL); + +- +- // Scrolled window for DocView +- aWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); +- gtk_widget_set_hexpand (aWindow.m_pScrolledWindow, TRUE); +- gtk_widget_set_vexpand (aWindow.m_pScrolledWindow, TRUE); +- gtk_container_add(GTK_CONTAINER(aWindow.m_pVBox), aWindow.m_pScrolledWindow); +- +- gtk_container_add(GTK_CONTAINER(aWindow.m_pScrolledWindow), pDocView); +- +- GtkWidget* pProgressBar = gtk_progress_bar_new (); +- g_signal_connect(pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); +- +- GtkWidget* pStatusBar = gtk_statusbar_new (); +- aWindow.m_pStatusBar = pStatusBar; +- gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, pStatusBar); +- gtk_container_add (GTK_CONTAINER(aWindow.m_pVBox), pStatusBar); +- gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); +- gtk_widget_set_hexpand(pProgressBar, true); +- +- gtk_widget_show_all( pWindow ); +- // Hide the findbar by default. +- gtk_widget_hide(aWindow.m_pFindbar); +- +- g_aWindows[pWindow] = aWindow; +- +- lok_doc_view_open_document( LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView ); ++ TiledWindow aWindow; ++ aWindow.m_pDocView = pDocView; ++ createWindow(aWindow); ++ lok_doc_view_open_document(LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView); + + gtk_main(); + +-- +2.12.0 + diff --git a/SOURCES/0134-gtktiledviewer-factor-out-setupDocView-from-main.patch b/SOURCES/0134-gtktiledviewer-factor-out-setupDocView-from-main.patch new file mode 100644 index 0000000..efdc36c --- /dev/null +++ b/SOURCES/0134-gtktiledviewer-factor-out-setupDocView-from-main.patch @@ -0,0 +1,62 @@ +From 2252f488aec993855c44d884747394ff15810fac Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 15:05:51 +0200 +Subject: [PATCH 134/398] gtktiledviewer: factor out setupDocView() from main() + +Change-Id: Iac803f03267859c11f0f9090346b09b90c115b76 +(cherry picked from commit 8d8a8e1a2ea26df6d676495af7f017baa071153d) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 30 ++++++++++++---------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index b43f785a300a..53bc5ea39615 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -716,6 +716,21 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + return pWindow; + } + ++/// Common setup for DocView (regardless if it's just a new view or a document to be loaded). ++static void setupDocView(GtkWidget* pDocView) ++{ ++#if GLIB_CHECK_VERSION(2,40,0) ++ g_assert_nonnull(pDocView); ++#endif ++ g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); ++ g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); ++ g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); ++ g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); ++ g_signal_connect(pDocView, "size-changed", G_CALLBACK(signalSize), NULL); ++ g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); ++ g_signal_connect(pDocView, "cursor-changed", G_CALLBACK(cursorChanged), NULL); ++} ++ + int main( int argc, char* argv[] ) + { + if( argc < 3 || +@@ -730,19 +745,8 @@ int main( int argc, char* argv[] ) + + gtk_init( &argc, &argv ); + +- // Docview +- GtkWidget* pDocView = lok_doc_view_new (argv[1], NULL, NULL); +-#if GLIB_CHECK_VERSION(2,40,0) +- g_assert_nonnull(pDocView); +-#endif +- g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); +- g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); +- g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); +- g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); +- g_signal_connect(pDocView, "size-changed", G_CALLBACK(signalSize), NULL); +- g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); +- g_signal_connect(pDocView, "cursor-changed", G_CALLBACK(cursorChanged), NULL); +- ++ GtkWidget* pDocView = lok_doc_view_new(argv[1], NULL, NULL); ++ setupDocView(pDocView); + TiledWindow aWindow; + aWindow.m_pDocView = pDocView; + createWindow(aWindow); +-- +2.12.0 + diff --git a/SOURCES/0135-gtktiledviewer-set-up-a-new-GtkWindow-for-a-new-view.patch b/SOURCES/0135-gtktiledviewer-set-up-a-new-GtkWindow-for-a-new-view.patch new file mode 100644 index 0000000..2e3f193 --- /dev/null +++ b/SOURCES/0135-gtktiledviewer-set-up-a-new-GtkWindow-for-a-new-view.patch @@ -0,0 +1,43 @@ +From aa50f4ae737bd4428c8a104447dd0b3519a733a9 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 15:22:53 +0200 +Subject: [PATCH 135/398] gtktiledviewer: set up a new GtkWindow for a new view + +Change-Id: I9dcb5871c231a49bcd65a1187df6c3c81f92bd55 +(cherry picked from commit c1d72145314be0e53d5f93e3b639715c9fbba8b0) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 53bc5ea39615..e32397b133c9 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -77,6 +77,9 @@ public: + + static std::map g_aWindows; + ++static void setupDocView(GtkWidget* pDocView); ++static GtkWidget* createWindow(TiledWindow& rWindow); ++ + static TiledWindow& lcl_getTiledWindow(GtkWidget* pWidget) + { + GtkWidget* pToplevel = gtk_widget_get_toplevel(pWidget); +@@ -193,9 +196,11 @@ static void toggleFindbar(GtkWidget* pButton, gpointer /*pItem*/) + static void createView(GtkWidget* pButton, gpointer /*pItem*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pButton); +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); +- LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); +- pDocument->pClass->createView(pDocument); ++ GtkWidget* pDocView = lok_doc_view_new_from_widget(LOK_DOC_VIEW(rWindow.m_pDocView)); ++ setupDocView(pDocView); ++ TiledWindow aWindow; ++ aWindow.m_pDocView = pDocView; ++ createWindow(aWindow); + } + + /// Our GtkClipboardGetFunc implementation for HTML. +-- +2.12.0 + diff --git a/SOURCES/0136-lokdocview-avoid-GTK-calls-in-openDocumentInThread.patch b/SOURCES/0136-lokdocview-avoid-GTK-calls-in-openDocumentInThread.patch new file mode 100644 index 0000000..e8fe0fc --- /dev/null +++ b/SOURCES/0136-lokdocview-avoid-GTK-calls-in-openDocumentInThread.patch @@ -0,0 +1,106 @@ +From 9ba754a4df93b5d92eb871c9e37e9430da563cdc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 15:36:51 +0200 +Subject: [PATCH 136/398] lokdocview: avoid GTK+ calls in + openDocumentInThread() + +GTK+ calls should be made from the main thread. + +Change-Id: Idcfa46d427d6e35fc544246a691bafc72f75a74c +(cherry picked from commit e6e5c248e52524ddaddc6d1a2627f10f169d0167) +--- + libreofficekit/source/gtk/lokdocview.cxx | 57 +++++++++++++++++++------------- + 1 file changed, 34 insertions(+), 23 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 3cce40a94217..0b0b5e9d9659 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -143,6 +143,7 @@ enum + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; + + static void lok_doc_view_initable_iface_init (GInitableIface *iface); ++static void callbackWorker (int nType, const char* pPayload, void* pData); + + SAL_DLLPUBLIC_EXPORT GType lok_doc_view_get_type(); + #ifdef __GNUC__ +@@ -380,6 +381,37 @@ static gboolean queueDraw(gpointer pData) + return G_SOURCE_REMOVE; + } + ++/// Set up LOKDocView after the document is loaded, invoked on the main thread by openDocumentInThread() running in a thread. ++static gboolean postDocumentLoad(gpointer pData) ++{ ++ LOKDocView* pLOKDocView = static_cast(pData); ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private(pLOKDocView)); ++ ++ priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); ++ priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pLOKDocView); ++ priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); ++ g_timeout_add(600, handleTimeout, pLOKDocView); ++ ++ float zoom = priv->m_fZoom; ++ long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; ++ long nDocumentHeightTwips = priv->m_nDocumentHeightTwips; ++ long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); ++ long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); ++ // Total number of columns in this document. ++ guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); ++ ++ ++ priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, ++ nColumns); ++ gtk_widget_set_size_request(GTK_WIDGET(pLOKDocView), ++ nDocumentWidthPixels, ++ nDocumentHeightPixels); ++ gtk_widget_set_can_focus(GTK_WIDGET(pLOKDocView), TRUE); ++ gtk_widget_grab_focus(GTK_WIDGET(pLOKDocView)); ++ ++ return G_SOURCE_REMOVE; ++} ++ + /// Implementation of the global callback handler, invoked by globalCallback(); + static gboolean + globalCallback (gpointer pData) +@@ -617,8 +649,7 @@ callback (gpointer pData) + return G_SOURCE_REMOVE; + } + +-static void +-callbackWorker (int nType, const char* pPayload, void* pData) ++static void callbackWorker (int nType, const char* pPayload, void* pData) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pData); + +@@ -1193,27 +1224,7 @@ openDocumentInThread (gpointer data) + } + else + { +- priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); +- priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pDocView); +- priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); +- g_timeout_add(600, handleTimeout, pDocView); +- +- float zoom = priv->m_fZoom; +- long nDocumentWidthTwips = priv->m_nDocumentWidthTwips; +- long nDocumentHeightTwips = priv->m_nDocumentHeightTwips; +- long nDocumentWidthPixels = twipToPixel(nDocumentWidthTwips, zoom); +- long nDocumentHeightPixels = twipToPixel(nDocumentHeightTwips, zoom); +- // Total number of columns in this document. +- guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); +- +- +- priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, +- nColumns); +- gtk_widget_set_size_request(GTK_WIDGET(pDocView), +- nDocumentWidthPixels, +- nDocumentHeightPixels); +- gtk_widget_set_can_focus(GTK_WIDGET(pDocView), TRUE); +- gtk_widget_grab_focus(GTK_WIDGET(pDocView)); ++ gdk_threads_add_idle(postDocumentLoad, pDocView); + g_task_return_boolean (task, true); + } + } +-- +2.12.0 + diff --git a/SOURCES/0137-lokdocview-set-up-the-widget-in-all-windows.patch b/SOURCES/0137-lokdocview-set-up-the-widget-in-all-windows.patch new file mode 100644 index 0000000..a837f8c --- /dev/null +++ b/SOURCES/0137-lokdocview-set-up-the-widget-in-all-windows.patch @@ -0,0 +1,39 @@ +From d439c2271500a145d4c6e37e3a8d504cc2027b5f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 15 Sep 2015 15:41:46 +0200 +Subject: [PATCH 137/398] lokdocview: set up the widget in all windows + +With this finally the number of GTK+ windows always match the number +returned by SfxLokHelper::getViews(). + +Change-Id: Ia45bef7dea86b80cfac00e2ad7c1a16d7f5b507b +(cherry picked from commit b3498e9fcdc895853564d13173075bebc7407ef2) +--- + libreofficekit/source/gtk/lokdocview.cxx | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 0b0b5e9d9659..92095f2d9707 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1850,8 +1850,15 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pLOKDocView) + { + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private(pLOKDocView)); +- return GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/0, /*error=*/0, +- "lopath", priv->m_aLOPath, "lopointer", priv->m_pOffice, "docpointer", priv->m_pDocument, NULL)); ++ GtkWidget* pDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/0, /*error=*/0, ++ "lopath", priv->m_aLOPath, "lopointer", priv->m_pOffice, "docpointer", priv->m_pDocument, NULL)); ++ ++ // No documentLoad(), just a createView(). ++ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)); ++ pDocument->pClass->createView(pDocument); ++ ++ postDocumentLoad(pDocView); ++ return pDocView; + } + + /** +-- +2.12.0 + diff --git a/SOURCES/0138-gtktiledviewer-add-setupWidgetAndCreateWindow-to-avo.patch b/SOURCES/0138-gtktiledviewer-add-setupWidgetAndCreateWindow-to-avo.patch new file mode 100644 index 0000000..f573ed5 --- /dev/null +++ b/SOURCES/0138-gtktiledviewer-add-setupWidgetAndCreateWindow-to-avo.patch @@ -0,0 +1,80 @@ +From b4dda1d4bda439d063493d2c6726071f54fc4c55 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 09:22:17 +0200 +Subject: [PATCH 138/398] gtktiledviewer: add setupWidgetAndCreateWindow() to + avoid copy&paste + +Change-Id: Ibbbaaa1c148cfd4578ad37e0f99b62ab885a1a83 +(cherry picked from commit 855e1bac1d5155352706c7d849942f5dc453c67d) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 33 +++++++++++++++------- + 1 file changed, 23 insertions(+), 10 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index e32397b133c9..5a18aee50bf3 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -79,6 +79,7 @@ static std::map g_aWindows; + + static void setupDocView(GtkWidget* pDocView); + static GtkWidget* createWindow(TiledWindow& rWindow); ++static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpointer userdata); + + static TiledWindow& lcl_getTiledWindow(GtkWidget* pWidget) + { +@@ -192,17 +193,34 @@ static void toggleFindbar(GtkWidget* pButton, gpointer /*pItem*/) + } + } + +-/// Calls lok::Document::createView(). +-static void createView(GtkWidget* pButton, gpointer /*pItem*/) ++/// Common initialization, regardless if it's just a new view or a full init. ++static void setupWidgetAndCreateWindow(GtkWidget* pDocView) + { +- TiledWindow& rWindow = lcl_getTiledWindow(pButton); +- GtkWidget* pDocView = lok_doc_view_new_from_widget(LOK_DOC_VIEW(rWindow.m_pDocView)); + setupDocView(pDocView); + TiledWindow aWindow; + aWindow.m_pDocView = pDocView; + createWindow(aWindow); + } + ++/// Creates a new view, i.e. no LOK init or document load. ++static void createView(GtkWidget* pButton, gpointer /*pItem*/) ++{ ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ GtkWidget* pDocView = lok_doc_view_new_from_widget(LOK_DOC_VIEW(rWindow.m_pDocView)); ++ ++ setupWidgetAndCreateWindow(pDocView); ++} ++ ++/// Creates a new model, i.e. LOK init and document load, one view implicitly. ++static void createModelAndView(const char* pLOPath, const char* pDocPath) ++{ ++ GtkWidget* pDocView = lok_doc_view_new(pLOPath, 0, 0); ++ ++ setupWidgetAndCreateWindow(pDocView); ++ ++ lok_doc_view_open_document(LOK_DOC_VIEW(pDocView), pDocPath, 0, openDocumentCallback, pDocView); ++} ++ + /// Our GtkClipboardGetFunc implementation for HTML. + static void htmlGetFunc(GtkClipboard* /*pClipboard*/, GtkSelectionData* pSelectionData, guint /*info*/, gpointer pUserData) + { +@@ -750,12 +768,7 @@ int main( int argc, char* argv[] ) + + gtk_init( &argc, &argv ); + +- GtkWidget* pDocView = lok_doc_view_new(argv[1], NULL, NULL); +- setupDocView(pDocView); +- TiledWindow aWindow; +- aWindow.m_pDocView = pDocView; +- createWindow(aWindow); +- lok_doc_view_open_document(LOK_DOC_VIEW(pDocView), argv[2], NULL, openDocumentCallback, pDocView); ++ createModelAndView(argv[1], argv[2]); + + gtk_main(); + +-- +2.12.0 + diff --git a/SOURCES/0139-lok-Document-add-get-setView.patch b/SOURCES/0139-lok-Document-add-get-setView.patch new file mode 100644 index 0000000..0e3c9a9 --- /dev/null +++ b/SOURCES/0139-lok-Document-add-get-setView.patch @@ -0,0 +1,181 @@ +From 27ebd2b9c14a691889e6c7332024feab7c723d49 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 09:30:41 +0200 +Subject: [PATCH 139/398] lok::Document: add get/setView() + +Change-Id: Ic3bce8f01d7e048e853c063c4bce1255845c60d0 +(cherry picked from commit 46588c42a546d4517b773853856b9c8f8c2e5ece) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 6 ++++++ + desktop/source/lib/init.cxx | 18 ++++++++++++++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 4 ++++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 20 +++++++++++++++++++- + include/sfx2/lokhelper.hxx | 4 ++++ + sfx2/source/view/lokhelper.cxx | 24 ++++++++++++++++++++++++ + 6 files changed, 75 insertions(+), 1 deletion(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 6baaa32239c9..7ad81278d64a 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -139,6 +139,12 @@ void DesktopLOKTest::testCreateView() + int nId = pDocument->m_pDocumentClass->createView(pDocument); + CPPUNIT_ASSERT_EQUAL(2, SfxLokHelper::getViews()); + ++ // Make sure the created view is the active one, then switch to the old ++ // one. ++ CPPUNIT_ASSERT_EQUAL(1, pDocument->m_pDocumentClass->getView(pDocument)); ++ pDocument->m_pDocumentClass->setView(pDocument, 0); ++ CPPUNIT_ASSERT_EQUAL(0, pDocument->m_pDocumentClass->getView(pDocument)); ++ + pDocument->m_pDocumentClass->destroyView(pDocument, nId); + CPPUNIT_ASSERT_EQUAL(1, SfxLokHelper::getViews()); + closeDoc(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 3b1286e5944d..d76de5e5bb3c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -252,6 +252,8 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + + static int doc_createView(LibreOfficeKitDocument* pThis); + static void doc_destroyView(LibreOfficeKitDocument* pThis, int nId); ++static void doc_setView(LibreOfficeKitDocument* pThis, int nId); ++static int doc_getView(LibreOfficeKitDocument* pThis); + + LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : + mxComponent( xComponent ) +@@ -285,6 +287,8 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference createView = doc_createView; + m_pDocumentClass->destroyView = doc_destroyView; ++ m_pDocumentClass->setView = doc_setView; ++ m_pDocumentClass->getView = doc_getView; + + gDocumentClass = m_pDocumentClass; + } +@@ -1067,6 +1071,20 @@ static void doc_destroyView(LibreOfficeKitDocument* /*pThis*/, int nId) + SfxLokHelper::destroyView(nId); + } + ++static void doc_setView(LibreOfficeKitDocument* /*pThis*/, int nId) ++{ ++ SolarMutexGuard aGuard; ++ ++ SfxLokHelper::setView(nId); ++} ++ ++static int doc_getView(LibreOfficeKitDocument* /*pThis*/) ++{ ++ SolarMutexGuard aGuard; ++ ++ return SfxLokHelper::getView(); ++} ++ + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 7f41d13ff393..18f4b3edc624 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -170,6 +170,10 @@ struct _LibreOfficeKitDocumentClass + int (*createView) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::destroyView(). + void (*destroyView) (LibreOfficeKitDocument* pThis, int nId); ++ /// @see lok::Document::setView(). ++ void (*setView) (LibreOfficeKitDocument* pThis, int nId); ++ /// @see lok::Document::getView(). ++ int (*getView) (LibreOfficeKitDocument* pThis); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 3e1a0ac20b07..f5821b71191a 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -269,13 +269,31 @@ public: + } + + /** +- * Destroy a view of an existring document. ++ * Destroy a view of an existing document. + * @param nId a view ID, returned by createView(). + */ + void destroyView(int nId) + { + mpDoc->pClass->destroyView(mpDoc, nId); + } ++ ++ /** ++ * Set an existing view of an existing document as current. ++ * @param nId a view ID, returned by createView(). ++ */ ++ void setView(int nId) ++ { ++ mpDoc->pClass->setView(mpDoc, nId); ++ } ++ ++ /** ++ * Get the current view. ++ * @return a view ID, previously returned by createView(). ++ */ ++ int getView() ++ { ++ return mpDoc->pClass->getView(mpDoc); ++ } + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx +index b57cb7d75b23..a05cd5d4b210 100644 +--- a/include/sfx2/lokhelper.hxx ++++ b/include/sfx2/lokhelper.hxx +@@ -21,6 +21,10 @@ public: + static int createView(SfxViewShell* pViewShell); + /// Destroy a view shell from the global shell list. + static void destroyView(size_t nId); ++ /// Set a view shell as current one. ++ static void setView(size_t nId); ++ /// Get the currently active view. ++ static size_t getView(); + + /// Total number of view shells. + static int getViews(); +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +index 557478a78ae6..0aea6db9c24e 100644 +--- a/sfx2/source/view/lokhelper.cxx ++++ b/sfx2/source/view/lokhelper.cxx +@@ -38,6 +38,30 @@ void SfxLokHelper::destroyView(size_t nId) + pViewFrame->Exec_Impl(aRequest); + } + ++void SfxLokHelper::setView(size_t nId) ++{ ++ SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); ++ if (nId > rViewArr.size() - 1) ++ return; ++ ++ SfxViewShell* pViewShell = rViewArr[nId]; ++ if (SfxViewFrame* pViewFrame = pViewShell->GetViewFrame()) ++ pViewFrame->GetWindow().GrabFocus(); ++} ++ ++size_t SfxLokHelper::getView() ++{ ++ SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); ++ SfxViewFrame* pViewFrame = SfxViewFrame::Current(); ++ for (size_t i = 0; i < rViewArr.size(); ++i) ++ { ++ if (rViewArr[i]->GetViewFrame() == pViewFrame) ++ return i; ++ } ++ assert(false); ++ return 0; ++} ++ + int SfxLokHelper::getViews() + { + SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); +-- +2.12.0 + diff --git a/SOURCES/0140-Use-SfxViewFrame-Current.patch b/SOURCES/0140-Use-SfxViewFrame-Current.patch new file mode 100644 index 0000000..7a22647 --- /dev/null +++ b/SOURCES/0140-Use-SfxViewFrame-Current.patch @@ -0,0 +1,134 @@ +From b2d1dd0d6c4368909b90733aed41d5dc26113c00 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 10:32:34 +0200 +Subject: [PATCH 140/398] Use SfxViewFrame::Current() + +Allows getting rid of vcl::ITiledRenderable::getCurrentViewShell(), +which would do the same, just not implemented outside Writer. + +Change-Id: Id26ceca560fb9002dc2d5c740c411b9c4a149523 +(cherry picked from commit 8cb6094447041b7fbe29bd5584b5daf9babb5cad) +--- + desktop/source/lib/init.cxx | 12 ++---------- + include/sfx2/lokhelper.hxx | 4 ++-- + include/vcl/ITiledRenderable.hxx | 8 -------- + sfx2/source/view/lokhelper.cxx | 4 ++-- + sw/inc/unotxdoc.hxx | 2 -- + sw/source/uibase/uno/unotxdoc.cxx | 5 ----- + 6 files changed, 6 insertions(+), 29 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index d76de5e5bb3c..fa99038860cd 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1049,19 +1049,11 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + } + } + +-static int doc_createView(LibreOfficeKitDocument* pThis) ++static int doc_createView(LibreOfficeKitDocument* /*pThis*/) + { + SolarMutexGuard aGuard; + +- ITiledRenderable* pDoc = getTiledRenderable(pThis); +- if (!pDoc) +- { +- gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; +- return -1; +- } +- +- SfxViewShell* pViewShell = pDoc->getCurrentViewShell(); +- return SfxLokHelper::createView(pViewShell); ++ return SfxLokHelper::createView(); + } + + static void doc_destroyView(LibreOfficeKitDocument* /*pThis*/, int nId) +diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx +index a05cd5d4b210..50516227e992 100644 +--- a/include/sfx2/lokhelper.hxx ++++ b/include/sfx2/lokhelper.hxx +@@ -17,8 +17,8 @@ class SfxViewShell; + class SFX2_DLLPUBLIC SfxLokHelper + { + public: +- /// Create a new view shell for pViewShell's object shell. +- static int createView(SfxViewShell* pViewShell); ++ /// Create a new view shell from the current view frame. ++ static int createView(); + /// Destroy a view shell from the global shell list. + static void destroyView(size_t nId); + /// Set a view shell as current one. +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index a31d808437af..6639745e4a2f 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -16,8 +16,6 @@ + #include + #include + +-class SfxViewShell; +- + namespace vcl + { + +@@ -141,12 +139,6 @@ public: + * @see lok::Document::resetSelection(). + */ + virtual void resetSelection() = 0; +- +- /// Get the currently active view shell of the document. +- virtual SfxViewShell* getCurrentViewShell() +- { +- return 0; +- } + }; + + } // namespace vcl +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +index 0aea6db9c24e..f53d2b35b1bd 100644 +--- a/sfx2/source/view/lokhelper.cxx ++++ b/sfx2/source/view/lokhelper.cxx +@@ -15,9 +15,9 @@ + + #include + +-int SfxLokHelper::createView(SfxViewShell* pViewShell) ++int SfxLokHelper::createView() + { +- SfxViewFrame* pViewFrame = pViewShell->GetViewFrame(); ++ SfxViewFrame* pViewFrame = SfxViewFrame::Current(); + SfxRequest aRequest(pViewFrame, SID_NEWWINDOW); + pViewFrame->ExecView_Impl(aRequest); + +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index 71dbb4f2fd5a..9f0b03b3af38 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -431,8 +431,6 @@ public: + virtual void setGraphicSelection(int nType, int nX, int nY) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::resetSelection(). + virtual void resetSelection() SAL_OVERRIDE; +- /// @see vcl::ITiledRenderable::getCurrentViewShell(). +- virtual SfxViewShell* getCurrentViewShell() SAL_OVERRIDE; + + // ::com::sun::star::tiledrendering::XTiledRenderable + virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) SAL_OVERRIDE; +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 8dce9b5589d6..d6315d2964ae 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3410,11 +3410,6 @@ void SwXTextDocument::resetSelection() + pWrtShell->ResetSelect(0, false); + } + +-SfxViewShell* SwXTextDocument::getCurrentViewShell() +-{ +- return pDocShell->GetView(); +-} +- + void SAL_CALL SwXTextDocument::paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) + { + SystemGraphicsData aData; +-- +2.12.0 + diff --git a/SOURCES/0141-gtktiledviewer-use-setView-before-postKeyEvent.patch b/SOURCES/0141-gtktiledviewer-use-setView-before-postKeyEvent.patch new file mode 100644 index 0000000..3991633 --- /dev/null +++ b/SOURCES/0141-gtktiledviewer-use-setView-before-postKeyEvent.patch @@ -0,0 +1,84 @@ +From 3206f71ad36da6453801b4e3105f9968944f1aec Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 12:30:25 +0200 +Subject: [PATCH 141/398] gtktiledviewer: use setView() before postKeyEvent() + +Also in SfxLokHelper::setView() set the current view shell directly, +GetFocus() in VCL may be a NOP for hidden windows. + +With this, the Writer layout dump shows that two Gtk windows can have +different cursor positions correctly. + +Change-Id: I81890c1d8ad7972f1194db3d5f2e9d8a39fc2f87 +(cherry picked from commit f2e55ea10676d14c6564696a0648c0edbe4bd36d) +--- + libreofficekit/source/gtk/lokdocview.cxx | 21 +++++++++++++-------- + sfx2/source/view/lokhelper.cxx | 2 +- + 2 files changed, 14 insertions(+), 9 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 92095f2d9707..e84939e0da46 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -106,6 +106,9 @@ struct _LOKDocViewPrivate + /// If we are in the middle of a drag of a graphic selection handle. + gboolean m_bInDragGraphicHandles[8]; + ///@} ++ ++ /// View ID, returned by createView() or 0 by default. ++ int m_nViewId; + }; + + enum +@@ -240,6 +243,7 @@ postKeyEventInThread(gpointer data) + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->postKeyEvent(priv->m_pDocument, + pLOEvent->m_nKeyEvent, + pLOEvent->m_nCharCode, +@@ -1847,18 +1851,19 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath, NULL)); + } + +-SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pLOKDocView) ++SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOKDocView) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private(pLOKDocView)); +- GtkWidget* pDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/0, /*error=*/0, +- "lopath", priv->m_aLOPath, "lopointer", priv->m_pOffice, "docpointer", priv->m_pDocument, NULL)); ++ LOKDocViewPrivate* pOldPriv = static_cast(lok_doc_view_get_instance_private(pOldLOKDocView)); ++ GtkWidget* pNewDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/0, /*error=*/0, ++ "lopath", pOldPriv->m_aLOPath, "lopointer", pOldPriv->m_pOffice, "docpointer", pOldPriv->m_pDocument, NULL)); + + // No documentLoad(), just a createView(). +- LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)); +- pDocument->pClass->createView(pDocument); ++ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pNewDocView)); ++ LOKDocViewPrivate* pNewPriv = static_cast(lok_doc_view_get_instance_private(LOK_DOC_VIEW(pNewDocView))); ++ pNewPriv->m_nViewId = pDocument->pClass->createView(pDocument); + +- postDocumentLoad(pDocView); +- return pDocView; ++ postDocumentLoad(pNewDocView); ++ return pNewDocView; + } + + /** +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +index f53d2b35b1bd..0beb06ddd956 100644 +--- a/sfx2/source/view/lokhelper.cxx ++++ b/sfx2/source/view/lokhelper.cxx +@@ -46,7 +46,7 @@ void SfxLokHelper::setView(size_t nId) + + SfxViewShell* pViewShell = rViewArr[nId]; + if (SfxViewFrame* pViewFrame = pViewShell->GetViewFrame()) +- pViewFrame->GetWindow().GrabFocus(); ++ pViewFrame->MakeActive_Impl(false); + } + + size_t SfxLokHelper::getView() +-- +2.12.0 + diff --git a/SOURCES/0142-LOK-make-getViews-be-a-member-function-of-Document.patch b/SOURCES/0142-LOK-make-getViews-be-a-member-function-of-Document.patch new file mode 100644 index 0000000..1720b80 --- /dev/null +++ b/SOURCES/0142-LOK-make-getViews-be-a-member-function-of-Document.patch @@ -0,0 +1,215 @@ +From da8b89db49d0dfcef0ae0052bb8ab9d77a509dfb Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 14:14:04 +0200 +Subject: [PATCH 142/398] LOK: make getViews() be a member function of Document + +Just to be consistent, as all other view-related member functions are +there, too. + +No real impact, as only the unit test uses this so far, and it always +works with a single document. + +Change-Id: I46f1ed8265ab95017986ab45c1b510e961192241 +(cherry picked from commit a04b31c9facb08a8e38b79480b9a73bd2693cb9e) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 6 +++--- + desktop/source/lib/init.cxx | 17 +++++++++-------- + include/LibreOfficeKit/LibreOfficeKit.h | 5 ++--- + include/LibreOfficeKit/LibreOfficeKit.hxx | 18 ++++++++---------- + include/sfx2/lokhelper.hxx | 5 ++--- + sfx2/source/view/lokhelper.cxx | 13 +++++++++++-- + 6 files changed, 35 insertions(+), 29 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 7ad81278d64a..0cd88cefffa0 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -134,10 +134,10 @@ void DesktopLOKTest::testGetFonts() + void DesktopLOKTest::testCreateView() + { + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); +- CPPUNIT_ASSERT_EQUAL(1, SfxLokHelper::getViews()); ++ CPPUNIT_ASSERT_EQUAL(1, pDocument->m_pDocumentClass->getViews(pDocument)); + + int nId = pDocument->m_pDocumentClass->createView(pDocument); +- CPPUNIT_ASSERT_EQUAL(2, SfxLokHelper::getViews()); ++ CPPUNIT_ASSERT_EQUAL(2, pDocument->m_pDocumentClass->getViews(pDocument)); + + // Make sure the created view is the active one, then switch to the old + // one. +@@ -146,7 +146,7 @@ void DesktopLOKTest::testCreateView() + CPPUNIT_ASSERT_EQUAL(0, pDocument->m_pDocumentClass->getView(pDocument)); + + pDocument->m_pDocumentClass->destroyView(pDocument, nId); +- CPPUNIT_ASSERT_EQUAL(1, SfxLokHelper::getViews()); ++ CPPUNIT_ASSERT_EQUAL(1, pDocument->m_pDocumentClass->getViews(pDocument)); + closeDoc(); + } + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index fa99038860cd..617c94638cde 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -254,6 +254,7 @@ static int doc_createView(LibreOfficeKitDocument* pThis); + static void doc_destroyView(LibreOfficeKitDocument* pThis, int nId); + static void doc_setView(LibreOfficeKitDocument* pThis, int nId); + static int doc_getView(LibreOfficeKitDocument* pThis); ++static int doc_getViews(LibreOfficeKitDocument* pThis); + + LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : + mxComponent( xComponent ) +@@ -289,6 +290,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference destroyView = doc_destroyView; + m_pDocumentClass->setView = doc_setView; + m_pDocumentClass->getView = doc_getView; ++ m_pDocumentClass->getViews = doc_getViews; + + gDocumentClass = m_pDocumentClass; + } +@@ -316,8 +318,6 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions (LibreOfficeKit* pThi + static void lo_registerCallback (LibreOfficeKit* pThis, + LibreOfficeKitCallback pCallback, + void* pData); +-static int lo_getViews(LibreOfficeKit* pThis); +- + struct LibLibreOffice_Impl : public _LibreOfficeKit + { + OUString maLastExceptionMsg; +@@ -340,7 +340,6 @@ struct LibLibreOffice_Impl : public _LibreOfficeKit + m_pOfficeClass->getError = lo_getError; + m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions; + m_pOfficeClass->registerCallback = lo_registerCallback; +- m_pOfficeClass->getViews = lo_getViews; + + gOfficeClass = m_pOfficeClass; + } +@@ -458,11 +457,6 @@ static void lo_registerCallback (LibreOfficeKit* pThis, + pLib->mpCallbackData = pData; + } + +-static int lo_getViews(LibreOfficeKit* /*pThis*/) +-{ +- return SfxLokHelper::getViews(); +-} +- + static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const char* pFormat, const char* pFilterOptions) + { + LibLODocument_Impl* pDocument = static_cast(pThis); +@@ -1077,6 +1071,13 @@ static int doc_getView(LibreOfficeKitDocument* /*pThis*/) + return SfxLokHelper::getView(); + } + ++static int doc_getViews(LibreOfficeKitDocument* /*pThis*/) ++{ ++ SolarMutexGuard aGuard; ++ ++ return SfxLokHelper::getViews(); ++} ++ + static char* lo_getError (LibreOfficeKit *pThis) + { + LibLibreOffice_Impl* pLib = static_cast(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 18f4b3edc624..fc025aed5b15 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -54,9 +54,6 @@ struct _LibreOfficeKitClass + void (*registerCallback) (LibreOfficeKit* pThis, + LibreOfficeKitCallback pCallback, + void* pData); +- +- /// @see lok::Office::getViews(). +- int (*getViews) (LibreOfficeKit* pThis); + #endif + }; + +@@ -174,6 +171,8 @@ struct _LibreOfficeKitDocumentClass + void (*setView) (LibreOfficeKitDocument* pThis, int nId); + /// @see lok::Document::getView(). + int (*getView) (LibreOfficeKitDocument* pThis); ++ /// @see lok::Document::getViews(). ++ int (*getViews) (LibreOfficeKitDocument* pThis); + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index f5821b71191a..45ace9dfff04 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -294,6 +294,14 @@ public: + { + return mpDoc->pClass->getView(mpDoc); + } ++ ++ /** ++ * Get number of views of this document. ++ */ ++ inline int getViews() ++ { ++ return mpDoc->pClass->getViews(mpDoc); ++ } + #endif // LOK_USE_UNSTABLE_API + }; + +@@ -340,16 +348,6 @@ public: + { + return mpThis->pClass->getError(mpThis); + } +- +-#ifdef LOK_USE_UNSTABLE_API +- /** +- * Get number of total views. +- */ +- inline int getViews() +- { +- return mpThis->pClass->getViews(mpThis); +- } +-#endif + }; + + /// Factory method to create a lok::Office instance. +diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx +index 50516227e992..99f2076eeea1 100644 +--- a/include/sfx2/lokhelper.hxx ++++ b/include/sfx2/lokhelper.hxx +@@ -25,9 +25,8 @@ public: + static void setView(size_t nId); + /// Get the currently active view. + static size_t getView(); +- +- /// Total number of view shells. +- static int getViews(); ++ /// Get the number of views of the current object shell. ++ static size_t getViews(); + }; + + #endif +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +index 0beb06ddd956..646715ef226f 100644 +--- a/sfx2/source/view/lokhelper.cxx ++++ b/sfx2/source/view/lokhelper.cxx +@@ -62,10 +62,19 @@ size_t SfxLokHelper::getView() + return 0; + } + +-int SfxLokHelper::getViews() ++size_t SfxLokHelper::getViews() + { ++ size_t nRet = 0; ++ ++ SfxObjectShell* pObjectShell = SfxViewFrame::Current()->GetObjectShell(); + SfxViewShellArr_Impl& rViewArr = SfxGetpApp()->GetViewShells_Impl(); +- return rViewArr.size(); ++ for (size_t i = 0; i < rViewArr.size(); ++i) ++ { ++ if (rViewArr[i]->GetObjectShell() == pObjectShell) ++ ++nRet; ++ } ++ ++ return nRet; + } + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0143-LOK-allow-postMouseEvent-in-multiple-views.patch b/SOURCES/0143-LOK-allow-postMouseEvent-in-multiple-views.patch new file mode 100644 index 0000000..887bb31 --- /dev/null +++ b/SOURCES/0143-LOK-allow-postMouseEvent-in-multiple-views.patch @@ -0,0 +1,26 @@ +From 265831262dd2ea9b99f2723619f691005da16939 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 14:28:00 +0200 +Subject: [PATCH 143/398] LOK: allow postMouseEvent() in multiple views + +Change-Id: Iafb08cb44a96dbc03d12367d21b4120063bd0222 +(cherry picked from commit c9ebc92a1ebd48ad96ee5ca527c250489cb4ec27) +--- + libreofficekit/source/gtk/lokdocview.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index e84939e0da46..366f39efd3ac 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1197,6 +1197,7 @@ postMouseEventInThread(gpointer data) + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->postMouseEvent(priv->m_pDocument, + pLOEvent->m_nPostMouseEventType, + pLOEvent->m_nPostMouseEventX, +-- +2.12.0 + diff --git a/SOURCES/0144-Add-missing-lok-Document-setPartMode-wrapper.patch b/SOURCES/0144-Add-missing-lok-Document-setPartMode-wrapper.patch new file mode 100644 index 0000000..dff1004 --- /dev/null +++ b/SOURCES/0144-Add-missing-lok-Document-setPartMode-wrapper.patch @@ -0,0 +1,55 @@ +From 343e89c588aea46d122299b660ebcb8ec7213468 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 14:31:49 +0200 +Subject: [PATCH 144/398] Add missing lok::Document::setPartMode() wrapper + +Change-Id: I5dd5f0cfb8b34621b18a35be682249e042d9b173 +(cherry picked from commit 42844c2a8b614efa3bb7cd4f2525ce05a8647d20) +--- + include/LibreOfficeKit/LibreOfficeKit.h | 6 ++---- + include/LibreOfficeKit/LibreOfficeKit.hxx | 5 +++++ + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index fc025aed5b15..97ae1363a136 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -93,10 +93,7 @@ struct _LibreOfficeKitDocumentClass + char* (*getPartName) (LibreOfficeKitDocument* pThis, + int nPart); + +- /** Sets mode of the current part. +- * +- * @param nMode - element from the LibreOfficeKitPartMode enum. +- */ ++ /// @see lok::Document::setPartMode(). + void (*setPartMode) (LibreOfficeKitDocument* pThis, + int nMode); + +@@ -118,6 +115,7 @@ struct _LibreOfficeKitDocumentClass + /// @see lok::Document::initializeForRendering(). + void (*initializeForRendering) (LibreOfficeKitDocument* pThis); + ++ /// @see lok::Document::registerCallback(). + void (*registerCallback) (LibreOfficeKitDocument* pThis, + LibreOfficeKitCallback pCallback, + void* pData); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 45ace9dfff04..7f96e194e56c 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -94,6 +94,11 @@ public: + return mpDoc->pClass->getPartName(mpDoc, nPart); + } + ++ inline void setPartMode(int nMode) ++ { ++ mpDoc->pClass->setPartMode(mpDoc, nMode); ++ } ++ + /** + * Renders a subset of the document to a pre-allocated buffer. + * +-- +2.12.0 + diff --git a/SOURCES/0145-lokdocview-set-view-before-calling-lok-Document-memb.patch b/SOURCES/0145-lokdocview-set-view-before-calling-lok-Document-memb.patch new file mode 100644 index 0000000..76cc9e7 --- /dev/null +++ b/SOURCES/0145-lokdocview-set-view-before-calling-lok-Document-memb.patch @@ -0,0 +1,124 @@ +From 4cd8df4c0d923f5497ce8b860ed0eac64406cf9a Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Sep 2015 14:46:39 +0200 +Subject: [PATCH 145/398] lokdocview: set view before calling lok::Document + member functions + +getTextSelection() is still to be done, but has to be moved to the +widget first. + +Change-Id: I780a31f1dbce38b2b7398bfdacbbc1c40881229d +(cherry picked from commit d3446bc860e2e41adbee5ad6c49f12991dd9087b) +--- + include/LibreOfficeKit/LibreOfficeKit.h | 2 +- + libreofficekit/source/gtk/lokdocview.cxx | 11 +++++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 97ae1363a136..4c3e1fa851d4 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -158,7 +158,7 @@ struct _LibreOfficeKitDocumentClass + /// @see lok::Document::resetSelection + void (*resetSelection) (LibreOfficeKitDocument* pThis); + +- /// @see lok::Document:getStyles ++ /// @see lok::Document::getCommandValues(). + char* (*getCommandValues) (LibreOfficeKitDocument* pThis, const char* pCommand); + + /// @see lok::Document::createView(). +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 366f39efd3ac..f8202c339587 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -391,6 +391,7 @@ static gboolean postDocumentLoad(gpointer pData) + LOKDocView* pLOKDocView = static_cast(pData); + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private(pLOKDocView)); + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); + priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pLOKDocView); + priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); +@@ -1101,6 +1102,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GdkPoint aPoint; + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + if (priv->m_bInDragMiddleHandle) + { + g_info("lcl_signalMotion: dragging the middle handle"); +@@ -1183,6 +1185,7 @@ setGraphicSelectionInThread(gpointer data) + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->setGraphicSelection(priv->m_pDocument, + pLOEvent->m_nSetGraphicSelectionType, + pLOEvent->m_nSetGraphicSelectionX, +@@ -1243,6 +1246,7 @@ setPartInThread(gpointer data) + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + int nPart = pLOEvent->m_nPart; + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->setPart( priv->m_pDocument, nPart ); + } + +@@ -1255,6 +1259,7 @@ setPartmodeInThread(gpointer data) + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + int nPartMode = pLOEvent->m_nPartMode; + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->setPartMode( priv->m_pDocument, nPartMode ); + } + +@@ -1273,6 +1278,7 @@ setEditInThread(gpointer data) + else if (priv->m_bEdit && !bEdit) + { + g_info("lok_doc_view_set_edit: leaving edit mode"); ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->resetSelection(priv->m_pDocument); + } + priv->m_bEdit = bEdit; +@@ -1288,6 +1294,7 @@ postCommandInThread (gpointer data) + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments); + } + +@@ -1316,6 +1323,7 @@ paintTileInThread (gpointer data) + aTileRectangle.x = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileY; + aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileX; + ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + g_test_timer_start(); + priv->m_pDocument->pClass->paintTile(priv->m_pDocument, + pBuffer, +@@ -1974,6 +1982,7 @@ SAL_DLLPUBLIC_EXPORT int + lok_doc_view_get_parts (LOKDocView* pDocView) + { + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getParts( priv->m_pDocument ); + } + +@@ -1981,6 +1990,7 @@ SAL_DLLPUBLIC_EXPORT int + lok_doc_view_get_part (LOKDocView* pDocView) + { + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getPart( priv->m_pDocument ); + } + +@@ -2002,6 +2012,7 @@ SAL_DLLPUBLIC_EXPORT char* + lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart) + { + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getPartName( priv->m_pDocument, nPart ); + } + +-- +2.12.0 + diff --git a/SOURCES/0146-SfxLokHelper-setView-check-if-view-is-already-curren.patch b/SOURCES/0146-SfxLokHelper-setView-check-if-view-is-already-curren.patch new file mode 100644 index 0000000..672ffb8 --- /dev/null +++ b/SOURCES/0146-SfxLokHelper-setView-check-if-view-is-already-curren.patch @@ -0,0 +1,29 @@ +From 5edb280c093842d9d131f9cb7b404403d605a4dc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 17 Sep 2015 09:30:09 +0200 +Subject: [PATCH 146/398] SfxLokHelper::setView: check if view is already + current + +Change-Id: I9cf3a4887774657e0e205114688b088fc11c6822 +(cherry picked from commit 714257af17f74f8bcb5acceaebb0d0f4b3be3231) +--- + sfx2/source/view/lokhelper.cxx | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx +index 646715ef226f..f3731e799ec3 100644 +--- a/sfx2/source/view/lokhelper.cxx ++++ b/sfx2/source/view/lokhelper.cxx +@@ -45,6 +45,9 @@ void SfxLokHelper::setView(size_t nId) + return; + + SfxViewShell* pViewShell = rViewArr[nId]; ++ if (pViewShell->GetViewFrame() == SfxViewFrame::Current()) ++ return; ++ + if (SfxViewFrame* pViewFrame = pViewShell->GetViewFrame()) + pViewFrame->MakeActive_Impl(false); + } +-- +2.12.0 + diff --git a/SOURCES/0147-sfx2-add-SfxViewShell-libreOfficeKitViewCallback.patch b/SOURCES/0147-sfx2-add-SfxViewShell-libreOfficeKitViewCallback.patch new file mode 100644 index 0000000..ee59169 --- /dev/null +++ b/SOURCES/0147-sfx2-add-SfxViewShell-libreOfficeKitViewCallback.patch @@ -0,0 +1,101 @@ +From 62d05c21fdfe3e75e52fc275df6ef0ea95cb93d1 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 17 Sep 2015 10:58:56 +0200 +Subject: [PATCH 147/398] sfx2: add SfxViewShell::libreOfficeKitViewCallback() + +This is similar to the existing LOK callback, the difference is that the +existing one assumes there is only one SfxViewShell instance at the same +time. + +This newer callback is precisely per-view, so model notifications can +invoke all view callbacks, while view notifications can invoke only the +callback of the relevant view. + +This is just the framework, all actual client code has to be still +ported over (and then the existing callback can be removed). + +(cherry picked from commit c74ccac7cd94eba052d21cf74e03e214d58942e4) + +Change-Id: I3d8f27740c69fcf6ffbbdce12db2ea088321493d +--- + include/sfx2/viewsh.hxx | 7 +++++++ + sfx2/source/view/viewimp.hxx | 5 ++++- + sfx2/source/view/viewsh.cxx | 14 ++++++++++++++ + 3 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx +index c6e7f4a2ca12..69bd32c5ee25 100644 +--- a/include/sfx2/viewsh.hxx ++++ b/include/sfx2/viewsh.hxx +@@ -39,6 +39,8 @@ + #include + #include + #include ++#define LOK_USE_UNSTABLE_API ++#include + + class SfxBaseController; + class Size; +@@ -317,6 +319,11 @@ public: + SAL_DLLPRIVATE void TakeOwnership_Impl(); + SAL_DLLPRIVATE void TakeFrameOwnership_Impl(); + SAL_DLLPRIVATE bool ExecKey_Impl(const KeyEvent& aKey); ++ ++ /// The actual implementation of the lok::Document::registerViewCallback() API. ++ void registerLibreOfficeKitViewCallback(LibreOfficeKitCallback pCallback, void* pLibreOfficeKitData); ++ /// Invokes the registered callback, if there are any. ++ void libreOfficeKitViewCallback(int nType, const char* pPayload) const; + }; + + +diff --git a/sfx2/source/view/viewimp.hxx b/sfx2/source/view/viewimp.hxx +index 43b25d045eca..9f3ee1e3872b 100644 +--- a/sfx2/source/view/viewimp.hxx ++++ b/sfx2/source/view/viewimp.hxx +@@ -65,7 +65,10 @@ struct SfxViewShell_Impl + + mutable SfxInPlaceClientList* mpIPClientList; + +- SfxViewShell_Impl(SfxViewShellFlags const nFlags); ++ LibreOfficeKitCallback m_pLibreOfficeKitViewCallback; ++ void* m_pLibreOfficeKitViewData; ++ ++ explicit SfxViewShell_Impl(SfxViewShellFlags const nFlags); + ~SfxViewShell_Impl(); + + SfxInPlaceClientList* GetIPClientList_Impl( bool bCreate = true ) const; +diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx +index 939c590ffa82..8e7e68598dda 100644 +--- a/sfx2/source/view/viewsh.cxx ++++ b/sfx2/source/view/viewsh.cxx +@@ -310,6 +310,8 @@ SfxViewShell_Impl::SfxViewShell_Impl(SfxViewShellFlags const nFlags) + , m_nFamily(0xFFFF) // undefined, default set by TemplateDialog + , m_pController(0) + , mpIPClientList(NULL) ++, m_pLibreOfficeKitViewCallback(0) ++, m_pLibreOfficeKitViewData(0) + {} + + SfxViewShell_Impl::~SfxViewShell_Impl() +@@ -1633,6 +1635,18 @@ bool SfxViewShell::ExecKey_Impl(const KeyEvent& aKey) + return pImp->m_xAccExec->execute(aKey.GetKeyCode()); + } + ++void SfxViewShell::registerLibreOfficeKitViewCallback(LibreOfficeKitCallback pCallback, void* pData) ++{ ++ pImp->m_pLibreOfficeKitViewCallback = pCallback; ++ pImp->m_pLibreOfficeKitViewData = pData; ++} ++ ++void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) const ++{ ++ if (pImp->m_pLibreOfficeKitViewCallback) ++ pImp->m_pLibreOfficeKitViewCallback(nType, pPayload, pImp->m_pLibreOfficeKitViewData); ++} ++ + bool SfxViewShell::KeyInput( const KeyEvent &rKeyEvent ) + + /* [Description] +-- +2.12.0 + diff --git a/SOURCES/0148-comphelper-add-LibreOfficeKit-set-isViewCallback.patch b/SOURCES/0148-comphelper-add-LibreOfficeKit-set-isViewCallback.patch new file mode 100644 index 0000000..f42e87a --- /dev/null +++ b/SOURCES/0148-comphelper-add-LibreOfficeKit-set-isViewCallback.patch @@ -0,0 +1,77 @@ +From a5cddfd6432264a781e5418f970da6553db6a57d Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 17 Sep 2015 10:59:13 +0200 +Subject: [PATCH 148/398] comphelper: add LibreOfficeKit::set/isViewCallback() + +Change-Id: Iad0b2ee419327daf478f3ddda2378effe0184067 +(cherry picked from commit 1704221067e2bc6ba26eaa83573d29964b413a34) +--- + comphelper/source/misc/lok.cxx | 12 ++++++++++++ + desktop/source/lib/init.cxx | 4 ++++ + include/comphelper/lok.hxx | 5 +++++ + 3 files changed, 21 insertions(+) + +diff --git a/comphelper/source/misc/lok.cxx b/comphelper/source/misc/lok.cxx +index a6abd2a65486..279ec65c600c 100644 +--- a/comphelper/source/misc/lok.cxx ++++ b/comphelper/source/misc/lok.cxx +@@ -17,6 +17,8 @@ namespace LibreOfficeKit + + static bool g_bActive(false); + ++static bool g_bViewCallback(false); ++ + void setActive(bool bActive) + { + g_bActive = bActive; +@@ -27,6 +29,16 @@ bool isActive() + return g_bActive; + } + ++void setViewCallback(bool bViewCallback) ++{ ++ g_bViewCallback = bViewCallback; ++} ++ ++bool isViewCallback() ++{ ++ return g_bViewCallback; ++} ++ + static void (*pStatusIndicatorCallback)(void *data, statusIndicatorCallbackType type, int percent)(nullptr); + static void *pStatusIndicatorCallbackData(nullptr); + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 617c94638cde..52a78e228a32 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1192,6 +1192,10 @@ static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const char + return 1; + + comphelper::LibreOfficeKit::setActive(); ++ ++ static bool bViewCallback = getenv("LOK_VIEW_CALLBACK"); ++ comphelper::LibreOfficeKit::setViewCallback(bViewCallback); ++ + comphelper::LibreOfficeKit::setStatusIndicatorCallback(lo_status_indicator_callback, pLib); + + if (pUserProfilePath) +diff --git a/include/comphelper/lok.hxx b/include/comphelper/lok.hxx +index 79fa115e6585..2cc38c60e455 100644 +--- a/include/comphelper/lok.hxx ++++ b/include/comphelper/lok.hxx +@@ -36,6 +36,11 @@ COMPHELPER_DLLPUBLIC void setStatusIndicatorCallback(void (*callback)(void *data + // Check whether the code is running as invoked through LibreOfficeKit. + COMPHELPER_DLLPUBLIC bool isActive(); + ++/// Check whether clients register a callback for each view. ++COMPHELPER_DLLPUBLIC bool isViewCallback(); ++/// Set whether clients register a callback for each view. ++COMPHELPER_DLLPUBLIC void setViewCallback(bool bViewCallback); ++ + // Status indicator handling. Even if in theory there could be several status indicators active at + // the same time, in practice there is only one at a time, so we don't handle any identification of + // status indicator in this API. +-- +2.12.0 + diff --git a/SOURCES/0149-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_TILES.patch b/SOURCES/0149-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_TILES.patch new file mode 100644 index 0000000..74d42c8 --- /dev/null +++ b/SOURCES/0149-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_TILES.patch @@ -0,0 +1,42 @@ +From 3b8231a0656c7bddb2159bf494dd25074c0755b2 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 17 Sep 2015 11:44:53 +0200 +Subject: [PATCH 149/398] sw: implement per-view LOK_CALLBACK_INVALIDATE_TILES + +Change-Id: Id839dc076824e69fe07386c83bf21fc4c7ce2b8e +(cherry picked from commit b0f04d1ba273cc94989a5079f957117433076a9b) +--- + sw/source/uibase/docvw/edtwin.cxx | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx +index a76f68755b30..f392010fb6b1 100644 +--- a/sw/source/uibase/docvw/edtwin.cxx ++++ b/sw/source/uibase/docvw/edtwin.cxx +@@ -69,6 +69,7 @@ + #include + + #include ++#include + + #include + #include +@@ -6217,8 +6218,13 @@ void SwEditWin::LogicInvalidate(const Rectangle* pRectangle) + else + sRectangle = pRectangle->toString(); + +- if ( m_rView.GetWrtShellPtr() ) +- m_rView.GetWrtShell().libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ m_rView.libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); ++ else ++ { ++ if (m_rView.GetWrtShellPtr()) ++ m_rView.GetWrtShell().libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); ++ } + } + + void SwEditWin::LogicMouseButtonDown(const MouseEvent& rMouseEvent) +-- +2.12.0 + diff --git a/SOURCES/0150-lok-Document-register-callback-in-the-view-if-reques.patch b/SOURCES/0150-lok-Document-register-callback-in-the-view-if-reques.patch new file mode 100644 index 0000000..9c1e0b4 --- /dev/null +++ b/SOURCES/0150-lok-Document-register-callback-in-the-view-if-reques.patch @@ -0,0 +1,59 @@ +From 2dd20703103d2510fa47958743ced3ae203f613d Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 17 Sep 2015 15:39:19 +0200 +Subject: [PATCH 150/398] lok::Document: register callback in the view, if + requested + +With this, a postKeyEvent() in one view properly results in one +LOK_CALLBACK_INVALIDATE_TILES per view, at least in Writer. + +Change-Id: Ia0a9a00ea5a98c38f3d399208b9ef028f3036f79 +(cherry picked from commit b8a54763f4f66538f13b6c0e13045e5cb3167ca4) +--- + desktop/source/lib/init.cxx | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 52a78e228a32..64a6c00ffba6 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -54,6 +54,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -816,14 +818,22 @@ static void doc_registerCallback(LibreOfficeKitDocument* pThis, + LibreOfficeKitCallback pCallback, + void* pData) + { +- ITiledRenderable* pDoc = getTiledRenderable(pThis); +- if (!pDoc) ++ if (comphelper::LibreOfficeKit::isViewCallback()) + { +- gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; +- return; ++ if (SfxViewShell* pViewShell = SfxViewFrame::Current()->GetViewShell()) ++ pViewShell->registerLibreOfficeKitViewCallback(pCallback, pData); + } ++ else ++ { ++ ITiledRenderable* pDoc = getTiledRenderable(pThis); ++ if (!pDoc) ++ { ++ gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; ++ return; ++ } + +- pDoc->registerCallback(pCallback, pData); ++ pDoc->registerCallback(pCallback, pData); ++ } + } + + static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nCharCode, int nKeyCode) +-- +2.12.0 + diff --git a/SOURCES/0151-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_VISIBL.patch b/SOURCES/0151-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_VISIBL.patch new file mode 100644 index 0000000..2a0be60 --- /dev/null +++ b/SOURCES/0151-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_VISIBL.patch @@ -0,0 +1,62 @@ +From eaa1e3dcd0d84b8c60f5175b8e3ab5582e4658e7 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 17 Sep 2015 17:19:49 +0200 +Subject: [PATCH 151/398] sw: implement per-view + LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR + +Change-Id: Ib4c1caede94d3eac372a3605c430bbbd353755f3 +(cherry picked from commit 5c2811d682c6e623f3b2613df3119987c0c79c12) +--- + sw/inc/viewsh.hxx | 2 +- + sw/source/core/crsr/viscrs.cxx | 8 ++++++-- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx +index 1ba064f0c16c..fcccb91654fb 100644 +--- a/sw/inc/viewsh.hxx ++++ b/sw/inc/viewsh.hxx +@@ -449,7 +449,7 @@ public: + { return mpCareWindow ? mpCareWindow.get() : CareChildWin(rVSh); } + static vcl::Window* CareChildWin(SwViewShell& rVSh); + +- inline SfxViewShell *GetSfxViewShell() { return mpSfxViewShell; } ++ inline SfxViewShell *GetSfxViewShell() const { return mpSfxViewShell; } + inline void SetSfxViewShell(SfxViewShell *pNew) { mpSfxViewShell = pNew; } + + // Selection of Draw Engine has been changed. +diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx +index e0d32cc86e11..13cfcd89b22b 100644 +--- a/sw/source/core/crsr/viscrs.cxx ++++ b/sw/source/core/crsr/viscrs.cxx +@@ -54,6 +54,7 @@ + #include + + #include ++#include + #include + + // Here static members are defined. They will get changed on alteration of the +@@ -178,7 +179,7 @@ void SwVisCrsr::_SetPosAndShow() + + m_aTextCrsr.SetPos( aRect.Pos() ); + +- if (m_pCrsrShell->isTiledRendering()) ++ if (comphelper::LibreOfficeKit::isActive()) + { + // notify about page number change (if that happened) + sal_uInt16 nPage, nVirtPage; +@@ -193,7 +194,10 @@ void SwVisCrsr::_SetPosAndShow() + // notify about the cursor position & size + Rectangle aSVRect(aRect.Pos().getX(), aRect.Pos().getY(), aRect.Pos().getX() + aRect.SSize().Width(), aRect.Pos().getY() + aRect.SSize().Height()); + OString sRect = aSVRect.toString(); +- m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, sRect.getStr()); ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ m_pCrsrShell->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, sRect.getStr()); ++ else ++ m_pCrsrShell->libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, sRect.getStr()); + } + + if ( !m_pCrsrShell->IsCrsrReadonly() || m_pCrsrShell->GetViewOptions()->IsSelectionInReadonly() ) +-- +2.12.0 + diff --git a/SOURCES/0152-gtktiledviewer-don-t-crash-on-opening-non-existing-f.patch b/SOURCES/0152-gtktiledviewer-don-t-crash-on-opening-non-existing-f.patch new file mode 100644 index 0000000..944d497 --- /dev/null +++ b/SOURCES/0152-gtktiledviewer-don-t-crash-on-opening-non-existing-f.patch @@ -0,0 +1,57 @@ +From f752c0f12b0e903eb958e48ec1b88e4bc70778f9 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 18 Sep 2015 10:58:24 +0200 +Subject: [PATCH 152/398] gtktiledviewer: don't crash on opening non-existing + files + +Change-Id: Ic48adaf038e8fbcc86a94b5e351d2f963fcfcd16 +(cherry picked from commit 43b2103f932c92374e2ba2ab0ec1006582a0f646) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 16 ++++++++++++++-- + libreofficekit/source/gtk/lokdocview.cxx | 2 -- + 2 files changed, 14 insertions(+), 4 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 5a18aee50bf3..8e64972be17d 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -553,8 +553,20 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo + + if (!lok_doc_view_open_document_finish(pDocView, res, &error)) + { +- g_warning ("Error occurred while opening the document : %s", error->message); +- g_error_free (error); ++ GtkDialogFlags eFlags = GTK_DIALOG_DESTROY_WITH_PARENT; ++ GtkWidget* pDialog = gtk_message_dialog_new(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView))), ++ eFlags, ++ GTK_MESSAGE_ERROR, ++ GTK_BUTTONS_CLOSE, ++ "Error occurred while opening the document: '%s'", ++ error->message); ++ gtk_dialog_run(GTK_DIALOG(pDialog)); ++ gtk_widget_destroy(pDialog); ++ ++ g_error_free(error); ++ gtk_widget_destroy(GTK_WIDGET(pDocView)); ++ gtk_main_quit(); ++ return; + } + + populatePartSelector(pDocView); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index f8202c339587..60304b4ff59c 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1225,9 +1225,7 @@ openDocumentInThread (gpointer data) + priv->m_pDocument = priv->m_pOffice->pClass->documentLoad( priv->m_pOffice, priv->m_aDocPath ); + if ( !priv->m_pDocument ) + { +- // FIXME: should have a GError parameter and populate it. + char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice ); +- fprintf( stderr, "Error opening document '%s'\n", pError ); + g_task_return_new_error(task, 0, 0, "%s", pError); + } + else +-- +2.12.0 + diff --git a/SOURCES/0153-gtktiledviewer-fix-leftover-import-progressbar-in-cr.patch b/SOURCES/0153-gtktiledviewer-fix-leftover-import-progressbar-in-cr.patch new file mode 100644 index 0000000..2daa26a --- /dev/null +++ b/SOURCES/0153-gtktiledviewer-fix-leftover-import-progressbar-in-cr.patch @@ -0,0 +1,46 @@ +From c97dc2f0e98daf6d732aadb983e36cd1d2637ffd Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 18 Sep 2015 11:14:58 +0200 +Subject: [PATCH 153/398] gtktiledviewer: fix leftover import progressbar in + createView() + +Change-Id: Ia71e80c521cdc6a8e4df52e51e063a44a0dd53df +(cherry picked from commit af29b2b57cc07490cc36ff02d5ff3f3844e7c102) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 8e64972be17d..46264eb0126b 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -194,12 +194,13 @@ static void toggleFindbar(GtkWidget* pButton, gpointer /*pItem*/) + } + + /// Common initialization, regardless if it's just a new view or a full init. +-static void setupWidgetAndCreateWindow(GtkWidget* pDocView) ++static TiledWindow& setupWidgetAndCreateWindow(GtkWidget* pDocView) + { + setupDocView(pDocView); + TiledWindow aWindow; + aWindow.m_pDocView = pDocView; +- createWindow(aWindow); ++ GtkWidget* pWindow = createWindow(aWindow); ++ return lcl_getTiledWindow(pWindow); + } + + /// Creates a new view, i.e. no LOK init or document load. +@@ -208,7 +209,9 @@ static void createView(GtkWidget* pButton, gpointer /*pItem*/) + TiledWindow& rWindow = lcl_getTiledWindow(pButton); + GtkWidget* pDocView = lok_doc_view_new_from_widget(LOK_DOC_VIEW(rWindow.m_pDocView)); + +- setupWidgetAndCreateWindow(pDocView); ++ TiledWindow& rNewWindow = setupWidgetAndCreateWindow(pDocView); ++ // Hide status bar that contains the unused progress bar. ++ gtk_widget_hide(rNewWindow.m_pStatusBar); + } + + /// Creates a new model, i.e. LOK init and document load, one view implicitly. +-- +2.12.0 + diff --git a/SOURCES/0154-sw-implement-per-view-LOK_CALLBACK_TEXT_SELECTION.patch b/SOURCES/0154-sw-implement-per-view-LOK_CALLBACK_TEXT_SELECTION.patch new file mode 100644 index 0000000..c5b3546 --- /dev/null +++ b/SOURCES/0154-sw-implement-per-view-LOK_CALLBACK_TEXT_SELECTION.patch @@ -0,0 +1,135 @@ +From 4cb2a43c66b393ffd28d91e5fb27d782eaf7acb0 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 18 Sep 2015 14:29:18 +0200 +Subject: [PATCH 154/398] sw: implement per-view LOK_CALLBACK_TEXT_SELECTION + +Also: + +- let the unit test set the global LOK flag, as sw code now depends on + that +- in framework, don't return early after emitting the LOK status + indicator callback, otherwise CppunitTest_sw_tiledrendering shows how + sw LOK callbacks are missing + +Change-Id: I0c4ac12f2ef5118d29afd131676bcb27d5db7746 +(cherry picked from commit 1a83f30ebe2c56b00804ce774537b34f1049be84) +--- + framework/source/helper/statusindicator.cxx | 2 -- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 4 ++++ + sw/source/core/crsr/viscrs.cxx | 26 ++++++++++++++++++++------ + 3 files changed, 24 insertions(+), 8 deletions(-) + +diff --git a/framework/source/helper/statusindicator.cxx b/framework/source/helper/statusindicator.cxx +index 5c9dafc5ba81..ce8310a07cf5 100644 +--- a/framework/source/helper/statusindicator.cxx ++++ b/framework/source/helper/statusindicator.cxx +@@ -43,7 +43,6 @@ void SAL_CALL StatusIndicator::start(const OUString& sText , + m_nLastCallbackPercent = -1; + + comphelper::LibreOfficeKit::statusIndicatorStart(); +- return; + } + + css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory); +@@ -60,7 +59,6 @@ void SAL_CALL StatusIndicator::end() + if (comphelper::LibreOfficeKit::isActive()) + { + comphelper::LibreOfficeKit::statusIndicatorFinish(); +- return; + } + + css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory); +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index 07dd7e34b29c..e7ab14942f79 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -383,6 +383,8 @@ void SwTiledRenderingTest::testSearchViewArea() + void SwTiledRenderingTest::testSearchTextFrame() + { + #if !defined(WNT) && !defined(MACOSX) ++ comphelper::LibreOfficeKit::setActive(); ++ + SwXTextDocument* pXTextDocument = createDoc("search.odt"); + pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this); + uno::Sequence aPropertyValues(comphelper::InitPropertySequence( +@@ -393,6 +395,8 @@ void SwTiledRenderingTest::testSearchTextFrame() + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + // This was empty: nothing was highlighted after searching for 'TextFrame'. + CPPUNIT_ASSERT(!m_aTextSelection.isEmpty()); ++ ++ comphelper::LibreOfficeKit::setActive(false); + #endif + } + +diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx +index 13cfcd89b22b..808756159545 100644 +--- a/sw/source/core/crsr/viscrs.cxx ++++ b/sw/source/core/crsr/viscrs.cxx +@@ -361,7 +361,7 @@ void SwSelPaintRects::Show(std::vector* pSelectionRectangles) + // talks about "the" cursor at the moment. As long as that's true, + // don't say anything about the Writer cursor till a draw object is + // being edited. +- if (GetShell()->isTiledRendering() && !pView->GetTextEditObject()) ++ if (comphelper::LibreOfficeKit::isActive() && !pView->GetTextEditObject()) + { + if (!empty()) + { +@@ -377,12 +377,18 @@ void SwSelPaintRects::Show(std::vector* pSelectionRectangles) + if (aStartRect.HasArea()) + { + OString sRect = aStartRect.SVRect().toString(); +- GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_START, sRect.getStr()); ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_START, sRect.getStr()); ++ else ++ GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_START, sRect.getStr()); + } + if (aEndRect.HasArea()) + { + OString sRect = aEndRect.SVRect().toString(); +- GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_END, sRect.getStr()); ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION_END, sRect.getStr()); ++ else ++ GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_END, sRect.getStr()); + } + } + +@@ -396,7 +402,12 @@ void SwSelPaintRects::Show(std::vector* pSelectionRectangles) + } + OString sRect = ss.str().c_str(); + if (!pSelectionRectangles) +- GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); ++ { ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); ++ else ++ GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); ++ } + else + pSelectionRectangles->push_back(sRect); + } +@@ -593,7 +604,7 @@ void SwShellCrsr::Show() + pShCrsr->SwSelPaintRects::Show(&aSelectionRectangles); + } + +- if (GetShell()->isTiledRendering()) ++ if (comphelper::LibreOfficeKit::isActive()) + { + std::stringstream ss; + bool bFirst = true; +@@ -609,7 +620,10 @@ void SwShellCrsr::Show() + ss << rSelectionRectangle.getStr(); + } + OString sRect = ss.str().c_str(); +- GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ GetShell()->GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); ++ else ++ GetShell()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, sRect.getStr()); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0155-sw-implement-per-view-LOK_CALLBACK_CURSOR_VISIBLE.patch b/SOURCES/0155-sw-implement-per-view-LOK_CALLBACK_CURSOR_VISIBLE.patch new file mode 100644 index 0000000..b7dd6c5 --- /dev/null +++ b/SOURCES/0155-sw-implement-per-view-LOK_CALLBACK_CURSOR_VISIBLE.patch @@ -0,0 +1,66 @@ +From ea203d6dcaad5ea5e1aea716041072f9030e6467 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 18 Sep 2015 14:32:53 +0200 +Subject: [PATCH 155/398] sw: implement per-view LOK_CALLBACK_CURSOR_VISIBLE + +Change-Id: I4e00679547997cfb3dafe603b908f055011a3b30 +(cherry picked from commit 32f419fee5f9df4facb7a9b3ec910471d2a20247) +--- + sw/source/core/crsr/crsrsh.cxx | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx +index 3a0c6667b2e2..cbb89aca8868 100644 +--- a/sw/source/core/crsr/crsrsh.cxx ++++ b/sw/source/core/crsr/crsrsh.cxx +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -63,6 +64,7 @@ + #include + #include + #include ++#include + + using namespace com::sun::star; + using namespace util; +@@ -2118,8 +2120,13 @@ void SwCrsrShell::ShowCrsr() + m_bSVCrsrVis = true; + m_pCurCrsr->SetShowTextInputFieldOverlay( true ); + +- if (isTiledRendering()) +- libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(true).getStr()); ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(true).getStr()); ++ else ++ libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(true).getStr()); ++ } + + UpdateCrsr(); + } +@@ -2135,8 +2142,13 @@ void SwCrsrShell::HideCrsr() + m_pCurCrsr->SetShowTextInputFieldOverlay( false ); + m_pVisCrsr->Hide(); + +- if (isTiledRendering()) +- libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(false).getStr()); ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ if (comphelper::LibreOfficeKit::isViewCallback()) ++ GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(false).getStr()); ++ else ++ libreOfficeKitCallback(LOK_CALLBACK_CURSOR_VISIBLE, OString::boolean(false).getStr()); ++ } + } + } + +-- +2.12.0 + diff --git a/SOURCES/0156-CppCheck-reduce-variables-scope.patch b/SOURCES/0156-CppCheck-reduce-variables-scope.patch new file mode 100644 index 0000000..d0bfe7f --- /dev/null +++ b/SOURCES/0156-CppCheck-reduce-variables-scope.patch @@ -0,0 +1,43 @@ +From 01673b7cf6bb0abbd35ff79b50dc15b14bacad70 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C3=ABl=20Lef=C3=A8vre?= +Date: Mon, 21 Sep 2015 15:11:57 +0200 +Subject: [PATCH 156/398] CppCheck : reduce variables scope +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-on: https://gerrit.libreoffice.org/18753 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 92c8d74c543aa94cd512369072975dca7006d5b3) + +Change-Id: Ief402017b693a4337f330fb07bb7a6dc6e749f72 +--- + desktop/source/lib/init.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 64a6c00ffba6..1b06c4220564 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -566,7 +566,6 @@ static void doc_iniUnoCommands () + }; + + util::URL aCommandURL; +- const SfxSlot* pSlot = NULL; + SfxViewShell* pViewShell = SfxViewShell::Current(); + SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): NULL; + +@@ -582,6 +581,8 @@ static void doc_iniUnoCommands () + + for (sal_uInt32 nIterator = 0; nIterator < SAL_N_ELEMENTS(sUnoCommands); nIterator++) + { ++ const SfxSlot* pSlot = NULL; ++ + aCommandURL.Complete = sUnoCommands[nIterator]; + xParser->parseStrict(aCommandURL); + pSlot = rSlotPool.GetUnoSlot(aCommandURL.Path); +-- +2.12.0 + diff --git a/SOURCES/0157-lok-add-Office-getFilterTypes.patch b/SOURCES/0157-lok-add-Office-getFilterTypes.patch new file mode 100644 index 0000000..c94cca8 --- /dev/null +++ b/SOURCES/0157-lok-add-Office-getFilterTypes.patch @@ -0,0 +1,126 @@ +From e94667a1d9fbeea7655a4c5a6424534f43c02112 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 25 Sep 2015 01:02:23 +0200 +Subject: [PATCH 157/398] lok: add Office::getFilterTypes() + +Change-Id: I3b1f4e11f2495e5ccb41f85802f243c0190695ee +(cherry picked from commit 9b9f2ad9c819421c9f24bcbca98ee147f70d85b2) +--- + desktop/source/lib/init.cxx | 39 +++++++++++++++++++++++++++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 3 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 21 +++++++++++++++++ + 3 files changed, 63 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 1b06c4220564..57697fabce4c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -320,6 +320,8 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions (LibreOfficeKit* pThi + static void lo_registerCallback (LibreOfficeKit* pThis, + LibreOfficeKitCallback pCallback, + void* pData); ++static char* lo_getFilterTypes(LibreOfficeKit* pThis); ++ + struct LibLibreOffice_Impl : public _LibreOfficeKit + { + OUString maLastExceptionMsg; +@@ -342,6 +344,7 @@ struct LibLibreOffice_Impl : public _LibreOfficeKit + m_pOfficeClass->getError = lo_getError; + m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions; + m_pOfficeClass->registerCallback = lo_registerCallback; ++ m_pOfficeClass->getFilterTypes = lo_getFilterTypes; + + gOfficeClass = m_pOfficeClass; + } +@@ -1098,6 +1101,42 @@ static char* lo_getError (LibreOfficeKit *pThis) + return pMemory; + } + ++static char* lo_getFilterTypes(LibreOfficeKit* pThis) ++{ ++ LibLibreOffice_Impl* pImpl = static_cast(pThis); ++ ++ if (!xSFactory.is()) ++ xSFactory = comphelper::getProcessServiceFactory(); ++ ++ if (!xSFactory.is()) ++ { ++ pImpl->maLastExceptionMsg = "Service factory is not available"; ++ return 0; ++ } ++ ++ uno::Reference xTypeDetection(xSFactory->createInstance("com.sun.star.document.TypeDetection"), uno::UNO_QUERY); ++ uno::Sequence aTypes = xTypeDetection->getElementNames(); ++ boost::property_tree::ptree aTree; ++ for (const OUString& rType : aTypes) ++ { ++ uno::Sequence aValues; ++ if (xTypeDetection->getByName(rType) >>= aValues) ++ { ++ auto it = std::find_if(aValues.begin(), aValues.end(), [](const beans::PropertyValue& rValue) { return rValue.Name == "MediaType"; }); ++ OUString aValue; ++ if (it != aValues.end() && (it->Value >>= aValue) && !aValue.isEmpty()) ++ { ++ boost::property_tree::ptree aChild; ++ aChild.put("MediaType", aValue.toUtf8()); ++ aTree.add_child(rType.toUtf8().getStr(), aChild); ++ } ++ } ++ } ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ return strdup(aStream.str().c_str()); ++} ++ + static void force_c_locale() + { + // force locale (and resource files loaded) to en-US +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 4c3e1fa851d4..d5094bdb1b76 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -54,6 +54,9 @@ struct _LibreOfficeKitClass + void (*registerCallback) (LibreOfficeKit* pThis, + LibreOfficeKitCallback pCallback, + void* pData); ++ ++ /// @see lok::Office::getFilterTypes(). ++ char* (*getFilterTypes) (LibreOfficeKit* pThis); + #endif + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 7f96e194e56c..207a9ce6e883 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -353,6 +353,27 @@ public: + { + return mpThis->pClass->getError(mpThis); + } ++ ++#ifdef LOK_USE_UNSTABLE_API ++ /** ++ * Returns details of filter types. ++ * ++ * Example returned string: ++ * ++ * { ++ * "writer8": { ++ * "MediaType": "application/vnd.oasis.opendocument.text" ++ * }, ++ * "calc8": { ++ * "MediaType": "application/vnd.oasis.opendocument.spreadsheet" ++ * } ++ * } ++ */ ++ inline char* getFilterTypes() ++ { ++ return mpThis->pClass->getFilterTypes(mpThis); ++ } ++#endif // LOK_USE_UNSTABLE_API + }; + + /// Factory method to create a lok::Office instance. +-- +2.12.0 + diff --git a/SOURCES/0158-desktop-make-LibLibreOffice_Impl-visible-to-testcase.patch b/SOURCES/0158-desktop-make-LibLibreOffice_Impl-visible-to-testcase.patch new file mode 100644 index 0000000..7a66429 --- /dev/null +++ b/SOURCES/0158-desktop-make-LibLibreOffice_Impl-visible-to-testcase.patch @@ -0,0 +1,116 @@ +From 9b45ae57735ee9f7a64ceb7cac8b23e322a63bfc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 25 Sep 2015 01:06:31 +0200 +Subject: [PATCH 158/398] desktop: make LibLibreOffice_Impl visible to + testcases + +(cherry picked from commit 14a9a7d52074104afa24278a7a350f05d6df572a) + +Change-Id: I345a6cab57cc594614e348700bb3c1c9a0673989 +--- + desktop/inc/lib/init.hxx | 12 +++++++++++ + desktop/source/lib/init.cxx | 51 +++++++++++++++++---------------------------- + 2 files changed, 31 insertions(+), 32 deletions(-) + +diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx +index b17f82566daf..81e7eb61664e 100644 +--- a/desktop/inc/lib/init.hxx ++++ b/desktop/inc/lib/init.hxx +@@ -11,6 +11,7 @@ + #include + #include + #include "../../source/inc/desktopdllapi.h" ++#include + + using namespace css; + using namespace boost; +@@ -24,4 +25,15 @@ namespace desktop { + explicit LibLODocument_Impl(const uno::Reference &xComponent); + ~LibLODocument_Impl(); + }; ++ ++ struct DESKTOP_DLLPUBLIC LibLibreOffice_Impl : public _LibreOfficeKit ++ { ++ OUString maLastExceptionMsg; ++ std::shared_ptr< LibreOfficeKitClass > m_pOfficeClass; ++ oslThread maThread; ++ LibreOfficeKitCallback mpCallback; ++ void *mpCallbackData; ++ ++ LibLibreOffice_Impl(); ++ }; + } +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 57697fabce4c..8e4c0f3ab4e5 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -86,10 +86,6 @@ using namespace vcl; + using namespace desktop; + using namespace utl; + +-using namespace boost; +- +-struct LibLibreOffice_Impl; +- + static LibLibreOffice_Impl *gImpl = NULL; + static weak_ptr< LibreOfficeKitClass > gOfficeClass; + static weak_ptr< LibreOfficeKitDocumentClass > gDocumentClass; +@@ -322,36 +318,27 @@ static void lo_registerCallback (LibreOfficeKit* pThis, + void* pData); + static char* lo_getFilterTypes(LibreOfficeKit* pThis); + +-struct LibLibreOffice_Impl : public _LibreOfficeKit ++LibLibreOffice_Impl::LibLibreOffice_Impl() ++ : maThread(0) ++ , mpCallback(nullptr) ++ , mpCallbackData(nullptr) + { +- OUString maLastExceptionMsg; +- shared_ptr< LibreOfficeKitClass > m_pOfficeClass; +- oslThread maThread; +- LibreOfficeKitCallback mpCallback; +- void *mpCallbackData; +- +- LibLibreOffice_Impl() +- : maThread(0) +- , mpCallback(nullptr) +- , mpCallbackData(nullptr) +- { +- if(!(m_pOfficeClass = gOfficeClass.lock())) { +- m_pOfficeClass.reset(new LibreOfficeKitClass); +- m_pOfficeClass->nSize = sizeof(LibreOfficeKitClass); +- +- m_pOfficeClass->destroy = lo_destroy; +- m_pOfficeClass->documentLoad = lo_documentLoad; +- m_pOfficeClass->getError = lo_getError; +- m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions; +- m_pOfficeClass->registerCallback = lo_registerCallback; +- m_pOfficeClass->getFilterTypes = lo_getFilterTypes; +- +- gOfficeClass = m_pOfficeClass; +- } +- +- pClass = m_pOfficeClass.get(); ++ if(!(m_pOfficeClass = gOfficeClass.lock())) { ++ m_pOfficeClass.reset(new LibreOfficeKitClass); ++ m_pOfficeClass->nSize = sizeof(LibreOfficeKitClass); ++ ++ m_pOfficeClass->destroy = lo_destroy; ++ m_pOfficeClass->documentLoad = lo_documentLoad; ++ m_pOfficeClass->getError = lo_getError; ++ m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions; ++ m_pOfficeClass->registerCallback = lo_registerCallback; ++ m_pOfficeClass->getFilterTypes = lo_getFilterTypes; ++ ++ gOfficeClass = m_pOfficeClass; + } +-}; ++ ++ pClass = m_pOfficeClass.get(); ++} + + namespace + { +-- +2.12.0 + diff --git a/SOURCES/0159-fix-build.patch b/SOURCES/0159-fix-build.patch new file mode 100644 index 0000000..88a3e04 --- /dev/null +++ b/SOURCES/0159-fix-build.patch @@ -0,0 +1,57 @@ +From 22f4b009e889ba9d08244ff3c7b57c2faade3903 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Sun, 19 Mar 2017 21:16:15 +0100 +Subject: [PATCH 159/398] fix build + +Change-Id: Id1067aef106764484584a30fb55efebb7868f24a +--- + desktop/inc/lib/init.hxx | 3 +-- + desktop/source/lib/init.cxx | 6 ++---- + 2 files changed, 3 insertions(+), 6 deletions(-) + +diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx +index 81e7eb61664e..d3a42fb10bde 100644 +--- a/desktop/inc/lib/init.hxx ++++ b/desktop/inc/lib/init.hxx +@@ -14,13 +14,12 @@ + #include + + using namespace css; +-using namespace boost; + + namespace desktop { + struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public _LibreOfficeKitDocument + { + uno::Reference mxComponent; +- shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; ++ std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; + + explicit LibLODocument_Impl(const uno::Reference &xComponent); + ~LibLODocument_Impl(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 8e4c0f3ab4e5..5d716abdf8c4 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -13,8 +13,6 @@ + #include + #include + +-#include +-#include + #include + + #define LOK_USE_UNSTABLE_API +@@ -87,8 +85,8 @@ using namespace desktop; + using namespace utl; + + static LibLibreOffice_Impl *gImpl = NULL; +-static weak_ptr< LibreOfficeKitClass > gOfficeClass; +-static weak_ptr< LibreOfficeKitDocumentClass > gDocumentClass; ++static std::weak_ptr< LibreOfficeKitClass > gOfficeClass; ++static std::weak_ptr< LibreOfficeKitDocumentClass > gDocumentClass; + + typedef struct + { +-- +2.12.0 + diff --git a/SOURCES/0160-Add-lok-Office-getFilterTypes-testcase.patch b/SOURCES/0160-Add-lok-Office-getFilterTypes-testcase.patch new file mode 100644 index 0000000..6a10cc8 --- /dev/null +++ b/SOURCES/0160-Add-lok-Office-getFilterTypes-testcase.patch @@ -0,0 +1,53 @@ +From 2779f57b90defc7f9fe381a221ad285381a65964 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 25 Sep 2015 09:06:28 +0200 +Subject: [PATCH 160/398] Add lok::Office::getFilterTypes() testcase + +Change-Id: I9fa710288729b904f2f1c5b3c575212ef21c8a79 +(cherry picked from commit edb9ef41f29bf3477b8985ee409ce2d22214e63f) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 0cd88cefffa0..d7b93472c1b5 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -51,11 +51,13 @@ public: + void testGetStyles(); + void testGetFonts(); + void testCreateView(); ++ void testGetFilterTypes(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); + CPPUNIT_TEST(testGetFonts); + CPPUNIT_TEST(testCreateView); ++ CPPUNIT_TEST(testGetFilterTypes); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -150,6 +152,20 @@ void DesktopLOKTest::testCreateView() + closeDoc(); + } + ++void DesktopLOKTest::testGetFilterTypes() ++{ ++ LibLibreOffice_Impl aOffice; ++ char* pJSON = aOffice.m_pOfficeClass->getFilterTypes(&aOffice); ++ ++ std::stringstream aStream(pJSON); ++ boost::property_tree::ptree aTree; ++ boost::property_tree::read_json(aStream, aTree); ++ ++ CPPUNIT_ASSERT(aTree.size() > 0); ++ CPPUNIT_ASSERT_EQUAL(std::string("application/vnd.oasis.opendocument.text"), aTree.get_child("writer8").get_child("MediaType").get_value()); ++ free(pJSON); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +-- +2.12.0 + diff --git a/SOURCES/0161-Move-all-introspection-comments-to-header-file.patch b/SOURCES/0161-Move-all-introspection-comments-to-header-file.patch new file mode 100644 index 0000000..7b7180a --- /dev/null +++ b/SOURCES/0161-Move-all-introspection-comments-to-header-file.patch @@ -0,0 +1,377 @@ +From 0942d9f6f6057e83fb542a008dfc80c6e1dcc98e Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 24 Sep 2015 14:41:26 +0200 +Subject: [PATCH 161/398] Move all introspection comments to header file + +... wherever possible. There are few things we can't move to +header file, for example, the comments corresponding to GObject +properties, and signals. + +Change-Id: If74d61b17ccee11f8a056f3a93040d2cff2dd98d +Reviewed-on: https://gerrit.libreoffice.org/18863 +Reviewed-by: Miklos Vajna +Tested-by: Miklos Vajna +(cherry picked from commit 392437393d97a157e8291d20f1d6b6ac357ff0db) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 132 ++++++++++++++++++++++++++++- + libreofficekit/source/gtk/lokdocview.cxx | 87 +------------------ + 2 files changed, 129 insertions(+), 90 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index f17925b4c53a..81f42105d374 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -40,54 +40,178 @@ struct _LOKDocViewClass + + GType lok_doc_view_get_type (void) G_GNUC_CONST; + ++/** ++ * lok_doc_view_new: ++ * @pPath: LibreOffice install path. ++ * @cancellable: The cancellable object that you can use to cancel this ++ * operation. ++ * @error: The error that will be set if the object fails to initialize. ++ * ++ * Returns: (transfer none): The #LOKDocView widget instance. ++ */ + GtkWidget* lok_doc_view_new (const gchar* pPath, + GCancellable *cancellable, + GError **error); + ++/** ++ * lok_doc_view_new_from_widget: ++ * @pDocView: The #LOKDocView instance ++ * ++ * Returns: (transfer none): The #LOKDocView widget instance. ++ */ + GtkWidget* lok_doc_view_new_from_widget (LOKDocView* pDocView); + ++/** ++ * lok_doc_view_open_document: ++ * @pDocView: The #LOKDocView instance ++ * @pPath: (transfer full): The path of the document that #LOKDocView widget should try to open ++ * @cancellable: ++ * @callback: ++ * @userdata: ++ * ++ * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise ++ */ + void lok_doc_view_open_document (LOKDocView* pDocView, + const gchar* pPath, + GCancellable* cancellable, + GAsyncReadyCallback callback, + gpointer userdata); + ++/** ++ * lok_doc_view_open_document_finish: ++ * @pDocView: The #LOKDocView instance ++ * @res: ++ * @error: ++ * ++ * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise ++ */ + gboolean lok_doc_view_open_document_finish (LOKDocView* pDocView, + GAsyncResult* res, + GError** error); + +-/// Gets the document the viewer displays. ++/** ++ * lok_doc_view_get_document: ++ * @pDocView: The #LOKDocView instance ++ * ++ * Gets the document the viewer displays. ++ * ++ * Returns: The #LibreOfficeKitDocument instance the widget is currently showing ++ */ + LibreOfficeKitDocument* lok_doc_view_get_document (LOKDocView* pDocView); + ++/** ++ * lok_doc_view_set_zoom: ++ * @pDocView: The #LOKDocView instance ++ * @fZoom: The new zoom level that pDocView must set it into. ++ * ++ * Sets the new zoom level for the widget. ++ */ + void lok_doc_view_set_zoom (LOKDocView* pDocView, + float fZoom); ++ ++/** ++ * lok_doc_view_get_zoom: ++ * @pDocView: The #LOKDocView instance ++ * ++ * Returns: The current zoom factor value in float for pDocView ++ */ + float lok_doc_view_get_zoom (LOKDocView* pDocView); + ++/** ++ * lok_doc_view_get_parts: ++ * @pDocView: The #LOKDocView instance ++ */ + int lok_doc_view_get_parts (LOKDocView* pDocView); ++ ++/** ++ * lok_doc_view_get_part: ++ * @pDocView: The #LOKDocView instance ++ */ + int lok_doc_view_get_part (LOKDocView* pDocView); ++ ++/** ++ * lok_doc_view_set_part: ++ * @pDocView: The #LOKDocView instance ++ * @nPart: ++ */ + void lok_doc_view_set_part (LOKDocView* pDocView, + int nPart); ++ ++/** ++ * lok_doc_view_get_part_name: ++ * @pDocView: The #LOKDocView instance ++ * @nPart: ++ */ + char* lok_doc_view_get_part_name (LOKDocView* pDocView, + int nPart); ++ ++/** ++ * lok_doc_view_set_partmode: ++ * @pDocView: The #LOKDocView instance ++ * @nPartMode: ++ */ + void lok_doc_view_set_partmode (LOKDocView* pDocView, + int nPartMode); + ++/** ++ * lok_doc_view_reset_view: ++ * @pDocView: The #LOKDocView instance ++ */ + void lok_doc_view_reset_view (LOKDocView* pDocView); + +-/// Sets if the viewer is actually an editor or not. ++/** ++ * lok_doc_view_set_edit: ++ * @pDocView: The #LOKDocView instance ++ * @bEdit: %TRUE if the pDocView should go in edit mode, %FALSE otherwise ++ * ++ * Sets if the viewer is actually an editor or not. ++ */ + void lok_doc_view_set_edit (LOKDocView* pDocView, + gboolean bEdit); +-/// Gets if the viewer is actually an editor or not. ++ ++/** ++ * lok_doc_view_get_edit: ++ * @pDocView: The #LOKDocView instance ++ * ++ * Gets if the viewer is actually an editor or not. ++ * ++ * Returns: %TRUE if the given pDocView is in edit mode. ++ */ + gboolean lok_doc_view_get_edit (LOKDocView* pDocView); + +-/// Posts the .uno: command to the LibreOfficeKit. ++/** ++ * lok_doc_view_post_command: ++ * @pDocView: the #LOKDocView instance ++ * @pCommand: the command to issue to LO core ++ * @pArguments: the arguments to the given command ++ * ++ * Posts the .uno: command to the LibreOfficeKit. ++ */ + void lok_doc_view_post_command (LOKDocView* pDocView, + const gchar* pCommand, + const gchar* pArguments); + ++/** ++ * lok_doc_view_pixel_to_twip: ++ * @pDocView: The #LOKDocView instance ++ * @fInput: The value in pixels to convert to twips ++ * ++ * Converts the value in pixels to twips according to zoom level. ++ * ++ * Returns: The corresponding value in twips ++ */ + float lok_doc_view_pixel_to_twip (LOKDocView* pDocView, + float fInput); + ++/** ++ * lok_doc_view_twip_to_pixel: ++ * @pDocView: The #LOKDocView instance ++ * @fInput: The value in twips to convert to pixels ++ * ++ * Converts the value in twips to pixels according to zoom level. ++ * ++ * Returns: The corresponding value in pixels ++ */ + float lok_doc_view_twip_to_pixel (LOKDocView* pDocView, + float fInput); + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 60304b4ff59c..7c52ce2e2efb 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1843,15 +1843,6 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_INT, G_TYPE_INT); + } + +-/** +- * lok_doc_view_new: +- * @pPath: LibreOffice install path. +- * @cancellable: The cancellable object that you can use to cancel this +- * operation. +- * @error: The error that will be set if the object fails to initialize. +- * +- * Returns: (transfer none): The #LOKDocView widget instance. +- */ + SAL_DLLPUBLIC_EXPORT GtkWidget* + lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + { +@@ -1873,14 +1864,6 @@ SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOK + return pNewDocView; + } + +-/** +- * lok_doc_view_open_document_finish: +- * @pDocView: The #LOKDocView instance +- * @res: +- * @error: +- * +- * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise +- */ + SAL_DLLPUBLIC_EXPORT gboolean + lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GError** error) + { +@@ -1894,17 +1877,6 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr + return g_task_propagate_boolean(task, error); + } + +- +-/** +- * lok_doc_view_open_document: +- * @pDocView: The #LOKDocView instance +- * @pPath: (transfer full): The path of the document that #LOKDocView widget should try to open +- * @cancellable: +- * @callback: +- * @userdata: +- * +- * Returns: %TRUE if the document is loaded succesfully, %FALSE otherwise +- */ + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_open_document (LOKDocView* pDocView, + const gchar* pPath, +@@ -1925,12 +1897,6 @@ lok_doc_view_open_document (LOKDocView* pDocView, + g_object_unref(task); + } + +-/** +- * lok_doc_view_get_document: +- * @pDocView: The #LOKDocView instance +- * +- * Returns: The #LibreOfficeKitDocument instance the widget is currently showing +- */ + SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* + lok_doc_view_get_document (LOKDocView* pDocView) + { +@@ -1938,13 +1904,6 @@ lok_doc_view_get_document (LOKDocView* pDocView) + return priv->m_pDocument; + } + +-/** +- * lok_doc_view_set_zoom: +- * @pDocView: The #LOKDocView instance +- * @fZoom: The new zoom level that pDocView must set it into. +- * +- * Sets the new zoom level for the widget. +- */ + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + { +@@ -1963,12 +1922,6 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + nDocumentHeightPixels); + } + +-/** +- * lok_doc_view_get_zoom: +- * @pDocView: The #LOKDocView instance +- * +- * Returns: The current zoom factor value in float for pDocView +- */ + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_get_zoom (LOKDocView* pDocView) + { +@@ -2036,13 +1989,6 @@ lok_doc_view_reset_view(LOKDocView* pDocView) + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + +-/** +- * lok_doc_view_set_edit: +- * @pDocView: The #LOKDocView instance +- * @bEdit: %TRUE if the pDocView should go in edit mode, %FALSE otherwise +- * +- * Sets the edit-mode for pDocView +- */ + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_edit(LOKDocView* pDocView, + gboolean bEdit) +@@ -2057,12 +2003,6 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + g_object_unref(task); + } + +-/** +- * lok_doc_view_get_edit: +- * @pDocView: The #LOKDocView instance +- * +- * Returns: %TRUE if the given pDocView is in edit mode. +- */ + SAL_DLLPUBLIC_EXPORT gboolean + lok_doc_view_get_edit (LOKDocView* pDocView) + { +@@ -2070,14 +2010,7 @@ lok_doc_view_get_edit (LOKDocView* pDocView) + return priv->m_bEdit; + } + +-/** +- * lok_doc_view_post_command: +- * @pDocView: the #LOKDocView instance +- * @pCommand: the command to issue to LO core +- * @pArguments: the arguments to the given command +- * +- * This methods forwards your command to LO core. +-*/ ++ + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_post_command (LOKDocView* pDocView, + const gchar* pCommand, +@@ -2094,15 +2027,6 @@ lok_doc_view_post_command (LOKDocView* pDocView, + g_object_unref(task); + } + +-/** +- * lok_doc_view_pixel_to_twip: +- * @pDocView: The #LOKDocView instance +- * @fInput: The value in pixels to convert to twips +- * +- * Converts the value in pixels to twips according to zoom level. +- * +- * Returns: The corresponding value in twips +- */ + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + { +@@ -2110,15 +2034,6 @@ lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + return pixelToTwip(fInput, priv->m_fZoom); + } + +-/** +- * lok_doc_view_twip_to_pixel: +- * @pDocView: The #LOKDocView instance +- * @fInput: The value in twips to convert to pixels +- * +- * Converts the value in twips to pixels according to zoom level. +- * +- * Returns: The corresponding value in pixels +- */ + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_twip_to_pixel (LOKDocView* pDocView, float fInput) + { +-- +2.12.0 + diff --git a/SOURCES/0162-sd-tiled-rendering-avoid-passing-explicit-0-vcl-Wind.patch b/SOURCES/0162-sd-tiled-rendering-avoid-passing-explicit-0-vcl-Wind.patch new file mode 100644 index 0000000..98b7cab --- /dev/null +++ b/SOURCES/0162-sd-tiled-rendering-avoid-passing-explicit-0-vcl-Wind.patch @@ -0,0 +1,71 @@ +From 5432f81622409e99a465adddbabaa21e0acaa2ed Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 28 Sep 2015 09:05:18 +0200 +Subject: [PATCH 162/398] sd tiled rendering: avoid passing explicit 0 + vcl::Window + +Seen as dereferenced in svx for Impress table handling, and doing some +logic <-> pixel conversion -- and mpActiveWindow not being 0 in that +case. + +Change-Id: I7f7c41a7d366704f6f8b9a7971f763c6661c8799 +(cherry picked from commit 6a9f985ea698355f38c1681c1eb276f8b9dd859c) +--- + sd/source/ui/view/viewshel.cxx | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx +index 51a049e4d66d..241950ce043c 100644 +--- a/sd/source/ui/view/viewshel.cxx ++++ b/sd/source/ui/view/viewshel.cxx +@@ -521,7 +521,7 @@ void ViewShell::LogicMouseButtonDown(const MouseEvent& rMouseEvent) + Point aPoint = mpActiveWindow->GetPointerPosPixel(); + mpActiveWindow->SetLastMousePos(rMouseEvent.GetPosPixel()); + +- MouseButtonDown(rMouseEvent, 0); ++ MouseButtonDown(rMouseEvent, mpActiveWindow); + + mpActiveWindow->SetPointerPosPixel(aPoint); + } +@@ -534,7 +534,7 @@ void ViewShell::LogicMouseButtonUp(const MouseEvent& rMouseEvent) + Point aPoint = mpActiveWindow->GetPointerPosPixel(); + mpActiveWindow->SetLastMousePos(rMouseEvent.GetPosPixel()); + +- MouseButtonUp(rMouseEvent, 0); ++ MouseButtonUp(rMouseEvent, mpActiveWindow); + + mpActiveWindow->SetPointerPosPixel(aPoint); + } +@@ -547,7 +547,7 @@ void ViewShell::LogicMouseMove(const MouseEvent& rMouseEvent) + Point aPoint = mpActiveWindow->GetPointerPosPixel(); + mpActiveWindow->SetLastMousePos(rMouseEvent.GetPosPixel()); + +- MouseMove(rMouseEvent, 0); ++ MouseMove(rMouseEvent, mpActiveWindow); + + mpActiveWindow->SetPointerPosPixel(aPoint); + } +@@ -631,16 +631,16 @@ void ViewShell::SetGraphicMm100Position(bool bStart, const Point& rPosition) + if (bStart) + { + MouseEvent aClickEvent(rPosition, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT); +- MouseButtonDown(aClickEvent, 0); ++ MouseButtonDown(aClickEvent, mpActiveWindow); + MouseEvent aMoveEvent(Point(rPosition.getX(), rPosition.getY()), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT); +- MouseMove(aMoveEvent, 0); ++ MouseMove(aMoveEvent, mpActiveWindow); + } + else + { + MouseEvent aMoveEvent(Point(rPosition.getX(), rPosition.getY()), 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT); +- MouseMove(aMoveEvent, 0); ++ MouseMove(aMoveEvent, mpActiveWindow); + MouseEvent aClickEvent(rPosition, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT); +- MouseButtonUp(aClickEvent, 0); ++ MouseButtonUp(aClickEvent, mpActiveWindow); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0163-libreofficekit-fix-mismatched-free-delete.patch b/SOURCES/0163-libreofficekit-fix-mismatched-free-delete.patch new file mode 100644 index 0000000..573b049 --- /dev/null +++ b/SOURCES/0163-libreofficekit-fix-mismatched-free-delete.patch @@ -0,0 +1,202 @@ +From 6ac4def0a86d75c2ffc49ef8319515ba4bff26cc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 28 Sep 2015 09:06:10 +0200 +Subject: [PATCH 163/398] libreofficekit: fix mismatched free() / delete + +Change-Id: I60eb53d4bf9943fd52e0a9d8e3574a7d1cc027e0 +(cherry picked from commit 0067b4df75cdbeb325024cd2b66e3d64fe8b3fcd) +--- + libreofficekit/source/gtk/lokdocview.cxx | 28 ++++++++++++++-------------- + libreofficekit/source/gtk/tilebuffer.cxx | 11 ++++++++--- + libreofficekit/source/gtk/tilebuffer.hxx | 3 +++ + 3 files changed, 25 insertions(+), 17 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 7c52ce2e2efb..6679cee56cd3 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -314,7 +314,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYUP; + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } +@@ -325,7 +325,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYINPUT; + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } +@@ -951,7 +951,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -970,7 +970,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1019,7 +1019,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom); + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom); +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1047,7 +1047,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); + pLOEvent->m_nPostMouseEventCount = nCount; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1065,7 +1065,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); + pLOEvent->m_nPostMouseEventCount = nCount; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1153,7 +1153,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1169,7 +1169,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); + pLOEvent->m_nPostMouseEventCount = 1; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1891,7 +1891,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + pLOEvent->m_pPath = pPath; + + priv->m_aDocPath = pPath; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1953,7 +1953,7 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); + + pLOEvent->m_nPart = nPart; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1975,7 +1975,7 @@ lok_doc_view_set_partmode(LOKDocView* pDocView, + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); + pLOEvent->m_nPartMode = nPartMode; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -1997,7 +1997,7 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); + pLOEvent->m_bEdit = bEdit; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); +@@ -2022,7 +2022,7 @@ lok_doc_view_post_command (LOKDocView* pDocView, + pLOEvent->m_pCommand = pCommand; + pLOEvent->m_pArguments = g_strdup(pArguments); + +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); + g_object_unref(task); + } +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 85f6eb0422c2..687ef44d6468 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -73,7 +73,7 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, + pLOEvent->m_nPaintTileX = x; + pLOEvent->m_nPaintTileY = y; + pLOEvent->m_fPaintTileZoom = fZoom; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + } + } +@@ -89,7 +89,7 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + pLOEvent->m_nPaintTileX = x; + pLOEvent->m_nPaintTileY = y; + pLOEvent->m_fPaintTileZoom = fZoom; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + return m_mTiles[index]; + } +@@ -99,7 +99,7 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + pLOEvent->m_nPaintTileX = x; + pLOEvent->m_nPaintTileY = y; + pLOEvent->m_fPaintTileZoom = fZoom; +- g_task_set_task_data(task, pLOEvent, g_free); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); + return m_DummyTile; + } +@@ -107,5 +107,10 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + return m_mTiles[index]; + } + ++void LOEvent::destroy(void* pMemory) ++{ ++ LOEvent* pLOEvent = static_cast(pMemory); ++ delete pLOEvent; ++} + + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index d4e7120e6587..fdcdd15eddd7 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -237,6 +237,9 @@ struct LOEvent + , m_nSetGraphicSelectionY(0) + { + } ++ ++ /// Wrapper around delete to help GLib. ++ static void destroy(void* pMemory); + }; + + #endif // INCLUDED_TILEBUFFER_HXX +-- +2.12.0 + diff --git a/SOURCES/0164-lok-add-Document-getPartPageRectangles.patch b/SOURCES/0164-lok-add-Document-getPartPageRectangles.patch new file mode 100644 index 0000000..8ead7f6 --- /dev/null +++ b/SOURCES/0164-lok-add-Document-getPartPageRectangles.patch @@ -0,0 +1,248 @@ +From ed4ab7cba0e5f7eaf18b4f10b731d52ae3b8f049 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 29 Sep 2015 10:47:31 +0200 +Subject: [PATCH 164/398] lok: add Document::getPartPageRectangles() + +(cherry picked from commit d355207b45755cfe1eef0147bc25ead931741684) + +Change-Id: I20acd44f7a81471982ba96ad3894a9124e035c5f +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 25 +++++++++++++++++++++++++ + desktop/source/lib/init.cxx | 19 +++++++++++++++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 3 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 14 ++++++++++++++ + include/vcl/ITiledRenderable.hxx | 8 ++++++++ + sw/inc/crsrsh.hxx | 3 +++ + sw/inc/unotxdoc.hxx | 2 ++ + sw/source/core/crsr/crsrsh.cxx | 14 ++++++++++++++ + sw/source/uibase/uno/unotxdoc.cxx | 11 +++++++++++ + 9 files changed, 99 insertions(+) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index d7b93472c1b5..a7696d824bee 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -52,12 +52,14 @@ public: + void testGetFonts(); + void testCreateView(); + void testGetFilterTypes(); ++ void testGetPartPageRectangles(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); + CPPUNIT_TEST(testGetFonts); + CPPUNIT_TEST(testCreateView); + CPPUNIT_TEST(testGetFilterTypes); ++ CPPUNIT_TEST(testGetPartPageRectangles); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -152,6 +154,29 @@ void DesktopLOKTest::testCreateView() + closeDoc(); + } + ++void DesktopLOKTest::testGetPartPageRectangles() ++{ ++ // Test that we get as many page rectangles as expected: blank document is ++ // one page. ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ char* pRectangles = pDocument->pClass->getPartPageRectangles(pDocument); ++ OUString sRectangles = OUString::fromUtf8(pRectangles); ++ ++ std::vector aRectangles; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ OUString aRectangle = sRectangles.getToken(0, ';', nIndex); ++ if (!aRectangle.isEmpty()) ++ aRectangles.push_back(aRectangle); ++ } ++ while (nIndex >= 0); ++ CPPUNIT_ASSERT_EQUAL(static_cast(1), aRectangles.size()); ++ ++ free(pRectangles); ++ closeDoc(); ++} ++ + void DesktopLOKTest::testGetFilterTypes() + { + LibLibreOffice_Impl aOffice; +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 5d716abdf8c4..4432ec8ea889 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -203,6 +203,7 @@ static void doc_destroy(LibreOfficeKitDocument* pThis); + static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* pUrl, const char* pFormat, const char* pFilterOptions); + static int doc_getDocumentType(LibreOfficeKitDocument* pThis); + static int doc_getParts(LibreOfficeKitDocument* pThis); ++static char* doc_getPartPageRectangles(LibreOfficeKitDocument* pThis); + static int doc_getPart(LibreOfficeKitDocument* pThis); + static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart); + static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart); +@@ -265,6 +266,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference saveAs = doc_saveAs; + m_pDocumentClass->getDocumentType = doc_getDocumentType; + m_pDocumentClass->getParts = doc_getParts; ++ m_pDocumentClass->getPartPageRectangles = doc_getPartPageRectangles; + m_pDocumentClass->getPart = doc_getPart; + m_pDocumentClass->setPart = doc_setPart; + m_pDocumentClass->getPartName = doc_getPartName; +@@ -658,6 +660,23 @@ static void doc_setPart(LibreOfficeKitDocument* pThis, int nPart) + pDoc->setPart( nPart ); + } + ++static char* doc_getPartPageRectangles(LibreOfficeKitDocument* pThis) ++{ ++ ITiledRenderable* pDoc = getTiledRenderable(pThis); ++ if (!pDoc) ++ { ++ gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; ++ return 0; ++ } ++ ++ OUString sRectangles = pDoc->getPartPageRectangles(); ++ OString aString = OUStringToOString(sRectangles, RTL_TEXTENCODING_UTF8); ++ char* pMemory = static_cast(malloc(aString.getLength() + 1)); ++ strcpy(pMemory, aString.getStr()); ++ return pMemory; ++ ++} ++ + static char* doc_getPartName(LibreOfficeKitDocument* pThis, int nPart) + { + ITiledRenderable* pDoc = getTiledRenderable(pThis); +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index d5094bdb1b76..d83dd49f32b5 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -85,6 +85,9 @@ struct _LibreOfficeKitDocumentClass + /// @see lok::Document::getParts(). + int (*getParts) (LibreOfficeKitDocument* pThis); + ++ /// @see lok::Document::getPartPageRectangles(). ++ char* (*getPartPageRectangles) (LibreOfficeKitDocument* pThis); ++ + /// @see lok::Document::getPart(). + int (*getPart) (LibreOfficeKitDocument* pThis); + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 207a9ce6e883..cd12ad64f245 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -76,6 +76,20 @@ public: + return mpDoc->pClass->getParts(mpDoc); + } + ++ /** ++ * Get the logical rectangle of each part in the document. ++ * ++ * A part refers to an individual page in Writer and has no relevant for ++ * Calc or Impress. ++ * ++ * @return a rectangle list, using the same format as ++ * LOK_CALLBACK_TEXT_SELECTION. ++ */ ++ inline char* getPartPageRectangles() ++ { ++ return mpDoc->pClass->getPartPageRectangles(mpDoc); ++ } ++ + /// Get the current part of the document. + inline int getPart() + { +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 6639745e4a2f..fd336f603296 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -139,6 +139,14 @@ public: + * @see lok::Document::resetSelection(). + */ + virtual void resetSelection() = 0; ++ ++ /** ++ * @see lok::Document::getPartPageRectangles(). ++ */ ++ virtual OUString getPartPageRectangles() ++ { ++ return OUString(); ++ } + }; + + } // namespace vcl +diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx +index 073a8dfb1d8d..ee849074cd7d 100644 +--- a/sw/inc/crsrsh.hxx ++++ b/sw/inc/crsrsh.hxx +@@ -852,6 +852,9 @@ public: + @return the textual description of the current selection + */ + OUString GetCrsrDescr() const; ++ ++ /// Implementation of lok::Document::getPartPageRectangles() for Writer. ++ OUString getPageRectangles(); + }; + + // Cursor Inlines: +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index 9f0b03b3af38..311147eeaaea 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -431,6 +431,8 @@ public: + virtual void setGraphicSelection(int nType, int nX, int nY) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::resetSelection(). + virtual void resetSelection() SAL_OVERRIDE; ++ /// @see vcl::ITiledRenderable::getPartPageRectangles(). ++ virtual OUString getPartPageRectangles() SAL_OVERRIDE; + + // ::com::sun::star::tiledrendering::XTiledRenderable + virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) SAL_OVERRIDE; +diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx +index cbb89aca8868..ffff6a6b2a93 100644 +--- a/sw/source/core/crsr/crsrsh.cxx ++++ b/sw/source/core/crsr/crsrsh.cxx +@@ -1201,6 +1201,20 @@ sal_uInt16 SwCrsrShell::GetPageCnt() + return GetLayout()->GetPageNum(); + } + ++OUString SwCrsrShell::getPageRectangles() ++{ ++ CurrShell aCurr(this); ++ SwRootFrm* pLayout = GetLayout(); ++ std::stringstream ss; ++ for (const SwFrm* pFrm = pLayout->GetLower(); pFrm; pFrm = pFrm->GetNext()) ++ { ++ if (pFrm != pLayout->GetLower()) ++ ss << "; "; ++ ss << pFrm->Frm().Left() << ", " << pFrm->Frm().Top() << ", " << pFrm->Frm().Width() << ", " << pFrm->Frm().Height(); ++ } ++ return OUString::fromUtf8(ss.str().c_str()); ++} ++ + /// go to the next SSelection + bool SwCrsrShell::GoNextCrsr() + { +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index d6315d2964ae..26ab19f170b9 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3177,6 +3177,17 @@ int SwXTextDocument::getParts() + return pWrtShell->GetPageCnt(); + } + ++OUString SwXTextDocument::getPartPageRectangles() ++{ ++ SolarMutexGuard aGuard; ++ ++ SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); ++ if (!pWrtShell) ++ return OUString(); ++ ++ return pWrtShell->getPageRectangles(); ++} ++ + int SwXTextDocument::getPart() + { + SolarMutexGuard aGuard; +-- +2.12.0 + diff --git a/SOURCES/0165-coverity-1325053-Dereference-after-null-check.patch b/SOURCES/0165-coverity-1325053-Dereference-after-null-check.patch new file mode 100644 index 0000000..e872274 --- /dev/null +++ b/SOURCES/0165-coverity-1325053-Dereference-after-null-check.patch @@ -0,0 +1,37 @@ +From e8191e29362314214d09dd774ab6993d076d852d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Tue, 29 Sep 2015 09:41:01 +0100 +Subject: [PATCH 165/398] coverity#1325053 Dereference after null check + +pre-change !pSh logic inverted at + +commit 1b15f4863e6d4b0a280ccd61713cbb1209ffe33e +Author: Miklos Vajna +Date: Fri Feb 6 12:12:02 2015 +0100 + + LOK: add LOK_CALLBACK_TEXT_SELECTION and implement it in sw + + Change-Id: I31662cb06add0d1a1c517b5f5416703aeaae1e77 + +Change-Id: If42741c4efce943aaff5081a1a75108470b2a488 +(cherry picked from commit 4a031d7c971558f89693925bb504c1157ab6bd04) +--- + sw/source/core/layout/trvlfrm.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx +index 65aa24f69e72..aec74f35feb3 100644 +--- a/sw/source/core/layout/trvlfrm.cxx ++++ b/sw/source/core/layout/trvlfrm.cxx +@@ -2019,7 +2019,7 @@ void SwRootFrm::CalcFrmRects(SwShellCrsr &rCrsr) + + SwViewShell *pSh = GetCurrShell(); + +- bool bIgnoreVisArea = false; ++ bool bIgnoreVisArea = true; + if (pSh) + bIgnoreVisArea = pSh->GetViewOptions()->IsPDFExport() || pSh->isTiledRendering(); + +-- +2.12.0 + diff --git a/SOURCES/0166-lokdocview-Reset-view-completely.patch b/SOURCES/0166-lokdocview-Reset-view-completely.patch new file mode 100644 index 0000000..76067c6 --- /dev/null +++ b/SOURCES/0166-lokdocview-Reset-view-completely.patch @@ -0,0 +1,74 @@ +From 54cbf52419e6318c2cdf19232f79a515ffb6e7f6 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 24 Sep 2015 18:47:01 +0200 +Subject: [PATCH 166/398] lokdocview: Reset view completely + +Resetting tiles only is not enough. We need to empty stale +selection rectangles, handle bars, cursor positions etc., so that +they do not interfere with next view to be opened using same +widget instance. + +We are not destroying the document here, so the widget would +still point to the same document unless it is made to point to +another document by subsequent lok_doc_view_open_document calls. + +Change-Id: I3c7cc789c8c7393b3793b4edf6aa96d54bc0b1a3 +Reviewed-on: https://gerrit.libreoffice.org/18866 +Reviewed-by: Miklos Vajna +Tested-by: Miklos Vajna +(cherry picked from commit c3ce35f0a12af2887b10987f76675174563487d7) +--- + libreofficekit/source/gtk/lokdocview.cxx | 37 ++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 6679cee56cd3..99476764e69d 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1986,6 +1986,43 @@ lok_doc_view_reset_view(LOKDocView* pDocView) + { + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + priv->m_aTileBuffer.resetAllTiles(); ++ priv->m_nLoadProgress = 0.0; ++ ++ memset(&priv->m_aVisibleCursor, 0, sizeof(priv->m_aVisibleCursor)); ++ priv->m_bCursorOverlayVisible = false; ++ priv->m_bCursorVisible = false; ++ ++ priv->m_nLastButtonPressTime = 0; ++ priv->m_nLastButtonReleaseTime = 0; ++ priv->m_aTextSelectionRectangles.clear(); ++ ++ memset(&priv->m_aTextSelectionStart, 0, sizeof(priv->m_aTextSelectionStart)); ++ memset(&priv->m_aTextSelectionEnd, 0, sizeof(priv->m_aTextSelectionEnd)); ++ memset(&priv->m_aGraphicSelection, 0, sizeof(priv->m_aGraphicSelection)); ++ priv->m_bInDragGraphicSelection = false; ++ ++ cairo_surface_destroy(priv->m_pHandleStart); ++ priv->m_pHandleStart = 0; ++ memset(&priv->m_aHandleStartRect, 0, sizeof(priv->m_aHandleStartRect)); ++ priv->m_bInDragStartHandle = false; ++ ++ cairo_surface_destroy(priv->m_pHandleMiddle); ++ priv->m_pHandleMiddle = 0; ++ memset(&priv->m_aHandleMiddleRect, 0, sizeof(priv->m_aHandleMiddleRect)); ++ priv->m_bInDragMiddleHandle = false; ++ ++ cairo_surface_destroy(priv->m_pHandleEnd); ++ priv->m_pHandleEnd = 0; ++ memset(&priv->m_aHandleEndRect, 0, sizeof(priv->m_aHandleEndRect)); ++ priv->m_bInDragEndHandle = false; ++ ++ cairo_surface_destroy(priv->m_pGraphicHandle); ++ priv->m_pGraphicHandle = 0; ++ memset(&priv->m_aGraphicHandleRects, 0, sizeof(priv->m_aGraphicHandleRects)); ++ memset(&priv->m_bInDragGraphicHandles, 0, sizeof(priv->m_bInDragGraphicHandles)); ++ ++ priv->m_nViewId = 0; ++ + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + +-- +2.12.0 + diff --git a/SOURCES/0167-Impress-set-current-page-Id-before-showing-the-new-p.patch b/SOURCES/0167-Impress-set-current-page-Id-before-showing-the-new-p.patch new file mode 100644 index 0000000..3de3ba1 --- /dev/null +++ b/SOURCES/0167-Impress-set-current-page-Id-before-showing-the-new-p.patch @@ -0,0 +1,61 @@ +From f7c573ccf8878bcd12babfe64ceca60252c967e6 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Fri, 7 Aug 2015 09:03:26 +0300 +Subject: [PATCH 167/398] Impress: set current page Id before showing the new + page + +For tiled rendering this has the effect of not invalidating the +previous slide when switching slides. After switching slides, an +invalidation occurs caused by showing the new slide, and calling +'GetPart' before 'SwitchPage' finishes returned the old part number. + +Change-Id: I1cafd0e51cd39be3a80d0559ae3051238b8df744 +Reviewed-on: https://gerrit.libreoffice.org/17562 +Tested-by: Jenkins +Reviewed-by: Samuel Mehrbrodt +Tested-by: Samuel Mehrbrodt +(cherry picked from commit 45576ea3b3c19d8fe545e984bf23708df90b1990) +--- + sd/source/ui/view/drviews1.cxx | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx +index ec192473ec6e..3b749419e860 100644 +--- a/sd/source/ui/view/drviews1.cxx ++++ b/sd/source/ui/view/drviews1.cxx +@@ -964,6 +964,7 @@ bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage) + } + + mpDrawView->HideSdrPage(); ++ maTabControl->SetCurPageId(nSelectedPage+1); + mpDrawView->ShowSdrPage(mpActualPage); + GetViewShellBase().GetDrawController().FireSwitchCurrentPage(mpActualPage); + +@@ -989,7 +990,6 @@ bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage) + } + } + +- maTabControl->SetCurPageId(nSelectedPage+1); + OUString aPageName = mpActualPage->GetName(); + + if (maTabControl->GetPageText(nSelectedPage+1) != aPageName) +@@ -1025,6 +1025,7 @@ bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage) + } + + mpDrawView->HideSdrPage(); ++ maTabControl->SetCurPageId(nSelectedPage+1); + + SdPage* pMaster = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind); + +@@ -1063,8 +1064,6 @@ bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage) + if (nPos != -1) + aLayoutName = aLayoutName.copy(0, nPos); + +- maTabControl->SetCurPageId(nSelectedPage+1); +- + if (maTabControl->GetPageText(nSelectedPage+1) != aLayoutName) + { + maTabControl->SetPageText(nSelectedPage+1, aLayoutName); +-- +2.12.0 + diff --git a/SOURCES/0168-desktop-vcl-support-transparency-in-VirtualDevices-w.patch b/SOURCES/0168-desktop-vcl-support-transparency-in-VirtualDevices-w.patch new file mode 100644 index 0000000..7131561 --- /dev/null +++ b/SOURCES/0168-desktop-vcl-support-transparency-in-VirtualDevices-w.patch @@ -0,0 +1,131 @@ +From 4678c8d368c3accd85c57745cf58218f5ea1b907 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 1 Oct 2015 14:17:21 +0200 +Subject: [PATCH 168/398] desktop, vcl: support transparency in VirtualDevices + with user-provided memory + +Change-Id: I65c31995c02a644aa436aecd065255fab38045e4 +(cherry picked from commit 1d3b613318654ceb2d34996ef8ca653cfe32a8ea) +--- + desktop/source/lib/init.cxx | 24 +++++++++++++++++++++++- + include/vcl/virdev.hxx | 2 ++ + vcl/source/gdi/virdev.cxx | 12 ++++++++---- + 3 files changed, 33 insertions(+), 5 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 4432ec8ea889..1f87146bacf8 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -754,10 +754,21 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + InitSvpForLibreOfficeKit(); + + ScopedVclPtrInstance< VirtualDevice > pDevice(nullptr, Size(1, 1), (sal_uInt16)32) ; ++ ++ // Set background to transparent by default. ++ memset(pBuffer, 0, nCanvasWidth * nCanvasHeight * 4); ++ pDevice->SetBackground(Wallpaper(Color(COL_TRANSPARENT))); ++ + boost::shared_array< sal_uInt8 > aBuffer( pBuffer, NoDelete< sal_uInt8 >() ); ++ ++ // Allocate a separate buffer for the alpha device. ++ std::vector aAlpha(nCanvasWidth * nCanvasHeight); ++ memset(aAlpha.data(), 0, nCanvasWidth * nCanvasHeight); ++ boost::shared_array aAlphaBuffer(aAlpha.data(), NoDelete()); ++ + pDevice->SetOutputSizePixelScaleOffsetAndBuffer( + Size(nCanvasWidth, nCanvasHeight), Fraction(1.0), Point(), +- aBuffer, true ); ++ aBuffer, aAlphaBuffer, true ); + + pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, + nTilePosX, nTilePosY, nTileWidth, nTileHeight); +@@ -771,6 +782,17 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + nTilePosX, nTilePosY, nTileWidth, nTileHeight); + #endif + ++ // Overwrite pBuffer's alpha channel with the separate alpha buffer. ++ for (int nRow = 0; nRow < nCanvasHeight; ++nRow) ++ { ++ for (int nCol = 0; nCol < nCanvasWidth; ++nCol) ++ { ++ const int nOffset = (nCanvasHeight * nRow) + nCol; ++ // VCL's transparent is 0, RGBA's transparent is 0xff. ++ pBuffer[nOffset * 4 +3] = 0xff - aAlpha[nOffset]; ++ } ++ } ++ + static bool bDebug = getenv("LOK_DEBUG") != 0; + if (bDebug) + { +diff --git a/include/vcl/virdev.hxx b/include/vcl/virdev.hxx +index 3720a19c98f3..85e0afd78131 100644 +--- a/include/vcl/virdev.hxx ++++ b/include/vcl/virdev.hxx +@@ -48,6 +48,7 @@ private: + const bool bTopDown ); + SAL_DLLPRIVATE bool ImplSetOutputSizePixel( const Size& rNewSize, bool bErase, + const basebmp::RawMemorySharedArray &pBuffer, ++ const basebmp::RawMemorySharedArray &pAlphaBuffer, + const bool bTopDown ); + + VirtualDevice (const VirtualDevice &) SAL_DELETED_FUNCTION; +@@ -127,6 +128,7 @@ public: + const Fraction& rScale, + const Point& rNewOffset, + const basebmp::RawMemorySharedArray &pBuffer, ++ const basebmp::RawMemorySharedArray &pAlphaBuffer, + const bool bTopDown = false ); + bool SetOutputSize( const Size& rNewSize, bool bErase = true ) + { return SetOutputSizePixel( LogicToPixel( rNewSize ), bErase ); } +diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx +index b24378de4b25..ee44d30267e8 100644 +--- a/vcl/source/gdi/virdev.cxx ++++ b/vcl/source/gdi/virdev.cxx +@@ -393,6 +393,7 @@ void VirtualDevice::ImplFillOpaqueRectangle( const Rectangle& rRect ) + + bool VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, bool bErase, + const basebmp::RawMemorySharedArray &pBuffer, ++ const basebmp::RawMemorySharedArray &pAlphaBuffer, + const bool bTopDown ) + { + if( InnerImplSetOutputSizePixel(rNewSize, bErase, pBuffer, bTopDown) ) +@@ -409,7 +410,7 @@ bool VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, bool bErase, + { + mpAlphaVDev = VclPtr::Create( *this, mnAlphaDepth ); + mpAlphaVDev->InnerImplSetOutputSizePixel(rNewSize, bErase, +- basebmp::RawMemorySharedArray(), ++ pAlphaBuffer, + bTopDown ); + } + +@@ -443,13 +444,16 @@ void VirtualDevice::EnableRTL( bool bEnable ) + + bool VirtualDevice::SetOutputSizePixel( const Size& rNewSize, bool bErase ) + { +- return ImplSetOutputSizePixel( rNewSize, bErase, basebmp::RawMemorySharedArray(), false ); ++ return ImplSetOutputSizePixel( rNewSize, bErase, basebmp::RawMemorySharedArray(), basebmp::RawMemorySharedArray(), false ); + } + + bool VirtualDevice::SetOutputSizePixelScaleOffsetAndBuffer( + const Size& rNewSize, const Fraction& rScale, const Point& rNewOffset, +- const basebmp::RawMemorySharedArray &pBuffer, const bool bTopDown ) ++ const basebmp::RawMemorySharedArray &pBuffer, const basebmp::RawMemorySharedArray &pAlphaBuffer, const bool bTopDown ) + { ++ if (pAlphaBuffer) ++ mnAlphaDepth = 8; ++ + if (pBuffer) { + MapMode mm = GetMapMode(); + mm.SetOrigin( rNewOffset ); +@@ -457,7 +461,7 @@ bool VirtualDevice::SetOutputSizePixelScaleOffsetAndBuffer( + mm.SetScaleY( rScale ); + SetMapMode( mm ); + } +- return ImplSetOutputSizePixel( rNewSize, true, pBuffer, bTopDown ); ++ return ImplSetOutputSizePixel( rNewSize, true, pBuffer, pAlphaBuffer, bTopDown ); + } + + void VirtualDevice::SetReferenceDevice( RefDevMode i_eRefDevMode ) +-- +2.12.0 + diff --git a/SOURCES/0169-sw-tiled-rendering-default-to-transparent-background.patch b/SOURCES/0169-sw-tiled-rendering-default-to-transparent-background.patch new file mode 100644 index 0000000..1f5d6f8 --- /dev/null +++ b/SOURCES/0169-sw-tiled-rendering-default-to-transparent-background.patch @@ -0,0 +1,36 @@ +From 6b9ab42904f9e37935834528bf360a2a6e3da70b Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 1 Oct 2015 16:43:00 +0200 +Subject: [PATCH 169/398] sw tiled rendering: default to transparent background + outside page frames + +Change-Id: Ie018a878eb7d7ef14a80a6b86020c114ff14da88 +(cherry picked from commit 4fe010cce872ef035fec376298e416f9799c4a21) +--- + sw/source/uibase/config/viewopt.cxx | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sw/source/uibase/config/viewopt.cxx b/sw/source/uibase/config/viewopt.cxx +index 190a6e3b5d72..7597589f0657 100644 +--- a/sw/source/uibase/config/viewopt.cxx ++++ b/sw/source/uibase/config/viewopt.cxx +@@ -38,6 +38,7 @@ + #include + + #include ++#include + + #ifdef DBG_UTIL + bool SwViewOption::s_bTest9 = false; //DrawingLayerNotLoading +@@ -206,6 +207,8 @@ SwViewOption::SwViewOption() : + m_bTest1 = m_bTest2 = m_bTest3 = m_bTest4 = + m_bTest5 = m_bTest6 = m_bTest7 = m_bTest8 = m_bTest10 = false; + #endif ++ if (comphelper::LibreOfficeKit::isActive()) ++ aAppBackgroundColor = COL_TRANSPARENT; + } + + SwViewOption::SwViewOption(const SwViewOption& rVOpt) +-- +2.12.0 + diff --git a/SOURCES/0170-vcl-tiled-rendering-avoid-Pixel-represents-color-val.patch b/SOURCES/0170-vcl-tiled-rendering-avoid-Pixel-represents-color-val.patch new file mode 100644 index 0000000..f3ba88e --- /dev/null +++ b/SOURCES/0170-vcl-tiled-rendering-avoid-Pixel-represents-color-val.patch @@ -0,0 +1,41 @@ +From 95c0e2be5e09f8e658295ea12f814706664c431f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 2 Oct 2015 10:31:35 +0200 +Subject: [PATCH 170/398] vcl tiled rendering: avoid 'Pixel represents color + values!' warnings + +Which happens e.g. during rendering tiles: +OutputDevice::BlendBitmapWithAlpha() produces an RGB alpha +(255,255,255), then tries to set a pixel in the 8bit alpha channel using +it, so when BitmapReadAccess::SetPixelFor_8BIT_PAL() tries to get the +color index, we try to get it from a color that is not indexed. + +Let's assume that when the color is not indexed, it's always gray, so it +doesn't matter what color we pick for the alpha mask needs. + +Change-Id: I325c1d70514fd176fdc9cc39683b444447adf07f +(cherry picked from commit 4caaa09d4da0f7bd5aa0fae3233d66bd977f185e) +--- + vcl/source/gdi/bmpacc2.cxx | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/vcl/source/gdi/bmpacc2.cxx b/vcl/source/gdi/bmpacc2.cxx +index d664c4b769fd..286ea8fca26a 100644 +--- a/vcl/source/gdi/bmpacc2.cxx ++++ b/vcl/source/gdi/bmpacc2.cxx +@@ -79,7 +79,11 @@ BitmapColor BitmapReadAccess::GetPixelFor_8BIT_PAL(ConstScanline pScanline, long + + void BitmapReadAccess::SetPixelFor_8BIT_PAL(Scanline pScanline, long nX, const BitmapColor& rBitmapColor, const ColorMask&) + { +- pScanline[ nX ] = rBitmapColor.GetIndex(); ++ if (rBitmapColor.IsIndex()) ++ pScanline[ nX ] = rBitmapColor.GetIndex(); ++ else ++ // Let's hope that the RGB color values equal, so it doesn't matter what do we pick ++ pScanline[ nX ] = rBitmapColor.GetBlueOrIndex(); + } + + BitmapColor BitmapReadAccess::GetPixelFor_8BIT_TC_MASK(ConstScanline pScanline, long nX, const ColorMask& rMask) +-- +2.12.0 + diff --git a/SOURCES/0171-desktop-handle-sal_uInt16-in-jsonToPropertyValues.patch b/SOURCES/0171-desktop-handle-sal_uInt16-in-jsonToPropertyValues.patch new file mode 100644 index 0000000..5ed99c9 --- /dev/null +++ b/SOURCES/0171-desktop-handle-sal_uInt16-in-jsonToPropertyValues.patch @@ -0,0 +1,27 @@ +From ea4aefaba7c4a6ad4e33b2a85f1802243696d293 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 5 Oct 2015 11:29:02 +0200 +Subject: [PATCH 171/398] desktop: handle sal_uInt16 in jsonToPropertyValues() + +Change-Id: Ic0059404b7ccbc922703705e7818404d4904f324 +(cherry picked from commit 44838c669b6bd02e14c394aebd9d19bcbf5ff409) +--- + desktop/source/lib/init.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 1f87146bacf8..a1356aa02ca1 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -902,6 +902,8 @@ static void jsonToPropertyValues(const char* pJSON, uno::Sequence(OString(rValue.c_str()).toUInt32()); + else + SAL_WARN("desktop.lib", "jsonToPropertyValues: unhandled type '"< +Date: Mon, 5 Oct 2015 11:29:28 +0200 +Subject: [PATCH 172/398] LOK: add CALLBACK_SEARCH_RESULT_COUNT and implement + in sw + +Change-Id: I616b3f6d2881aaa479f6498d3121540980256c15 +(cherry picked from commit 6c040ad18bd7b5a2d1d11130f4dbfd1c9d90055d) +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 4 +++- + sw/source/uibase/uiview/viewsrch.cxx | 8 +++++++- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 7038e5fc8cc2..dc3e0f94f3dc 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -155,7 +155,9 @@ typedef enum + * + * Payload is a single 0-based integer. + */ +- LOK_CALLBACK_SET_PART ++ LOK_CALLBACK_SET_PART, ++ /// Number of search results, in case something is found. ++ LOK_CALLBACK_SEARCH_RESULT_COUNT + } + LibreOfficeKitCallbackType; + +diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx +index 28fc2c920ac3..11764126e165 100644 +--- a/sw/source/uibase/uiview/viewsrch.cxx ++++ b/sw/source/uibase/uiview/viewsrch.cxx +@@ -209,7 +209,8 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + break; + case SvxSearchCmd::FIND_ALL: + { +- bool bRet = SearchAll(); ++ sal_uInt16 nFound = 0; ++ bool bRet = SearchAll(&nFound); + if( !bRet ) + { + #if HAVE_FEATURE_DESKTOP +@@ -222,6 +223,11 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + #endif + m_bFound = false; + } ++ else ++ { ++ OString aPayload = OString::number(nFound); ++ m_pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_COUNT, aPayload.getStr()); ++ } + rReq.SetReturnValue(SfxBoolItem(nSlot, bRet)); + #if HAVE_FEATURE_DESKTOP + { +-- +2.12.0 + diff --git a/SOURCES/0173-lokdocview-handle-LOK_CALLBACK_SEARCH_RESULT_COUNT.patch b/SOURCES/0173-lokdocview-handle-LOK_CALLBACK_SEARCH_RESULT_COUNT.patch new file mode 100644 index 0000000..934713c --- /dev/null +++ b/SOURCES/0173-lokdocview-handle-LOK_CALLBACK_SEARCH_RESULT_COUNT.patch @@ -0,0 +1,109 @@ +From 31ae1232bbde5ca3d74481dad1c9d70bab999c73 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 5 Oct 2015 11:30:15 +0200 +Subject: [PATCH 173/398] lokdocview: handle LOK_CALLBACK_SEARCH_RESULT_COUNT + +Change-Id: I0d1b641654e0de65169e19bb5843ea11b43a90a3 +(cherry picked from commit 22d342a82f225381057b5b8b941be8583de87a63) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 9 +++++++ + libreofficekit/source/gtk/lokdocview.cxx | 28 ++++++++++++++++++++++ + 2 files changed, 37 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 46264eb0126b..852bee584dfb 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -386,6 +386,14 @@ static void signalSearch(LOKDocView* pLOKDocView, char* /*pPayload*/, gpointer / + gtk_label_set_text(GTK_LABEL(rWindow.m_pFindbarLabel), "Search key not found"); + } + ++/// LOKDocView found some search matches -> set the search label accordingly. ++static void signalSearchResultCount(LOKDocView* pLOKDocView, char* pPayload, gpointer /*pData*/) ++{ ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); ++ std::stringstream ss; ++ ss << pPayload << " match(es)"; ++ gtk_label_set_text(GTK_LABEL(rWindow.m_pFindbarLabel), ss.str().c_str()); ++} + + static void signalPart(LOKDocView* pLOKDocView, int nPart, gpointer /*pData*/) + { +@@ -763,6 +771,7 @@ static void setupDocView(GtkWidget* pDocView) + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); ++ g_signal_connect(pDocView, "search-result-count", G_CALLBACK(signalSearchResultCount), NULL); + g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); + g_signal_connect(pDocView, "size-changed", G_CALLBACK(signalSize), NULL); + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 99476764e69d..3aa4cabeb76c 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -121,6 +121,7 @@ enum + SIZE_CHANGED, + HYPERLINK_CLICKED, + CURSOR_CHANGED, ++ SEARCH_RESULT_COUNT, + + LAST_SIGNAL + }; +@@ -221,6 +222,8 @@ callbackTypeToString (int nType) + return "LOK_CALLBACK_STATUS_INDICATOR_FINISH"; + case LOK_CALLBACK_SEARCH_NOT_FOUND: + return "LOK_CALLBACK_SEARCH_NOT_FOUND"; ++ case LOK_CALLBACK_SEARCH_RESULT_COUNT: ++ return "LOK_CALLBACK_SEARCH_RESULT_COUNT"; + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED"; + case LOK_CALLBACK_SET_PART: +@@ -363,6 +366,11 @@ searchNotFound(LOKDocView* pDocView, const std::string& rString) + g_signal_emit(pDocView, doc_view_signals[SEARCH_NOT_FOUND], 0, rString.c_str()); + } + ++static void searchResultCount(LOKDocView* pDocView, const std::string& rString) ++{ ++ g_signal_emit(pDocView, doc_view_signals[SEARCH_RESULT_COUNT], 0, rString.c_str()); ++} ++ + static void + setPart(LOKDocView* pDocView, const std::string& rString) + { +@@ -645,6 +653,11 @@ callback (gpointer pData) + setPart(pDocView, pCallback->m_aPayload); + } + break; ++ case LOK_CALLBACK_SEARCH_RESULT_COUNT: ++ { ++ searchResultCount(pDocView, pCallback->m_aPayload); ++ } ++ break; + default: + g_assert(false); + break; +@@ -1841,6 +1854,21 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_NONE, 4, + G_TYPE_INT, G_TYPE_INT, + G_TYPE_INT, G_TYPE_INT); ++ /** ++ * LOKDocView::search-result-count: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aCommand: number of matches. ++ */ ++ doc_view_signals[SEARCH_RESULT_COUNT] = ++ g_signal_new("search-result_count", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, NULL, ++ g_cclosure_marshal_VOID__STRING, ++ G_TYPE_NONE, 1, ++ G_TYPE_STRING); ++ + } + + SAL_DLLPUBLIC_EXPORT GtkWidget* +-- +2.12.0 + diff --git a/SOURCES/0174-gtktiledviewer-make-it-possible-to-trigger-SearchIte.patch b/SOURCES/0174-gtktiledviewer-make-it-possible-to-trigger-SearchIte.patch new file mode 100644 index 0000000..e9da37d --- /dev/null +++ b/SOURCES/0174-gtktiledviewer-make-it-possible-to-trigger-SearchIte.patch @@ -0,0 +1,76 @@ +From 34aa1adc51adf0da82774b0da1194870a0d90241 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 5 Oct 2015 11:39:11 +0200 +Subject: [PATCH 174/398] gtktiledviewer: make it possible to trigger + SearchItem.Command + +Change-Id: I210da07802bae1f2f2948976bc0faf90e93152b4 +(cherry picked from commit aa3f607f80a2269ca2e1f8a5805d2e0b4cd36d7e) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 852bee584dfb..ed97a6743b38 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -53,6 +53,7 @@ public: + GtkWidget* m_pFindbar; + GtkWidget* m_pFindbarEntry; + GtkWidget* m_pFindbarLabel; ++ bool m_bFindAll; + + TiledWindow() + : m_pDocView(0), +@@ -70,7 +71,8 @@ public: + m_bPartSelectorBroadcast(true), + m_pFindbar(0), + m_pFindbarEntry(0), +- m_pFindbarLabel(0) ++ m_pFindbarLabel(0), ++ m_bFindAll(false) + { + } + }; +@@ -178,6 +180,13 @@ static void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/) + lok_doc_view_set_edit(pLOKDocView, bActive); + } + ++/// Toggles if search should find all results or only the first one. ++static void toggleFindAll(GtkWidget* pButton, gpointer /*pItem*/) ++{ ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ rWindow.m_bFindAll = !rWindow.m_bFindAll; ++} ++ + /// Toggle the visibility of the findbar. + static void toggleFindbar(GtkWidget* pButton, gpointer /*pItem*/) + { +@@ -284,6 +293,12 @@ static void doSearch(GtkWidget* pButton, bool bBackwards) + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/value", '/'), pText); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards); ++ if (rWindow.m_bFindAll) ++ { ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/type", '/'), "unsigned short"); ++ // SvxSearchCmd::FIND_ALL ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/value", '/'), "1"); ++ } + + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + GdkRectangle aArea; +@@ -729,6 +744,11 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarPrev, -1); + g_signal_connect(G_OBJECT(pFindbarPrev), "clicked", G_CALLBACK(signalSearchPrev), NULL); + ++ GtkToolItem* pFindAll = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_label(GTK_TOOL_BUTTON(pFindAll), "Highlight All"); ++ gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindAll, -1); ++ g_signal_connect(G_OBJECT(pFindAll), "toggled", G_CALLBACK(toggleFindAll), NULL); ++ + GtkToolItem* pFindbarLabelContainer = gtk_tool_item_new(); + rWindow.m_pFindbarLabel = gtk_label_new(""); + gtk_container_add(GTK_CONTAINER(pFindbarLabelContainer), rWindow.m_pFindbarLabel); +-- +2.12.0 + diff --git a/SOURCES/0175-LOK-added-the-button-type-and-key-modifier-to-postMo.patch b/SOURCES/0175-LOK-added-the-button-type-and-key-modifier-to-postMo.patch new file mode 100644 index 0000000..12b8aec --- /dev/null +++ b/SOURCES/0175-LOK-added-the-button-type-and-key-modifier-to-postMo.patch @@ -0,0 +1,397 @@ +From 44f959673e66d68d9933074157a310f2908964fe Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Sun, 4 Oct 2015 19:40:13 +0300 +Subject: [PATCH 175/398] LOK: added the button type and key modifier to + postMouseEvent() + +To get a better functionality we need to know the button type (left, +right, middle). We also need the key modifier (ctrl, alt, shift) for +actions such as ctrl+click (to open a link) or shift+click to select + +Change-Id: Iaccb93b276f8a6870dd41cc5132dbb85d2bbf71b +(cherry picked from commit c90c08a65c480a1012182979d5e9218f17a2ba2e) +--- + desktop/source/lib/init.cxx | 8 ++-- + include/LibreOfficeKit/LibreOfficeKit.h | 4 +- + include/LibreOfficeKit/LibreOfficeKit.hxx | 4 +- + include/vcl/ITiledRenderable.hxx | 2 +- + libreofficekit/Library_libreofficekitgtk.mk | 4 ++ + libreofficekit/source/gtk/lokdocview.cxx | 57 ++++++++++++++++++++++++++++- + libreofficekit/source/gtk/tilebuffer.hxx | 4 ++ + sc/inc/docuno.hxx | 3 +- + sc/source/ui/unoobj/docuno.cxx | 5 ++- + sd/source/ui/inc/unomodel.hxx | 3 +- + sd/source/ui/unoidl/unomodel.cxx | 5 ++- + sw/inc/unotxdoc.hxx | 3 +- + sw/source/uibase/uno/unotxdoc.cxx | 4 +- + 13 files changed, 88 insertions(+), 18 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index a1356aa02ca1..29e8e0d12faa 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -229,7 +229,9 @@ static void doc_postMouseEvent (LibreOfficeKitDocument* pThis, + int nType, + int nX, + int nY, +- int nCount); ++ int nCount, ++ int nButtons, ++ int nModifier); + static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, + const char* pCommand, + const char* pArguments); +@@ -924,7 +926,7 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* /*pThis*/, const char* pC + } + } + +-static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, int nY, int nCount) ++static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, int nY, int nCount, int nButtons, int nModifier) + { + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) +@@ -933,7 +935,7 @@ static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, + return; + } + +- pDoc->postMouseEvent(nType, nX, nY, nCount); ++ pDoc->postMouseEvent(nType, nX, nY, nCount, nButtons, nModifier); + } + + static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY) +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index d83dd49f32b5..83dcc9803d8a 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -137,7 +137,9 @@ struct _LibreOfficeKitDocumentClass + int nType, + int nX, + int nY, +- int nCount); ++ int nCount, ++ int nButtons, ++ int nModifier); + + /// @see lok::Document::postUnoCommand + void (*postUnoCommand) (LibreOfficeKitDocument* pThis, +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index cd12ad64f245..e9167c510110 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -192,9 +192,9 @@ public: + * @param nY vertical position in document coordinates + * @param nCount number of clicks: 1 for single click, 2 for double click + */ +- inline void postMouseEvent(int nType, int nX, int nY, int nCount) ++ inline void postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) + { +- mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY, nCount); ++ mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY, nCount, nButtons, nModifier); + } + + /** +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index fd336f603296..c294d20dc9cf 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -112,7 +112,7 @@ public: + * + * @see lok::Document::postMouseEvent(). + */ +- virtual void postMouseEvent(int nType, int nX, int nY, int nCount) = 0; ++ virtual void postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) = 0; + + /** + * Sets the start or end of a text selection. +diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk +index 71a77e9e36a3..7d25abf944b1 100644 +--- a/libreofficekit/Library_libreofficekitgtk.mk ++++ b/libreofficekit/Library_libreofficekitgtk.mk +@@ -16,6 +16,10 @@ $(eval $(call gb_Library_add_exception_objects,libreofficekitgtk,\ + libreofficekit/source/gtk/tilebuffer \ + )) + ++$(eval $(call gb_Library_use_externals,libreofficekitgtk,\ ++ boost_headers \ ++)) ++ + $(eval $(call gb_Library_add_cxxflags,libreofficekitgtk,\ + $$(GTK3_CFLAGS) \ + )) +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 3aa4cabeb76c..0bd735088586 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #include "tilebuffer.hxx" + +@@ -66,6 +67,10 @@ struct _LOKDocViewPrivate + guint32 m_nLastButtonPressTime; + /// Time of the last button release. + guint32 m_nLastButtonReleaseTime; ++ /// Last pressed button (left, right, middle) ++ guint32 m_nLastButtonPressed; ++ /// Key modifier (ctrl, atl, shift) ++ guint32 m_nKeyModifier; + /// Rectangles of the current text selection. + std::vector m_aTextSelectionRectangles; + /// Position and size of the selection start (as if there would be a cursor caret there). +@@ -267,6 +272,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + return FALSE; + } + ++ priv->m_nKeyModifier = 0; + switch (pEvent->keyval) + { + case GDK_KEY_BackSpace: +@@ -296,6 +302,21 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + case GDK_KEY_Right: + nKeyCode = com::sun::star::awt::Key::RIGHT; + break; ++ case GDK_KEY_Shift_L: ++ case GDK_KEY_Shift_R: ++ if (pEvent->type == GDK_KEY_PRESS) ++ priv->m_nKeyModifier |= KEY_SHIFT; ++ break; ++ case GDK_KEY_Control_L: ++ case GDK_KEY_Control_R: ++ if (pEvent->type == GDK_KEY_PRESS) ++ priv->m_nKeyModifier |= KEY_MOD1; ++ break; ++ case GDK_KEY_Alt_L: ++ case GDK_KEY_Alt_R: ++ if (pEvent->type == GDK_KEY_PRESS) ++ priv->m_nKeyModifier |= KEY_MOD2; ++ break; + default: + if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26) + nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_KEY_F1); +@@ -309,7 +330,6 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + if (pEvent->state & GDK_SHIFT_MASK) + nKeyCode |= KEY_SHIFT; + +- + if (pEvent->type == GDK_KEY_RELEASE) + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +@@ -1060,6 +1080,20 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); + pLOEvent->m_nPostMouseEventCount = nCount; ++ switch (pEvent->button) ++ { ++ case 1: ++ pLOEvent->m_nPostMouseEventButton = MOUSE_LEFT; ++ break; ++ case 2: ++ pLOEvent->m_nPostMouseEventButton = MOUSE_MIDDLE; ++ break; ++ case 3: ++ pLOEvent->m_nPostMouseEventButton = MOUSE_RIGHT; ++ break; ++ } ++ pLOEvent->m_nPostMouseEventModifier = priv->m_nKeyModifier; ++ priv->m_nLastButtonPressed = pLOEvent->m_nPostMouseEventButton; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); +@@ -1078,6 +1112,20 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); + pLOEvent->m_nPostMouseEventCount = nCount; ++ switch (pEvent->button) ++ { ++ case 1: ++ pLOEvent->m_nPostMouseEventButton = MOUSE_LEFT; ++ break; ++ case 2: ++ pLOEvent->m_nPostMouseEventButton = MOUSE_MIDDLE; ++ break; ++ case 3: ++ pLOEvent->m_nPostMouseEventButton = MOUSE_RIGHT; ++ break; ++ } ++ pLOEvent->m_nPostMouseEventModifier = priv->m_nKeyModifier; ++ priv->m_nLastButtonPressed = pLOEvent->m_nPostMouseEventButton; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); +@@ -1182,6 +1230,9 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); + pLOEvent->m_nPostMouseEventY = pixelToTwip(pEvent->y, priv->m_fZoom); + pLOEvent->m_nPostMouseEventCount = 1; ++ pLOEvent->m_nPostMouseEventButton = priv->m_nLastButtonPressed; ++ pLOEvent->m_nPostMouseEventModifier = priv->m_nKeyModifier; ++ + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); +@@ -1218,7 +1269,9 @@ postMouseEventInThread(gpointer data) + pLOEvent->m_nPostMouseEventType, + pLOEvent->m_nPostMouseEventX, + pLOEvent->m_nPostMouseEventY, +- pLOEvent->m_nPostMouseEventCount); ++ pLOEvent->m_nPostMouseEventCount, ++ pLOEvent->m_nPostMouseEventButton, ++ pLOEvent->m_nPostMouseEventModifier); + } + + static void +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index fdcdd15eddd7..34b9001e8bc5 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -204,6 +204,8 @@ struct LOEvent + int m_nPostMouseEventX; + int m_nPostMouseEventY; + int m_nPostMouseEventCount; ++ int m_nPostMouseEventButton; ++ int m_nPostMouseEventModifier; + ///@} + + /// @name setGraphicSelection parameters +@@ -232,6 +234,8 @@ struct LOEvent + , m_nPostMouseEventX(0) + , m_nPostMouseEventY(0) + , m_nPostMouseEventCount(0) ++ , m_nPostMouseEventButton(0) ++ , m_nPostMouseEventModifier(0) + , m_nSetGraphicSelectionType(0) + , m_nSetGraphicSelectionX(0) + , m_nSetGraphicSelectionY(0) +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index cd6888598f69..cc132278bdf8 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -54,6 +54,7 @@ + #include + #include + #include ++#include + #include + #include "drwlayer.hxx" + +@@ -401,7 +402,7 @@ public: + virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) SAL_OVERRIDE; + + /// @see vcl::ITiledRenderable::postMouseEvent(). +- virtual void postMouseEvent(int nType, int nX, int nY, int nCount) SAL_OVERRIDE; ++ virtual void postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons = MOUSE_LEFT, int nModifier = 0) SAL_OVERRIDE; + + /// @see vcl::ITiledRenderable::setTextSelection(). + virtual void setTextSelection(int nType, int nX, int nY) SAL_OVERRIDE; +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index 1a59f887b7d7..958495f7ea7b 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -591,7 +591,7 @@ void ScModelObj::postKeyEvent(int nType, int nCharCode, int nKeyCode) + } + } + +-void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount) ++void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) + { + SolarMutexGuard aGuard; + +@@ -607,7 +607,8 @@ void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount) + pViewData->SetZoom(Fraction(1, 1), Fraction(1, 1), true); + + // Calc operates in pixels... +- MouseEvent aEvent(Point(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY()), nCount, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT); ++ MouseEvent aEvent(Point(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY()), nCount, ++ MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); + + switch (nType) + { +diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx +index 009fb672cf27..4d7314875f0b 100644 +--- a/sd/source/ui/inc/unomodel.hxx ++++ b/sd/source/ui/inc/unomodel.hxx +@@ -45,6 +45,7 @@ + #include + #include + ++#include + #include + + #include +@@ -248,7 +249,7 @@ public: + /// @see vcl::ITiledRenderable::postKeyEvent(). + virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::postMouseEvent(). +- virtual void postMouseEvent(int nType, int nX, int nY, int nCount) SAL_OVERRIDE; ++ virtual void postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons = MOUSE_LEFT, int nModifier = 0) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::setTextSelection(). + virtual void setTextSelection(int nType, int nX, int nY) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::getTextSelection(). +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 0e88a099e081..6ae01a28efac 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2428,7 +2428,7 @@ void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode) + } + } + +-void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount) ++void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) + { + SolarMutexGuard aGuard; + +@@ -2436,7 +2436,8 @@ void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount) + if (!pViewShell) + return; + +- MouseEvent aEvent(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)), nCount, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT); ++ MouseEvent aEvent(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)), nCount, ++ MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); + + switch (nType) + { +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index 311147eeaaea..346cab63ca02 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -66,6 +66,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -422,7 +423,7 @@ public: + /// @see vcl::ITiledRenderable::postKeyEvent(). + virtual void postKeyEvent(int nType, int nCharCode, int nKeyCode) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::postMouseEvent(). +- virtual void postMouseEvent(int nType, int nX, int nY, int nCount) SAL_OVERRIDE; ++ virtual void postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons = MOUSE_LEFT, int nModifier = 0) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::setTextSelection(). + virtual void setTextSelection(int nType, int nX, int nY) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::getTextSelection(). +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 26ab19f170b9..fc1c6f411b74 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3282,12 +3282,12 @@ void SwXTextDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode) + } + } + +-void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount) ++void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) + { + SolarMutexGuard aGuard; + + SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin(); +- MouseEvent aEvent(Point(nX, nY), nCount, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT); ++ MouseEvent aEvent(Point(nX, nY), nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); + + switch (nType) + { +-- +2.12.0 + diff --git a/SOURCES/0176-CppunitTest_sw_tiledrendering-testcase-for-LOK_CALLB.patch b/SOURCES/0176-CppunitTest_sw_tiledrendering-testcase-for-LOK_CALLB.patch new file mode 100644 index 0000000..985caf6 --- /dev/null +++ b/SOURCES/0176-CppunitTest_sw_tiledrendering-testcase-for-LOK_CALLB.patch @@ -0,0 +1,96 @@ +From 1d76b4e38c93388488dbd7f32912f6f40e081721 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 5 Oct 2015 15:34:28 +0200 +Subject: [PATCH 176/398] CppunitTest_sw_tiledrendering: testcase for + LOK_CALLBACK_SEARCH_RESULT_COUNT + +Change-Id: I9f517bc2f3dfca9a2dc17a229f54c47b7790a355 +(cherry picked from commit b4e75e8f52c17d02a65022303fb6a0e4f1d97592) +--- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 32 +++++++++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index e7ab14942f79..c836f4bc5eab 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -42,6 +43,7 @@ public: + void testSearchTextFrame(); + void testSearchTextFrameWrapAround(); + void testDocumentSizeChanged(); ++ void testSearchAll(); + + CPPUNIT_TEST_SUITE(SwTiledRenderingTest); + CPPUNIT_TEST(testRegisterCallback); +@@ -56,6 +58,7 @@ public: + CPPUNIT_TEST(testSearchTextFrame); + CPPUNIT_TEST(testSearchTextFrameWrapAround); + CPPUNIT_TEST(testDocumentSizeChanged); ++ CPPUNIT_TEST(testSearchAll); + CPPUNIT_TEST_SUITE_END(); + + private: +@@ -66,10 +69,12 @@ private: + Size m_aDocumentSize; + OString m_aTextSelection; + bool m_bFound; ++ sal_Int32 m_nSearchResultCount; + }; + + SwTiledRenderingTest::SwTiledRenderingTest() +- : m_bFound(true) ++ : m_bFound(true), ++ m_nSearchResultCount(0) + { + } + +@@ -125,6 +130,11 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + m_bFound = false; + } + break; ++ case LOK_CALLBACK_SEARCH_RESULT_COUNT: ++ { ++ m_nSearchResultCount = OString(pPayload).toInt32(); ++ } ++ break; + } + } + +@@ -438,6 +448,26 @@ void SwTiledRenderingTest::testDocumentSizeChanged() + #endif + } + ++void SwTiledRenderingTest::testSearchAll() ++{ ++#if !defined(WNT) && !defined(MACOSX) ++ comphelper::LibreOfficeKit::setActive(); ++ ++ SwXTextDocument* pXTextDocument = createDoc("search.odt"); ++ pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this); ++ uno::Sequence aPropertyValues(comphelper::InitPropertySequence( ++ { ++ {"SearchItem.SearchString", uno::makeAny(OUString("shape"))}, ++ {"SearchItem.Backward", uno::makeAny(false)}, ++ {"SearchItem.Command", uno::makeAny(static_cast(SvxSearchCmd::FIND_ALL))}, ++ })); ++ comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); ++ // This was 0; should be 2 results in the body text. ++ CPPUNIT_ASSERT_EQUAL(static_cast(2), m_nSearchResultCount); ++ ++ comphelper::LibreOfficeKit::setActive(false); ++#endif ++} + CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +-- +2.12.0 + diff --git a/SOURCES/0177-LOK-add-the-search-phrase-to-the-search-result-count.patch b/SOURCES/0177-LOK-add-the-search-phrase-to-the-search-result-count.patch new file mode 100644 index 0000000..1c010fe --- /dev/null +++ b/SOURCES/0177-LOK-add-the-search-phrase-to-the-search-result-count.patch @@ -0,0 +1,94 @@ +From ec61694abf3a2fb70ce295ba87e18e196b6bbc3a Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Mon, 5 Oct 2015 17:07:06 +0300 +Subject: [PATCH 177/398] LOK: add the search phrase to the search result count + callback + +We need this to notify the user for which search phrase no results were +found + +Change-Id: I8cc7ab235b9129dfdcb022145456180ff7e4ca92 +(cherry picked from commit c30defcf8e34daec6ea0455d772fe296cc26ecc9) +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 6 +++++- + libreofficekit/source/gtk/lokdocview.cxx | 10 ++++++++++ + sw/qa/extras/tiledrendering/tiledrendering.cxx | 4 +++- + sw/source/uibase/uiview/viewsrch.cxx | 2 +- + 4 files changed, 19 insertions(+), 3 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index dc3e0f94f3dc..97c089ffef50 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -156,7 +156,11 @@ typedef enum + * Payload is a single 0-based integer. + */ + LOK_CALLBACK_SET_PART, +- /// Number of search results, in case something is found. ++ ++ /** ++ * Number of search results followed by the original searched phrase. ++ * count;phrase ++ */ + LOK_CALLBACK_SEARCH_RESULT_COUNT + } + LibreOfficeKitCallbackType; +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 0bd735088586..fa0386ba77f8 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -658,6 +658,16 @@ callback (gpointer pData) + searchNotFound(pDocView, pCallback->m_aPayload); + } + break; ++ case LOK_CALLBACK_SEARCH_RESULT_COUNT: ++ { ++ size_t nPos = pCallback->m_aPayload.find_first_of(";"); ++ int nSearchResultCount = std::stoi(pCallback->m_aPayload.substr(0, nPos)); ++ if (nSearchResultCount == 0) ++ { ++ searchNotFound(pDocView, pCallback->m_aPayload.substr(nPos + 1)); ++ } ++ } ++ break; + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + { + payloadToSize(pCallback->m_aPayload.c_str(), priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index c836f4bc5eab..bcc328e366a3 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + static const char* DATA_DIRECTORY = "/sw/qa/extras/tiledrendering/data/"; + +@@ -132,7 +133,8 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + break; + case LOK_CALLBACK_SEARCH_RESULT_COUNT: + { +- m_nSearchResultCount = OString(pPayload).toInt32(); ++ std::string aStrPayload(pPayload); ++ m_nSearchResultCount = std::stoi(aStrPayload.substr(0, aStrPayload.find_first_of(";"))); + } + break; + } +diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx +index 11764126e165..3ccc852065fb 100644 +--- a/sw/source/uibase/uiview/viewsrch.cxx ++++ b/sw/source/uibase/uiview/viewsrch.cxx +@@ -225,7 +225,7 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + } + else + { +- OString aPayload = OString::number(nFound); ++ OString aPayload = OString::number(nFound) + ";" + m_pSrchItem->GetSearchString().toUtf8(); + m_pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_COUNT, aPayload.getStr()); + } + rReq.SetReturnValue(SfxBoolItem(nSlot, bRet)); +-- +2.12.0 + diff --git a/SOURCES/0178-LOK-fixed-duplicated-switch-case-values.patch b/SOURCES/0178-LOK-fixed-duplicated-switch-case-values.patch new file mode 100644 index 0000000..91aef91 --- /dev/null +++ b/SOURCES/0178-LOK-fixed-duplicated-switch-case-values.patch @@ -0,0 +1,42 @@ +From f14e917df2cd85f90337a2fe7cae085390e4aa34 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Mon, 5 Oct 2015 18:07:28 +0300 +Subject: [PATCH 178/398] LOK: fixed duplicated switch case values + +(cherry picked from commit a6ef5718475ba35b52d9de474741b640316502eb) +--- + libreofficekit/source/gtk/lokdocview.cxx | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index fa0386ba77f8..5d810d801106 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -661,11 +661,7 @@ callback (gpointer pData) + case LOK_CALLBACK_SEARCH_RESULT_COUNT: + { + size_t nPos = pCallback->m_aPayload.find_first_of(";"); +- int nSearchResultCount = std::stoi(pCallback->m_aPayload.substr(0, nPos)); +- if (nSearchResultCount == 0) +- { +- searchNotFound(pDocView, pCallback->m_aPayload.substr(nPos + 1)); +- } ++ searchResultCount(pDocView, pCallback->m_aPayload.substr(0, nPos)); + } + break; + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: +@@ -683,11 +679,6 @@ callback (gpointer pData) + setPart(pDocView, pCallback->m_aPayload); + } + break; +- case LOK_CALLBACK_SEARCH_RESULT_COUNT: +- { +- searchResultCount(pDocView, pCallback->m_aPayload); +- } +- break; + default: + g_assert(false); + break; +-- +2.12.0 + diff --git a/SOURCES/0179-LOK-add-CALLBACK_SEARCH_RESULT_SELECTION-and-impleme.patch b/SOURCES/0179-LOK-add-CALLBACK_SEARCH_RESULT_SELECTION-and-impleme.patch new file mode 100644 index 0000000..d3d372c --- /dev/null +++ b/SOURCES/0179-LOK-add-CALLBACK_SEARCH_RESULT_SELECTION-and-impleme.patch @@ -0,0 +1,141 @@ +From 4a8fa9d37030d92b523707602e938e6604412727 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 09:21:38 +0200 +Subject: [PATCH 179/398] LOK: add CALLBACK_SEARCH_RESULT_SELECTION and + implement it in sw + +(cherry picked from commit 94752d5970be7ce22e053f9cd83bd59711446a0a) + +Change-Id: I4c2a5418101976e1cb38c0fa71dbd66fc883f905 +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 21 +++++++++- + sw/source/uibase/uiview/viewsrch.cxx | 57 +++++++++++++++++++++++++++- + 2 files changed, 76 insertions(+), 2 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 97c089ffef50..b87f69a39989 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -161,7 +161,26 @@ typedef enum + * Number of search results followed by the original searched phrase. + * count;phrase + */ +- LOK_CALLBACK_SEARCH_RESULT_COUNT ++ LOK_CALLBACK_SEARCH_RESULT_COUNT, ++ ++ /** ++ * Selection rectangles of the search result when find all is performed. ++ * ++ * Payload format example, in case of two matches: ++ * ++ * { ++ * "searchString": "...", ++ * "searchResultSelection": [ ++ * "...", ++ * "..." ++ * ] ++ * } ++ * ++ * - searchString is the search query ++ * - searchResultSelection is an array of rectangle list, in ++ * LOK_CALLBACK_TEXT_SELECTION format. ++ */ ++ LOK_CALLBACK_SEARCH_RESULT_SELECTION + } + LibreOfficeKitCallbackType; + +diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx +index 3ccc852065fb..570fadeb561a 100644 +--- a/sw/source/uibase/uiview/viewsrch.cxx ++++ b/sw/source/uibase/uiview/viewsrch.cxx +@@ -22,6 +22,7 @@ + #include + + #include ++#include + + #include + +@@ -58,6 +59,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -85,6 +87,21 @@ static vcl::Window* GetParentWindow( SvxSearchDialog* pSrchDlg ) + return pSrchDlg && pSrchDlg->IsVisible() ? pSrchDlg : 0; + } + ++/// Adds rMatches using rKey as a key to the rTree tree. ++static void lcl_addContainerToJson(boost::property_tree::ptree& rTree, const OString& rKey, const std::vector& rMatches) ++{ ++ boost::property_tree::ptree aChildren; ++ ++ for (const OString& rMatch : rMatches) ++ { ++ boost::property_tree::ptree aChild; ++ aChild.put("", rMatch.getStr()); ++ aChildren.push_back(std::make_pair("", aChild)); ++ } ++ ++ rTree.add_child(rKey.getStr(), aChildren); ++} ++ + void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + { + const SfxItemSet* pArgs = rReq.GetArgs(); +@@ -223,10 +240,48 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + #endif + m_bFound = false; + } +- else ++ else if (comphelper::LibreOfficeKit::isActive()) + { + OString aPayload = OString::number(nFound) + ";" + m_pSrchItem->GetSearchString().toUtf8(); + m_pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_COUNT, aPayload.getStr()); ++ ++ // Emit a callback also about the selection rectangles, grouped by matches. ++ if (SwPaM* pPaM = m_pWrtShell->GetCrsr()) ++ { ++ std::vector aMatches; ++ for (SwPaM& rPaM : pPaM->GetRingContainer()) ++ { ++ if (SwShellCrsr* pShellCrsr = dynamic_cast(&rPaM)) ++ { ++ std::vector aSelectionRectangles; ++ pShellCrsr->SwSelPaintRects::Show(&aSelectionRectangles); ++ std::stringstream ss; ++ bool bFirst = true; ++ for (size_t i = 0; i < aSelectionRectangles.size(); ++i) ++ { ++ const OString& rSelectionRectangle = aSelectionRectangles[i]; ++ if (rSelectionRectangle.isEmpty()) ++ continue; ++ if (bFirst) ++ bFirst = false; ++ else ++ ss << "; "; ++ ss << rSelectionRectangle.getStr(); ++ } ++ OString sRect = ss.str().c_str(); ++ aMatches.push_back(sRect); ++ } ++ } ++ boost::property_tree::ptree aTree; ++ aTree.put("searchString", m_pSrchItem->GetSearchString().toUtf8().getStr()); ++ lcl_addContainerToJson(aTree, "searchResultSelection", aMatches); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ aPayload = aStream.str().c_str(); ++ ++ m_pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); ++ } + } + rReq.SetReturnValue(SfxBoolItem(nSlot, bRet)); + #if HAVE_FEATURE_DESKTOP +-- +2.12.0 + diff --git a/SOURCES/0180-gtktiledviewer-recognize-LOK_CALLBACK_SEARCH_RESULT_.patch b/SOURCES/0180-gtktiledviewer-recognize-LOK_CALLBACK_SEARCH_RESULT_.patch new file mode 100644 index 0000000..c9e0f0c --- /dev/null +++ b/SOURCES/0180-gtktiledviewer-recognize-LOK_CALLBACK_SEARCH_RESULT_.patch @@ -0,0 +1,39 @@ +From 5e4796f308ea349d644458caadead085d2546443 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 09:21:54 +0200 +Subject: [PATCH 180/398] gtktiledviewer: recognize + LOK_CALLBACK_SEARCH_RESULT_SELECTION + +Change-Id: Ib932ee36e41afcb53d15a6362b998cc673d474f2 +(cherry picked from commit 2b6060d6c58b95153c907585d89cad815bc9b1ae) +--- + libreofficekit/source/gtk/lokdocview.cxx | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 5d810d801106..220e488a53a4 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -233,6 +233,8 @@ callbackTypeToString (int nType) + return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED"; + case LOK_CALLBACK_SET_PART: + return "LOK_CALLBACK_SET_PART"; ++ case LOK_CALLBACK_SEARCH_RESULT_SELECTION: ++ return "LOK_CALLBACK_SEARCH_RESULT_SELECTION"; + } + return 0; + } +@@ -679,6 +681,10 @@ callback (gpointer pData) + setPart(pDocView, pCallback->m_aPayload); + } + break; ++ case LOK_CALLBACK_SEARCH_RESULT_SELECTION: ++ { ++ } ++ break; + default: + g_assert(false); + break; +-- +2.12.0 + diff --git a/SOURCES/0181-CppunitTest_sw_tiledrendering-CALLBACK_SEARCH_RESULT.patch b/SOURCES/0181-CppunitTest_sw_tiledrendering-CALLBACK_SEARCH_RESULT.patch new file mode 100644 index 0000000..df1aa7b --- /dev/null +++ b/SOURCES/0181-CppunitTest_sw_tiledrendering-CALLBACK_SEARCH_RESULT.patch @@ -0,0 +1,71 @@ +From 28fbfa4f660be2c4698cdaae963e4e21d172e56d Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 10:18:18 +0200 +Subject: [PATCH 181/398] CppunitTest_sw_tiledrendering: + CALLBACK_SEARCH_RESULT_SELECTION testcase + +Change-Id: I66a8d73581641c71f2dce2d1992070f3ccce08c2 +(cherry picked from commit a7b86140d74039995bd4d312790244c1e2d4b501) +--- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index bcc328e366a3..2fd27dd4f8ff 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -7,6 +7,9 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + ++#include ++#include ++ + #include + #include + #include +@@ -23,7 +26,6 @@ + #include + #include + #include +-#include + + static const char* DATA_DIRECTORY = "/sw/qa/extras/tiledrendering/data/"; + +@@ -71,6 +73,7 @@ private: + OString m_aTextSelection; + bool m_bFound; + sal_Int32 m_nSearchResultCount; ++ std::vector m_aSearchResultSelection; + }; + + SwTiledRenderingTest::SwTiledRenderingTest() +@@ -137,6 +140,16 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + m_nSearchResultCount = std::stoi(aStrPayload.substr(0, aStrPayload.find_first_of(";"))); + } + break; ++ case LOK_CALLBACK_SEARCH_RESULT_SELECTION: ++ { ++ m_aSearchResultSelection.clear(); ++ boost::property_tree::ptree aTree; ++ std::stringstream aStream(pPayload); ++ boost::property_tree::read_json(aStream, aTree); ++ for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("searchResultSelection")) ++ m_aSearchResultSelection.push_back(rValue.second.data().c_str()); ++ } ++ break; + } + } + +@@ -466,6 +479,8 @@ void SwTiledRenderingTest::testSearchAll() + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + // This was 0; should be 2 results in the body text. + CPPUNIT_ASSERT_EQUAL(static_cast(2), m_nSearchResultCount); ++ // Make sure that we get exactly as many rectangle lists as matches. ++ CPPUNIT_ASSERT_EQUAL(static_cast(2), m_aSearchResultSelection.size()); + + comphelper::LibreOfficeKit::setActive(false); + #endif +-- +2.12.0 + diff --git a/SOURCES/0182-lokdocview-log-paintTile-arguments.patch b/SOURCES/0182-lokdocview-log-paintTile-arguments.patch new file mode 100644 index 0000000..a7e03c4 --- /dev/null +++ b/SOURCES/0182-lokdocview-log-paintTile-arguments.patch @@ -0,0 +1,72 @@ +From 74d4aa83ab2a936b4210dc249531240087e2fc84 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 10:47:03 +0200 +Subject: [PATCH 182/398] lokdocview: log paintTile() arguments + +Change-Id: I8015c8030c1c7f53ae1de053fe268a33464834ad +(cherry picked from commit 23ac7f2fb57c338fa608cbc28ac39d140026e3c3) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 1 - + libreofficekit/source/gtk/lokdocview.cxx | 14 +++++++------- + libreofficekit/source/gtk/tilebuffer.cxx | 1 - + 3 files changed, 7 insertions(+), 9 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index ed97a6743b38..3d0b0deba323 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -371,7 +371,6 @@ static void signalCommand(LOKDocView* pLOKDocView, char* pPayload, gpointer /*pD + { + std::string aKey = aPayload.substr(0, nPosition); + std::string aValue = aPayload.substr(nPosition + 1); +- g_info("signalCommand: '%s' is '%s'", aKey.c_str(), aValue.c_str()); + + if (rWindow.m_aCommandNameToolItems.find(aKey) != rWindow.m_aCommandNameToolItems.end()) + { +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 220e488a53a4..4026d958b8ed 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1395,7 +1395,13 @@ paintTileInThread (gpointer data) + aTileRectangle.y = pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) * pLOEvent->m_nPaintTileX; + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); +- g_test_timer_start(); ++ std::stringstream ss; ++ ss << "lok::Document::paintTile(" << static_cast(pBuffer) << ", " ++ << nTileSizePixels << ", " << nTileSizePixels << ", " ++ << aTileRectangle.x << ", " << aTileRectangle.y << ", " ++ << pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) << ", " ++ << pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) << ")"; ++ g_info(ss.str().c_str()); + priv->m_pDocument->pClass->paintTile(priv->m_pDocument, + pBuffer, + nTileSizePixels, nTileSizePixels, +@@ -1403,12 +1409,6 @@ paintTileInThread (gpointer data) + pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom), + pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom)); + +- double elapsedTime = g_test_timer_elapsed(); +- g_info ("Rendered (%d, %d) in %f seconds", +- pLOEvent->m_nPaintTileX, +- pLOEvent->m_nPaintTileY, +- elapsedTime); +- + //create a mapping for it + buffer.m_mTiles[index].setPixbuf(pPixBuf); + buffer.m_mTiles[index].valid = true; +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 687ef44d6468..0e81bc33f262 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -64,7 +64,6 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, + GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; +- g_info("Setting tile invalid (%d, %d)", x, y); + if (m_mTiles.find(index) != m_mTiles.end()) + { + m_mTiles[index].valid = false; +-- +2.12.0 + diff --git a/SOURCES/0183-sw-outline-SwViewOption-SetOnlineSpell.patch b/SOURCES/0183-sw-outline-SwViewOption-SetOnlineSpell.patch new file mode 100644 index 0000000..1e6d441 --- /dev/null +++ b/SOURCES/0183-sw-outline-SwViewOption-SetOnlineSpell.patch @@ -0,0 +1,45 @@ +From 447fa6b3fb93262d548441d4778fc5d429b5aef3 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 11:13:54 +0200 +Subject: [PATCH 183/398] sw: outline SwViewOption::SetOnlineSpell() + +Change-Id: Ic81b039e9a1b592ca52ab684ddb45ee44c7714df +(cherry picked from commit 0cf63ba224cb01377e3e6da68b0e72a3ed7e30af) +--- + sw/inc/viewopt.hxx | 3 +-- + sw/source/uibase/config/viewopt.cxx | 5 +++++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/sw/inc/viewopt.hxx b/sw/inc/viewopt.hxx +index 64c1e269f2f6..dee2189a6795 100644 +--- a/sw/inc/viewopt.hxx ++++ b/sw/inc/viewopt.hxx +@@ -300,8 +300,7 @@ public: + + inline bool IsOnlineSpell() const + { return !bReadonly && (nCoreOptions & VIEWOPT_1_ONLINESPELL) != 0; } +- inline void SetOnlineSpell( bool b ) +- { b ? (nCoreOptions |= VIEWOPT_1_ONLINESPELL ) : ( nCoreOptions &= ~VIEWOPT_1_ONLINESPELL); } ++ void SetOnlineSpell( bool b ); + + inline bool IsViewMetaChars() const + { return !bReadonly && (nCoreOptions & VIEWOPT_1_VIEWMETACHARS) != 0; } +diff --git a/sw/source/uibase/config/viewopt.cxx b/sw/source/uibase/config/viewopt.cxx +index 7597589f0657..c5080e84abd4 100644 +--- a/sw/source/uibase/config/viewopt.cxx ++++ b/sw/source/uibase/config/viewopt.cxx +@@ -312,6 +312,11 @@ bool SwViewOption::IsAutoCompleteWords() + return rFlags.bAutoCmpltCollectWords; + } + ++void SwViewOption::SetOnlineSpell(bool b) ++{ ++ b ? (nCoreOptions |= VIEWOPT_1_ONLINESPELL ) : ( nCoreOptions &= ~VIEWOPT_1_ONLINESPELL); ++} ++ + AuthorCharAttr::AuthorCharAttr() : + nItemId (SID_ATTR_CHAR_UNDERLINE), + nAttr (UNDERLINE_SINGLE), +-- +2.12.0 + diff --git a/SOURCES/0184-Disable-spellcheck-when-LOK-is-active.patch b/SOURCES/0184-Disable-spellcheck-when-LOK-is-active.patch new file mode 100644 index 0000000..7a5d09f --- /dev/null +++ b/SOURCES/0184-Disable-spellcheck-when-LOK-is-active.patch @@ -0,0 +1,57 @@ +From 702edb07b785e27cfaf45f4feee9e07d7b9402e7 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 12:05:14 +0200 +Subject: [PATCH 184/398] Disable spellcheck when LOK is active + +It's not useful when viewing, and for editing probably a dedicated +overlay would be better (like the one we have for cursor/selections +already). + +Disable for sw/sd explicitly, sc had it disabled implicitly already. + +Change-Id: I7134f5d1a1546787c22019e6b1abdc0dd887f888 +(cherry picked from commit c92ebc850345924619a12327f36cc6ac9c0b09d1) +--- + sd/source/core/drawdoc.cxx | 4 +++- + sw/source/uibase/config/viewopt.cxx | 3 +++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/sd/source/core/drawdoc.cxx b/sd/source/core/drawdoc.cxx +index fcf678ec669f..f820fabaab81 100644 +--- a/sd/source/core/drawdoc.cxx ++++ b/sd/source/core/drawdoc.cxx +@@ -97,6 +97,7 @@ + + #include + #include ++#include + + using namespace ::sd; + using namespace ::com::sun::star; +@@ -229,7 +230,8 @@ SdDrawDocument::SdDrawDocument(DocumentType eType, SfxObjectShell* pDrDocSh) + SetLanguage( MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL, + ::com::sun::star::i18n::ScriptType::COMPLEX), EE_CHAR_LANGUAGE_CTL ); + +- mbOnlineSpell = aOptions.bIsSpellAuto; ++ if (!comphelper::LibreOfficeKit::isActive()) ++ mbOnlineSpell = aOptions.bIsSpellAuto; + } + + LanguageType eRealLanguage = MsLangId::getRealLanguage( meLanguage ); +diff --git a/sw/source/uibase/config/viewopt.cxx b/sw/source/uibase/config/viewopt.cxx +index c5080e84abd4..77c716af839d 100644 +--- a/sw/source/uibase/config/viewopt.cxx ++++ b/sw/source/uibase/config/viewopt.cxx +@@ -314,6 +314,9 @@ bool SwViewOption::IsAutoCompleteWords() + + void SwViewOption::SetOnlineSpell(bool b) + { ++ if (comphelper::LibreOfficeKit::isActive()) ++ return; ++ + b ? (nCoreOptions |= VIEWOPT_1_ONLINESPELL ) : ( nCoreOptions &= ~VIEWOPT_1_ONLINESPELL); + } + +-- +2.12.0 + diff --git a/SOURCES/0185-sw-extract-lcl_emitSearchResultCallbacks-from-SwView.patch b/SOURCES/0185-sw-extract-lcl_emitSearchResultCallbacks-from-SwView.patch new file mode 100644 index 0000000..6515e33 --- /dev/null +++ b/SOURCES/0185-sw-extract-lcl_emitSearchResultCallbacks-from-SwView.patch @@ -0,0 +1,121 @@ +From 5a52abcc97428423885cb144e5380e825e082abb Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 12:29:33 +0200 +Subject: [PATCH 185/398] sw: extract lcl_emitSearchResultCallbacks() from + SwView::ExecSearch() + +Change-Id: I9c6b7540bcae85d6529e5cc195a7e86f58ee5713 +(cherry picked from commit ca8016c3a317a7ba1f03e117d575fb78a572b4b3) +--- + sw/source/uibase/uiview/viewsrch.cxx | 88 +++++++++++++++++++----------------- + 1 file changed, 46 insertions(+), 42 deletions(-) + +diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx +index 570fadeb561a..a22cbdb6528f 100644 +--- a/sw/source/uibase/uiview/viewsrch.cxx ++++ b/sw/source/uibase/uiview/viewsrch.cxx +@@ -102,6 +102,51 @@ static void lcl_addContainerToJson(boost::property_tree::ptree& rTree, const OSt + rTree.add_child(rKey.getStr(), aChildren); + } + ++/// Emits LOK callbacks (count, selection) for search results. ++static void lcl_emitSearchResultCallbacks(sal_uInt16 nFound, SvxSearchItem* pSearchItem, SwWrtShell* pWrtShell) ++{ ++ OString aPayload = OString::number(nFound) + ";" + pSearchItem->GetSearchString().toUtf8(); ++ pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_COUNT, aPayload.getStr()); ++ ++ // Emit a callback also about the selection rectangles, grouped by matches. ++ if (SwPaM* pPaM = pWrtShell->GetCrsr()) ++ { ++ std::vector aMatches; ++ for (SwPaM& rPaM : pPaM->GetRingContainer()) ++ { ++ if (SwShellCrsr* pShellCrsr = dynamic_cast(&rPaM)) ++ { ++ std::vector aSelectionRectangles; ++ pShellCrsr->SwSelPaintRects::Show(&aSelectionRectangles); ++ std::stringstream ss; ++ bool bFirst = true; ++ for (size_t i = 0; i < aSelectionRectangles.size(); ++i) ++ { ++ const OString& rSelectionRectangle = aSelectionRectangles[i]; ++ if (rSelectionRectangle.isEmpty()) ++ continue; ++ if (bFirst) ++ bFirst = false; ++ else ++ ss << "; "; ++ ss << rSelectionRectangle.getStr(); ++ } ++ OString sRect = ss.str().c_str(); ++ aMatches.push_back(sRect); ++ } ++ } ++ boost::property_tree::ptree aTree; ++ aTree.put("searchString", pSearchItem->GetSearchString().toUtf8().getStr()); ++ lcl_addContainerToJson(aTree, "searchResultSelection", aMatches); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ aPayload = aStream.str().c_str(); ++ ++ pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); ++ } ++} ++ + void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + { + const SfxItemSet* pArgs = rReq.GetArgs(); +@@ -241,48 +286,7 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + m_bFound = false; + } + else if (comphelper::LibreOfficeKit::isActive()) +- { +- OString aPayload = OString::number(nFound) + ";" + m_pSrchItem->GetSearchString().toUtf8(); +- m_pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_COUNT, aPayload.getStr()); +- +- // Emit a callback also about the selection rectangles, grouped by matches. +- if (SwPaM* pPaM = m_pWrtShell->GetCrsr()) +- { +- std::vector aMatches; +- for (SwPaM& rPaM : pPaM->GetRingContainer()) +- { +- if (SwShellCrsr* pShellCrsr = dynamic_cast(&rPaM)) +- { +- std::vector aSelectionRectangles; +- pShellCrsr->SwSelPaintRects::Show(&aSelectionRectangles); +- std::stringstream ss; +- bool bFirst = true; +- for (size_t i = 0; i < aSelectionRectangles.size(); ++i) +- { +- const OString& rSelectionRectangle = aSelectionRectangles[i]; +- if (rSelectionRectangle.isEmpty()) +- continue; +- if (bFirst) +- bFirst = false; +- else +- ss << "; "; +- ss << rSelectionRectangle.getStr(); +- } +- OString sRect = ss.str().c_str(); +- aMatches.push_back(sRect); +- } +- } +- boost::property_tree::ptree aTree; +- aTree.put("searchString", m_pSrchItem->GetSearchString().toUtf8().getStr()); +- lcl_addContainerToJson(aTree, "searchResultSelection", aMatches); +- +- std::stringstream aStream; +- boost::property_tree::write_json(aStream, aTree); +- aPayload = aStream.str().c_str(); +- +- m_pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); +- } +- } ++ lcl_emitSearchResultCallbacks(nFound, m_pSrchItem, m_pWrtShell); + rReq.SetReturnValue(SfxBoolItem(nSlot, bRet)); + #if HAVE_FEATURE_DESKTOP + { +-- +2.12.0 + diff --git a/SOURCES/0186-sw-tiled-rendering-emit-LOK_CALLBACK_SEARCH_RESULT-f.patch b/SOURCES/0186-sw-tiled-rendering-emit-LOK_CALLBACK_SEARCH_RESULT-f.patch new file mode 100644 index 0000000..1feb496 --- /dev/null +++ b/SOURCES/0186-sw-tiled-rendering-emit-LOK_CALLBACK_SEARCH_RESULT-f.patch @@ -0,0 +1,67 @@ +From 418c00d936bad7f4ecc59fc5246a51218026e983 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 6 Oct 2015 14:17:43 +0200 +Subject: [PATCH 186/398] sw tiled rendering: emit LOK_CALLBACK_SEARCH_RESULT* + for normal search + +We used to emit these for find-all only, for no good reason. + +Change-Id: Id07dc7649f9a8528b9d4ec16d5f7c651fd607111 +(cherry picked from commit 58c38e7ea5debc5440f1d81acf38d8d6ad0883d8) +--- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 7 +++++++ + sw/source/uibase/uiview/viewsrch.cxx | 4 ++++ + 2 files changed, 11 insertions(+) + +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index 2fd27dd4f8ff..1eb57dea109e 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -342,7 +342,10 @@ void lcl_search(bool bBackward) + void SwTiledRenderingTest::testSearch() + { + #if !defined(WNT) && !defined(MACOSX) ++ comphelper::LibreOfficeKit::setActive(); ++ + SwXTextDocument* pXTextDocument = createDoc("search.odt"); ++ pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this); + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); + size_t nNode = pWrtShell->getShellCrsr(false)->Start()->nNode.GetNode().GetIndex(); + +@@ -351,6 +354,8 @@ void SwTiledRenderingTest::testSearch() + CPPUNIT_ASSERT(!pWrtShell->GetDrawView()->GetTextEditObject()); + size_t nActual = pWrtShell->getShellCrsr(false)->Start()->nNode.GetNode().GetIndex(); + CPPUNIT_ASSERT_EQUAL(nNode + 1, nActual); ++ /// Make sure we get search result selection for normal find as well, not only find all. ++ CPPUNIT_ASSERT(!m_aSearchResultSelection.empty()); + + // Next hit, in the shape. + lcl_search(false); +@@ -375,6 +380,8 @@ void SwTiledRenderingTest::testSearch() + CPPUNIT_ASSERT(!pWrtShell->GetDrawView()->GetTextEditObject()); + nActual = pWrtShell->getShellCrsr(false)->Start()->nNode.GetNode().GetIndex(); + CPPUNIT_ASSERT_EQUAL(nNode + 1, nActual); ++ ++ comphelper::LibreOfficeKit::setActive(false); + #endif + } + +diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx +index a22cbdb6528f..c8d3e7a571ea 100644 +--- a/sw/source/uibase/uiview/viewsrch.cxx ++++ b/sw/source/uibase/uiview/viewsrch.cxx +@@ -253,7 +253,11 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + { + bool bRet = SearchAndWrap(bApi); + if( bRet ) ++ { + Scroll(m_pWrtShell->GetCharRect().SVRect()); ++ if (comphelper::LibreOfficeKit::isActive()) ++ lcl_emitSearchResultCallbacks(1, m_pSrchItem, m_pWrtShell); ++ } + rReq.SetReturnValue(SfxBoolItem(nSlot, bRet)); + #if HAVE_FEATURE_DESKTOP + { +-- +2.12.0 + diff --git a/SOURCES/0187-libreofficekit-Werror-unused-macros.patch b/SOURCES/0187-libreofficekit-Werror-unused-macros.patch new file mode 100644 index 0000000..e6a32b1 --- /dev/null +++ b/SOURCES/0187-libreofficekit-Werror-unused-macros.patch @@ -0,0 +1,28 @@ +From 388c0b9a3d553a36557a116376fd27e1805160c1 Mon Sep 17 00:00:00 2001 +From: Michael Stahl +Date: Tue, 6 Oct 2015 14:23:38 +0200 +Subject: [PATCH 187/398] libreofficekit: -Werror=unused-macros + +Change-Id: I154bd2c101819669d43ab475144ae400454df4d0 +(cherry picked from commit 0ca6d934b318bda1c91e4166acc2f2216a0d2b2a) +--- + libreofficekit/source/gtk/tilebuffer.cxx | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 0e81bc33f262..992f06cd5e00 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -9,9 +9,6 @@ + + #include "tilebuffer.hxx" + +-#if !GLIB_CHECK_VERSION(2,40,0) +-#define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__) +-#endif + + /* ------------------ + Utility functions +-- +2.12.0 + diff --git a/SOURCES/0188-lokdocview-invalidate-after-selection-change.patch b/SOURCES/0188-lokdocview-invalidate-after-selection-change.patch new file mode 100644 index 0000000..69eaf79 --- /dev/null +++ b/SOURCES/0188-lokdocview-invalidate-after-selection-change.patch @@ -0,0 +1,29 @@ +From 8a809d3725511d14e9c8f65e5b1382169e8ed653 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 7 Oct 2015 16:01:43 +0200 +Subject: [PATCH 188/398] lokdocview: invalidate after selection change + +Without this e.g. Calc search does not show the selection rectangle +correctly. + +Change-Id: I5bc20a93ee861d3353bc2e1c1ed7ea8d0e6c8ed4 +(cherry picked from commit c5ceddf3445f7d56ea4f044366e4a797703bdd0c) +--- + libreofficekit/source/gtk/lokdocview.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 4026d958b8ed..a40496eb7357 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -619,6 +619,7 @@ callback (gpointer pData) + } + else + memset(&priv->m_aHandleMiddleRect, 0, sizeof(priv->m_aHandleMiddleRect)); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + break; + case LOK_CALLBACK_TEXT_SELECTION_START: +-- +2.12.0 + diff --git a/SOURCES/0189-sc-tiled-rendering-fix-showing-all-search-results.patch b/SOURCES/0189-sc-tiled-rendering-fix-showing-all-search-results.patch new file mode 100644 index 0000000..dd369c8 --- /dev/null +++ b/SOURCES/0189-sc-tiled-rendering-fix-showing-all-search-results.patch @@ -0,0 +1,36 @@ +From c8beb0f19a10c8dc2d73c8d7440cf48c51552191 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 7 Oct 2015 17:19:26 +0200 +Subject: [PATCH 189/398] sc tiled rendering: fix showing all search results + +Calc can have multiple cells selected, but there is only one cell which +has the black border around the cell. Code in +ScViewFunc::SearchAndReplace() assumed that the two are always the same, +and that's how find-all always highlighted the first match only. + +Fix this by avoiding emitting LOK_CALLBACK_TEXT_SELECTION two times, at +least in the find-all case. + +Change-Id: Ifce789c7f5f11e94fb2445846279823096ecb2dd +(cherry picked from commit a31f95b180728c1c671930913b4b4ad96ebcda5f) +--- + sc/source/ui/view/viewfun2.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx +index 47b0ace1ccef..295d3dbcbf44 100644 +--- a/sc/source/ui/view/viewfun2.cxx ++++ b/sc/source/ui/view/viewfun2.cxx +@@ -1837,7 +1837,8 @@ bool ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem, + AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP ); + SetCursor( nCol, nRow, true ); + +- if (rDoc.GetDrawLayer()->isTiledRendering()) ++ // Don't move cell selection handles for find-all: selection of all but the first result would be lost. ++ if (rDoc.GetDrawLayer()->isTiledRendering() && nCommand == SvxSearchCmd::FIND) + { + Point aCurPos = GetViewData().GetScrPos(nCol, nRow, GetViewData().GetActivePart()); + +-- +2.12.0 + diff --git a/SOURCES/0190-Make-this-compile-for-iOS-again.patch b/SOURCES/0190-Make-this-compile-for-iOS-again.patch new file mode 100644 index 0000000..8db5b8f --- /dev/null +++ b/SOURCES/0190-Make-this-compile-for-iOS-again.patch @@ -0,0 +1,51 @@ +From 2c2bc72ba3c8f2ac31e4d02a095342a3dca9d349 Mon Sep 17 00:00:00 2001 +From: Tor Lillqvist +Date: Wed, 7 Oct 2015 21:25:50 +0300 +Subject: [PATCH 190/398] Make this compile for iOS again + +Change-Id: I36f88d7e1114096d1e7a7a1d29077c387c21a10a +(cherry picked from commit 3c9da1fbfae9c00a5eb9ddcb106a01b075703fcd) +--- + desktop/source/lib/init.cxx | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 29e8e0d12faa..836fc00e1042 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -774,15 +774,6 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + + pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, + nTilePosX, nTilePosY, nTileWidth, nTileHeight); +-#else +- SystemGraphicsData aData; +- aData.rCGContext = reinterpret_cast(pBuffer); +- // the Size argument is irrelevant, I hope +- ScopedVclPtrInstance pDevice(&aData, Size(1, 1), (sal_uInt16)0); +- +- pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, +- nTilePosX, nTilePosY, nTileWidth, nTileHeight); +-#endif + + // Overwrite pBuffer's alpha channel with the separate alpha buffer. + for (int nRow = 0; nRow < nCanvasHeight; ++nRow) +@@ -795,6 +786,16 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + } + } + ++#else ++ SystemGraphicsData aData; ++ aData.rCGContext = reinterpret_cast(pBuffer); ++ // the Size argument is irrelevant, I hope ++ ScopedVclPtrInstance pDevice(&aData, Size(1, 1), (sal_uInt16)0); ++ ++ pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, ++ nTilePosX, nTilePosY, nTileWidth, nTileHeight); ++#endif ++ + static bool bDebug = getenv("LOK_DEBUG") != 0; + if (bDebug) + { +-- +2.12.0 + diff --git a/SOURCES/0191-comphelper-add-string-join.patch b/SOURCES/0191-comphelper-add-string-join.patch new file mode 100644 index 0000000..8386e56 --- /dev/null +++ b/SOURCES/0191-comphelper-add-string-join.patch @@ -0,0 +1,62 @@ +From b038b07bec23311c246fb71aac1d38431bc50fc4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 8 Oct 2015 08:33:09 +0200 +Subject: [PATCH 191/398] comphelper: add string::join() + +If there is a need for it, this could be extended later to work with uno +sequences and/or OUStrings as well. + +Change-Id: Id0af8b1755c8e4b668720563d10a052337e1b2c9 +(cherry picked from commit fce720b3e4691eb3b7deef1d005d76b23123a5cb) +--- + comphelper/source/misc/string.cxx | 11 +++++++++++ + include/comphelper/string.hxx | 4 ++++ + 2 files changed, 15 insertions(+) + +diff --git a/comphelper/source/misc/string.cxx b/comphelper/source/misc/string.cxx +index 98391741a13d..c6fa2fdde270 100644 +--- a/comphelper/source/misc/string.cxx ++++ b/comphelper/source/misc/string.cxx +@@ -269,6 +269,17 @@ uno::Sequence< OUString > + return kws; + } + ++OString join(const OString& rSeparator, const std::vector& rSequence) ++{ ++ OStringBuffer aBuffer; ++ for (size_t i = 0; i < rSequence.size(); ++i) ++ { ++ if (i != 0) ++ aBuffer.append(rSeparator); ++ aBuffer.append(rSequence[i]); ++ } ++ return aBuffer.makeStringAndClear(); ++} + + sal_Int32 compareNatural( const OUString & rLHS, const OUString & rRHS, + const uno::Reference< i18n::XCollator > &rCollator, +diff --git a/include/comphelper/string.hxx b/include/comphelper/string.hxx +index b9680372c21b..8d2552266cf2 100644 +--- a/include/comphelper/string.hxx ++++ b/include/comphelper/string.hxx +@@ -23,6 +23,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -310,6 +311,9 @@ COMPHELPER_DLLPUBLIC sal_Int32 indexOfAny(OUString const& rIn, + COMPHELPER_DLLPUBLIC OUString convertCommaSeparated( + ::com::sun::star::uno::Sequence< OUString > const & i_rSeq); + ++/// Return a string which is the concatenation of the strings in the sequence. ++COMPHELPER_DLLPUBLIC OString join(const OString& rSeparator, const std::vector& rSequence); ++ + /** Convert a decimal string to a number. + + The string must be base-10, no sign but can contain any +-- +2.12.0 + diff --git a/SOURCES/0192-sc-tiled-rendering-no-need-to-show-this-dialog.patch b/SOURCES/0192-sc-tiled-rendering-no-need-to-show-this-dialog.patch new file mode 100644 index 0000000..75cc8c5 --- /dev/null +++ b/SOURCES/0192-sc-tiled-rendering-no-need-to-show-this-dialog.patch @@ -0,0 +1,37 @@ +From 13b160581f9f3ebdb1c21722e4e6f9783e0e0775 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 8 Oct 2015 10:07:46 +0200 +Subject: [PATCH 192/398] sc tiled rendering: no need to show this dialog + +And it just causes problems during unit testing. + +Change-Id: Ie8524b726ae2709bab707df9b2984f07357e3059 +(cherry picked from commit dd7d97589bcbed22cf2dd12b574fc28baedf24af) +--- + sc/source/ui/view/viewfun2.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx +index 295d3dbcbf44..555492f17538 100644 +--- a/sc/source/ui/view/viewfun2.cxx ++++ b/sc/source/ui/view/viewfun2.cxx +@@ -86,6 +86,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1737,7 +1738,7 @@ bool ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem, + if (nCommand == SvxSearchCmd::FIND_ALL || nCommand == SvxSearchCmd::REPLACE_ALL) + { + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); +- if (pViewFrm) ++ if (pViewFrm && !comphelper::LibreOfficeKit::isActive()) + { + pViewFrm->ShowChildWindow(sc::SearchResultsDlgWrapper::GetChildWindowId(), true); + SfxChildWindow* pWnd = pViewFrm->GetChildWindow(sc::SearchResultsDlgWrapper::GetChildWindowId()); +-- +2.12.0 + diff --git a/SOURCES/0193-lok-Document-initializeForRendering-handle-lack-of-l.patch b/SOURCES/0193-lok-Document-initializeForRendering-handle-lack-of-l.patch new file mode 100644 index 0000000..326e034 --- /dev/null +++ b/SOURCES/0193-lok-Document-initializeForRendering-handle-lack-of-l.patch @@ -0,0 +1,37 @@ +From ad9dac7f0a8c7f2e9225a519334a274c215ad351 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 8 Oct 2015 10:27:53 +0200 +Subject: [PATCH 193/398] lok::Document::initializeForRendering(): handle lack + of lok_init() + +Normally lok_init() sets the component context, but not e.g. during unit +testing. + +Change-Id: If3760f31af2e4b870f65e5aa7557607e8b6a1114 +(cherry picked from commit de1f156c6a35757d74b0e337b02743f1962ff0ae) +--- + desktop/source/lib/init.cxx | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 836fc00e1042..b69e58a4af1f 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -568,6 +568,14 @@ static void doc_iniUnoCommands () + return; + } + ++ if (!xContext.is()) ++ xContext = comphelper::getProcessComponentContext(); ++ if (!xContext.is()) ++ { ++ SAL_WARN("lok", "iniUnoCommands: Component context is not available"); ++ return; ++ } ++ + SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool(pViewFrame); + uno::Reference xParser(util::URLTransformer::create(xContext)); + +-- +2.12.0 + diff --git a/SOURCES/0194-CppunitTest_desktop_lib-add-Calc-find-all-testcase.patch b/SOURCES/0194-CppunitTest_desktop_lib-add-Calc-find-all-testcase.patch new file mode 100644 index 0000000..26488b4 --- /dev/null +++ b/SOURCES/0194-CppunitTest_desktop_lib-add-Calc-find-all-testcase.patch @@ -0,0 +1,296 @@ +From a54392a6c40037d9903c7d35dc62f9de6fefffaf Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 8 Oct 2015 10:56:49 +0200 +Subject: [PATCH 194/398] CppunitTest_desktop_lib: add Calc find-all testcase + +Fails without commit a31f95b180728c1c671930913b4b4ad96ebcda5f (sc tiled +rendering: fix showing all search results, 2015-10-07). + +Change-Id: Ibc01d468168367f789b3f5046808104fa3f5ef18 +(cherry picked from commit 97c414758d3d8aa3cc2233d52612cf0a33c24c34) +--- + desktop/CppunitTest_desktop_lib.mk | 3 ++ + desktop/qa/data/search.ods | Bin 0 -> 7636 bytes + desktop/qa/desktop_lib/test_desktop_lib.cxx | 76 ++++++++++++++++++++++++++-- + 3 files changed, 76 insertions(+), 3 deletions(-) + create mode 100644 desktop/qa/data/search.ods + +diff --git a/desktop/CppunitTest_desktop_lib.mk b/desktop/CppunitTest_desktop_lib.mk +index be394600ddf0..0c963f9088c2 100644 +--- a/desktop/CppunitTest_desktop_lib.mk ++++ b/desktop/CppunitTest_desktop_lib.mk +@@ -56,11 +56,14 @@ $(eval $(call gb_CppunitTest_use_components,desktop_lib,\ + svtools/util/svt \ + sw/util/sw \ + sw/util/swd \ ++ sc/util/sc \ ++ sc/util/scd \ + toolkit/util/tk \ + ucb/source/core/ucb1 \ + ucb/source/ucp/file/ucpfile1 \ + unoxml/source/service/unoxml \ + xmloff/util/xo \ ++ i18npool/source/search/i18nsearch \ + )) + + $(eval $(call gb_CppunitTest_use_configuration,desktop_lib)) +diff --git a/desktop/qa/data/search.ods b/desktop/qa/data/search.ods +new file mode 100644 +index 0000000000000000000000000000000000000000..ea1d73153828a6a80329cfc617e4276fd2b51ab2 +GIT binary patch +literal 7636 +zcmdT}XIPWV){Qhlsvdgpy(mq33sR+rUIPROhJYkN5Rejz6p;=hy;ms$A|QxVLApqj +zE+8PFAiaIz+-o`K>Ur+{`RzP!OS0BGd(X_8nLWCi*f`_>06qY~43i8O1ONc% +z2j(k)3)BUI^m2oM-P~YMJ1`RJ3K#N#+Y7pa5m1Dns~ZGv?`nr~fxwZ12sd{K*dE~o +zfgpAN!dd>lIDY>E0C0X#V>m%hC>L8e7z#rOA-~-Uy1^a8bhTB9FVSAY{DoLuO<5mv +zeSta7@Ub!HxJO(N%mt)-6LdpNOiV^b1_%UdXlQ^yAaiqbJ3G5uw{9U22ybt1G#VWq +z9-fepkdl&;lao_YQc_!6+t}FH+S=OP-90okG&wmrKR>^|zP`1!b$WVw{))3R6HTQP +z0N{ePy0Rk3b7Fmz0FG85!%?7Xb#LRZNIg1xxI{C^EhfZWVu&E`kF~Zr +znwo#A)_UDx7gFkL?M!FTtom-R|7w&mt-G461UqW;)(2uLv64YeFddA`)-Q +zHsn0F6JOpKIvziY?uFJKZ%d|#0N0YM_6a7ToorweS|bkcoZg3NcOTA^<6Sv>#1 +zmWjcaPow$Vc|swta4SV(Ds8je5+0T(M3lvqD;a>C8zeq4HhVOPk@+n~`@^XpN35?8 +z)D*L785!Z@3F#S-lzBHe1WE{BdrOVOw#w6>So!4xGpkY&1$?_1?SsF6K~Pz|%fOy+ +znG9L!d9n!mN}{Z}oVo10a=2=;pGw$B&nj*K^qwInB5BTXdSFjANxyKFsD3v+$>ORy +zAdhlL@g%x{3JR1U_%L&_IZ`dp_6wf7O +z7c!Yk4pfLwv5}LB^qE~+gT;u_zdo!q=eu$o6nTa3Xne@-T6iUai7lRSb9ze4+47h? +zJt6U12+#Ig$E&5dvHP`vWG=D|Y7snp(X9->)Pc@fdHooQuh53ivLDE56t6+N2a-d) +z)dZ&F?St>ez4Gp5=4E)9x7MVIq(w4UKpbPkV${@g-`e|6FUtF{G)PLkuj6d@!QVr` +zc~w}u@7Sw!f{l{4#@MsmIk#3KE#EByu^KOrT%dBxFoaUy4_FjwKhbfZM0RmJzY^hF +zv%jePd@@wtcJjdtOz6^~tYAbU#x%Xr};P}jC`^0=JZ`k9R);}c3 +zJ2T*I*M0C_Q60zFksQ3oDh<^m&S`C*8=7sqo71yd8>$GrSaH+i3>&vrFfaK^<7v%)h17 +zz@a(b_F?Cs=CrxE%`}MwTC~`Z5`UW^$rAM#qE2Gub|oYDjG6eR7iEH4;)vHS3dH_4 +zTDChPh;izRJL7IrMx94rJ=90x1CO@E>*azx9TWUhz8A*%Bl$~&6M(U;r>{SoZ)xfu +z9$if5oc+919EEQ~mxp&Tt$F(fmuK?GbJ?2e{!^O5xR(9#93vp{o4%l9@G5BdE-iu8 +zlLoUM>Yhz5L?#sYEb^;I$yFxjHM}C%mtX5`-qb?|27^YdN>pac_^IsTK1NM-@NE}J +zUDcc+Oq|?;^&UYJSJSVpC3s^WG}J9^KZ-gsXuT%=ux_q6YH=ccWtD_E&at6PBUSPF +zD1Kn5^n<->rw47Ll_P^tzqbNvOzFM5xlT9HRrI8hwO{Pt5V=~>Z^D$fU8v4PRf01E +z*05h3)Wx2H$B2Ak)7O)B8uSzyh&T_GT($6Wmh9#D3VmNlHjSnn+P}AWmS5&>?U!P# +zV_&vB*P9IVxQL^cQA0dV4ba@GRkVDl$Ox||WzysH&^een73kwSd1!TntE+htzdjtD +zx`YD&gfRgCzt=}Xj6T}A!jb30FGe0mOlDjc#EI_BSc5%ZPLqqRyEwgI4<&95xxnLA +zx9k6cS9l$t%RGd=^R=J6#_46r2Z(8sIqIFt0k +zOWo7F1cPA@M>Ha3Uym;_(wmt}Og!%(k*^sZJ-u+0BY}*?5xH;C)Ol<5wM$%`3^vQC3mek{h5#t +zDXuiSJ*h=GzN2a@m1dm;yrt!rOUs+L9-Rz3{oFoW&s4YW!cw3bI=nkzQLtjjJ>-=s +zp;8g{T2W#9#Hn`rNhsH<;+)J2XhmZViAXg&WhItCYPh;< +zVx&wE1^-C1+xQeTAapR3iuq`R$!evTE>8_yL0$3DFahV?f;W(=(`&;bt3KJ~DT?sWQ_nDCo})!Hm`;ncDP@#=lr~ +zng>vY=(v7;rSVCWzD>58Y^yrT&n7`w-g?#yO#i?_TIO|DoAPYk)dyD{f(nBcC3Hz| +z5?cFy6|b?DQ(>wd)U;eOg5}8HOZ(tKkP6(e=O?#rg_|Q{s)X3rBM&%Jt(c9;d=C+^ +zx}^J@FspH^=eLhTdNTJXJ|c_fr6o%Q@Tvm;*mQKlJ)^(9=q!n|W^zanCLLB9A-o{~ +zWGSk6s%Uk>`C!zrYkv;S86TL3mu2r%WNUfn{ +zRMt(f$GjyQm9ls;KZx6`RVS_hg4}3fCnzg>0+w^_d9u9`j4POtsow6+T-NRyU1>HE +zk#xzb@Psq^l7YI%>OOM%eMg|T91kcwJ(tsCFOfHmKT^BWU}Z(d^maLR~x&8E|;G +zUNy`a;}#tolq}a^C%EBXE`hvp=Q7<1@%77bVr1UMWYE$M{x&_oJnO+Mwt^z@NBVpd +zC(YSO(?ZH>pPKFJ?GF83ea%=FjsNOH-x@zliMC#R9}5orBDIPwwMs7a1-pI8^;}(i +z_zHMAFzPZ#_D||^J`qPCy*4# +z+9oEc#gatGa6d_qp_sA+p=0 +zYEO>ouoewmryGE{I6UzjguMi^rN>-__Vb1p9r1k2^UUVZL{t^G)EFz-l&Z-%Vy?v} +z3Ct^Zs(7YM2tAu_pxb=HE36K0l=ov;e21&ea)<27vh}Nt{BZR^#;X&Tw+$tx<|4tH +zt!sKpl%Ea98dd2Mb1n$N=QWKQf=mQrE`jT9q!b_5!g=^^w9 +zk28ZJ+bynqRO%(qR3zj>2jPcZ8i}?#w&>1L1f}e@i}uD;YmUcevzF-MJ*^wSzDCaZ +zI$$bPy19hae;Ys{kaWx6&~{ng<hV(*7ayCg +zT+>gm4pYO`$%JXcRx_8@n>9)Dl+#j1JZSM_el50r{aYha6dnw92|EjW&Q^A5^a+BJ +z;X%o_+9?Mw$@}iI$CVoie$q7^nix~$uq7N{2+so=q`cLxYk7Y{7d^tS??ZAz0!->f1Qt&Prl +zy-e$P%Dq-iTvC2@N=DiN=C{&(Rev+@l%`W6D?nT65gC0PMSu;3ahkHmu92h#?lt|6 +zAXL?sB3mH+mOCe0V(fz^)l)F^jQP5wB>l+Z>|Rq`}@p(dS3yX{`rITAY*)ySIrXXG;W!70PxIH;UZt&jkqyS*5BH +z4mXD^#5)Vl_;XfIVAD_fyh^9y^mILy_0s8mFM^rTWNmM2Qg0y@_xe~*@-A>_ydm8C +zczp2YQr3QsvqN~>yU$N0^k@2{h;gblXf|*)Tno<7YKN{9YjcGpswIZ9F>G_7`*y~~ +z7ZdUgeCG2akyiQWY2`J@II655a_=L9XNNd^ +z=Z>?`4m#UKYH8=qlTqq5y^3Np6?t`*Pvc)$hNs`Ty6c#DOg}A^JrF?!@hD|LVVgxQ +z>a5T|Y|}G#hz8Ay#BxOnpGt}9dsY_&YWD_U`OXEjg*)`4P05voj#1>nhg{*#l$YvG +zUq1~B@Ff@6dB`S9F6VM@hCjctg5d4m@Q&>uPD-U8&+e-^7-^`yyyY43`H)onVaC85 +z4*>9E_@^Q1&y*Ad2|l0gK8Wj$nq(#q-t)cGv;MAQtV2C|VH{+sHKNh0Hg$spKx#wz#@Dyi*t`GG;{kg7|i7&;=)W(A!>dpK;%?cXI|iS)!rn +z4+_C^Qph5 +zRt#e_>P!bO-g(f-0)hsr2gPxlu3ydaQZl$=r=JV8nzfx+ZptA~m2++G3l{S3!LriC53& +zxaC`E4sI{B`Q1#jqB;G_kGeB;Wg`d6DAtR44g!xw4fd`%h!N-+ +zW;ZZl%iawdVLGq>3J*(?ZcKvk6(-sD`vuQ=LdXRShdMwINI`ddhu*keIQlAC(56f< +zq;E_?2p89#yZgCw#!Imf6I`LKlq=IsQE^6kxy7p)Zx^1Zh|EM)KVApZcSTecwtz(K +zcsRP%oN8A1q#6XD=S@mYjMefnr7(PPM(1Vl*585iN?Iod3tT6H^*_z#_DtE9(P?CD +z8IicHM$}Oqg-^ivKnc3@!G~6|Z=S%xSP!|D8SS;lEE_Q;Rg_tE30$lHBD9t{CP3i< +z!OiX8=oy~`r@I?= +zcTvObUuM|iZBm6dbXFUrz0Q_T1^drv=F6)+lwk^eIgW?X%hg*?_a}?f`W}x&N8VMFW8RcE56i0#h2T8z4mib!`=)@BIs-v1Onhcq=nm<1!!rlZ33^BBk5zg>Qw_ +zhlAASYGjWuYxokiU2>$&rc=Y-Y{4 +z(p1Q(C3DT+B!hBfEEGvXrzgDX)D@%hhrg&f!yh(uE(HFie)BteEA*B$CgD5T^&e4v +zK-t~pxxkI^J(O_ct)TiF?&=qv(u%y)2Jquz@4WkrZ{Q7E9IR;E<>7%`6<7zD6iOP^ +zHe8V#l+X#+(R@_V3~t9AMyISk1>q-mjz`n?Z{vxy28@8xZ@}2Ls?SunuaGh_x?Tr7 +z?u@&)Y!7dch7a7on^N|LvJ&C@TJ@3{ubqG=b!&2hfaIAh`V2aCz*{(LuSm(YF4oH4 +zq~F{WxI=Ybrv|)587!E-cLTGc($&0xMGpA=e#)N}|NZoBcjfP>zwelQ2LM2r+u!Y< +zd}H}m!$0Sc&V}=b1!9`u&w2H~BY$2Wp68f;SoX!gWSssE{CN~VUq1e1m=gS0O#U7B +zv-4h0f6sI-sz2<>FPQ#AVt-F|u4+GQ +z?H6P}OYXmTzP06Z+&A4k7u_GmM)jYe{*46xQ!Dsu;qLx|^k)J7Z=J0A1<%id{8uM` +i7Ls#G{$Z;ao?i;It|l&K(hLAx#(dl``lC&A{`7zUFl)>J + +literal 0 +HcmV?d00001 + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index a7696d824bee..3e00e597c314 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -16,6 +16,11 @@ + #include + #include + #include ++#include ++#include ++#include ++#include ++#include + + #include "../../inc/lib/init.hxx" + +@@ -45,14 +50,17 @@ public: + UnoApiTest::tearDown(); + }; + +- LibLODocument_Impl* loadDoc(const char* pName); ++ LibLODocument_Impl* loadDoc(const char* pName, LibreOfficeKitDocumentType eType = LOK_DOCTYPE_TEXT); + void closeDoc(); ++ static void callback(int nType, const char* pPayload, void* pData); ++ void callbackImpl(int nType, const char* pPayload); + + void testGetStyles(); + void testGetFonts(); + void testCreateView(); + void testGetFilterTypes(); + void testGetPartPageRectangles(); ++ void testSearchCalc(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -60,16 +68,31 @@ public: + CPPUNIT_TEST(testCreateView); + CPPUNIT_TEST(testGetFilterTypes); + CPPUNIT_TEST(testGetPartPageRectangles); ++ CPPUNIT_TEST(testSearchCalc); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; ++ OString m_aTextSelection; + }; + +-LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName) ++LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName, LibreOfficeKitDocumentType eType) + { + OUString aFileURL; + createFileURL(OUString::createFromAscii(pName), aFileURL); +- mxComponent = loadFromDesktop(aFileURL, "com.sun.star.text.TextDocument"); ++ OUString aService; ++ switch (eType) ++ { ++ case LOK_DOCTYPE_TEXT: ++ aService = "com.sun.star.text.TextDocument"; ++ break; ++ case LOK_DOCTYPE_SPREADSHEET: ++ aService = "com.sun.star.sheet.SpreadsheetDocument"; ++ break; ++ default: ++ CPPUNIT_ASSERT(false); ++ break; ++ } ++ mxComponent = loadFromDesktop(aFileURL, aService); + if (!mxComponent.is()) + { + CPPUNIT_ASSERT(false); +@@ -86,6 +109,23 @@ void DesktopLOKTest::closeDoc() + } + } + ++void DesktopLOKTest::callback(int nType, const char* pPayload, void* pData) ++{ ++ static_cast(pData)->callbackImpl(nType, pPayload); ++} ++ ++void DesktopLOKTest::callbackImpl(int nType, const char* pPayload) ++{ ++ switch (nType) ++ { ++ case LOK_CALLBACK_TEXT_SELECTION: ++ { ++ m_aTextSelection = pPayload; ++ } ++ break; ++ } ++} ++ + void DesktopLOKTest::testGetStyles() + { + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); +@@ -191,6 +231,36 @@ void DesktopLOKTest::testGetFilterTypes() + free(pJSON); + } + ++void DesktopLOKTest::testSearchCalc() ++{ ++ LibLibreOffice_Impl aOffice; ++ comphelper::LibreOfficeKit::setActive(); ++ LibLODocument_Impl* pDocument = loadDoc("search.ods"); ++ pDocument->pClass->initializeForRendering(pDocument); ++ pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); ++ ++ uno::Sequence aPropertyValues(comphelper::InitPropertySequence( ++ { ++ {"SearchItem.SearchString", uno::makeAny(OUString("foo"))}, ++ {"SearchItem.Backward", uno::makeAny(false)}, ++ {"SearchItem.Command", uno::makeAny(static_cast(SvxSearchCmd::FIND_ALL))}, ++ })); ++ comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); ++ ++ std::vector aSelections; ++ sal_Int32 nIndex = 0; ++ do ++ { ++ OString aToken = m_aTextSelection.getToken(0, ';', nIndex); ++ aSelections.push_back(aToken); ++ } while (nIndex >= 0); ++ // This was 1, find-all only found one match. ++ CPPUNIT_ASSERT_EQUAL(static_cast(2), aSelections.size()); ++ ++ closeDoc(); ++ comphelper::LibreOfficeKit::setActive(false); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +-- +2.12.0 + diff --git a/SOURCES/0195-editeng-sw-sc-use-comphelper-string-join.patch b/SOURCES/0195-editeng-sw-sc-use-comphelper-string-join.patch new file mode 100644 index 0000000..634f42e --- /dev/null +++ b/SOURCES/0195-editeng-sw-sc-use-comphelper-string-join.patch @@ -0,0 +1,63 @@ +From eacd7a0d10a02292f723031080884a8914fc496f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 8 Oct 2015 08:37:12 +0200 +Subject: [PATCH 195/398] editeng, sw, sc: use comphelper::string::join() + +(cherry picked from commit 1cb13d87b5d887718f6d81a842444b7251dc64cf) + +Change-Id: I9b0a32271a965bc4089720ccb61b26b67ceab7b2 +--- + sc/source/ui/view/gridwin.cxx | 13 ++++--------- + 1 file changed, 4 insertions(+), 9 deletions(-) + +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index cfc0b5e27dd1..1320e27cb104 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -134,6 +134,7 @@ + #include + #include + #include ++#include + + #define LOK_USE_UNSTABLE_API + #include +@@ -5899,9 +5900,8 @@ static void updateLibreOfficeKitSelection(ScViewData* pViewData, ScDrawLayer* pD + double nPPTY = pViewData->GetPPTY(); + + Rectangle aBoundingBox; +- std::stringstream ss; ++ std::vector aRectangles; + +- bool bIsFirst = true; + for (auto aRectangle : rRectangles) + { + aRectangle.Right() += 1; +@@ -5909,14 +5909,9 @@ static void updateLibreOfficeKitSelection(ScViewData* pViewData, ScDrawLayer* pD + + aBoundingBox.Union(aRectangle); + +- if (bIsFirst) +- bIsFirst = false; +- else +- ss << "; "; +- + Rectangle aRect(aRectangle.Left() / nPPTX, aRectangle.Top() / nPPTY, + aRectangle.Right() / nPPTX, aRectangle.Bottom() / nPPTY); +- ss << aRect.toString().getStr(); ++ aRectangles.push_back(aRect.toString()); + } + + // selection start handle +@@ -5930,7 +5925,7 @@ static void updateLibreOfficeKitSelection(ScViewData* pViewData, ScDrawLayer* pD + pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_END, aEnd.toString().getStr()); + + // the selection itself +- pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, ss.str().c_str()); ++ pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, comphelper::string::join("; ", aRectangles).getStr()); + } + + void ScGridWindow::UpdateCursorOverlay() +-- +2.12.0 + diff --git a/SOURCES/0196-sc-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch b/SOURCES/0196-sc-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch new file mode 100644 index 0000000..b2085c4 --- /dev/null +++ b/SOURCES/0196-sc-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch @@ -0,0 +1,178 @@ +From 88384ac6a550a05ab944fd4b56f0222ab57c4498 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 8 Oct 2015 11:49:13 +0200 +Subject: [PATCH 196/398] sc tiled rendering: implement + LOK_CALLBACK_SEARCH_RESULT_SELECTION + +Change-Id: Iaca2c1807a6e92cf7a87b0843000d65aea45fe7b +(cherry picked from commit a42f582e0e8ee4118415632795184620c6b8058c) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 13 +++++++++++++ + sc/source/ui/inc/gridwin.hxx | 2 ++ + sc/source/ui/view/gridwin.cxx | 23 +++++++++++++++++++--- + sc/source/ui/view/viewfun2.cxx | 30 ++++++++++++++++++++++++++--- + 4 files changed, 62 insertions(+), 6 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 3e00e597c314..e77bc8984bbf 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -73,6 +73,7 @@ public: + + uno::Reference mxComponent; + OString m_aTextSelection; ++ std::vector m_aSearchResultSelection; + }; + + LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName, LibreOfficeKitDocumentType eType) +@@ -123,6 +124,16 @@ void DesktopLOKTest::callbackImpl(int nType, const char* pPayload) + m_aTextSelection = pPayload; + } + break; ++ case LOK_CALLBACK_SEARCH_RESULT_SELECTION: ++ { ++ m_aSearchResultSelection.clear(); ++ boost::property_tree::ptree aTree; ++ std::stringstream aStream(pPayload); ++ boost::property_tree::read_json(aStream, aTree); ++ for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("searchResultSelection")) ++ m_aSearchResultSelection.push_back(rValue.second.data().c_str()); ++ } ++ break; + } + } + +@@ -256,6 +267,8 @@ void DesktopLOKTest::testSearchCalc() + } while (nIndex >= 0); + // This was 1, find-all only found one match. + CPPUNIT_ASSERT_EQUAL(static_cast(2), aSelections.size()); ++ // Make sure that we get exactly as many rectangle lists as matches. ++ CPPUNIT_ASSERT_EQUAL(static_cast(2), m_aSearchResultSelection.size()); + + closeDoc(); + comphelper::LibreOfficeKit::setActive(false); +diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx +index e4bb56aac1f0..b8425a8e34c3 100644 +--- a/sc/source/ui/inc/gridwin.hxx ++++ b/sc/source/ui/inc/gridwin.hxx +@@ -337,6 +337,8 @@ public: + /// @see vcl::ITiledRenderable::setTextSelection() for the values of nType. + /// Coordinates are in pixels. + void SetCellSelectionPixel(int nType, int nPixelX, int nPixelY); ++ /// Get the cell selection, coordinates are in logic units. ++ void GetCellSelection(std::vector& rLogicRects); + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE; + +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index 1320e27cb104..f24b42f3b27e 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -5890,8 +5890,12 @@ void ScGridWindow::UpdateCopySourceOverlay() + SetMapMode( aOldMode ); + } + +-/// Turn the selection ranges rRectangles into the LibreOfficeKit selection, and call the callback. +-static void updateLibreOfficeKitSelection(ScViewData* pViewData, ScDrawLayer* pDrawLayer, const std::vector& rRectangles) ++/** ++ * Turn the selection ranges rRectangles into the LibreOfficeKit selection, and call the callback. ++ * ++ * @param pLogicRects - if not 0, then don't invoke the callback, just collect the rectangles in the pointed vector. ++ */ ++static void updateLibreOfficeKitSelection(ScViewData* pViewData, ScDrawLayer* pDrawLayer, const std::vector& rRectangles, std::vector* pLogicRects = 0) + { + if (!pDrawLayer->isTiledRendering()) + return; +@@ -5911,9 +5915,15 @@ static void updateLibreOfficeKitSelection(ScViewData* pViewData, ScDrawLayer* pD + + Rectangle aRect(aRectangle.Left() / nPPTX, aRectangle.Top() / nPPTY, + aRectangle.Right() / nPPTX, aRectangle.Bottom() / nPPTY); +- aRectangles.push_back(aRect.toString()); ++ if (pLogicRects) ++ pLogicRects->push_back(aRect); ++ else ++ aRectangles.push_back(aRect.toString()); + } + ++ if (pLogicRects) ++ return; ++ + // selection start handle + Rectangle aStart(aBoundingBox.Left() / nPPTX, aBoundingBox.Top() / nPPTY, + aBoundingBox.Left() / nPPTX, (aBoundingBox.Top() / nPPTY) + 256); +@@ -6097,6 +6107,13 @@ void ScGridWindow::UpdateCursorOverlay() + SetMapMode( aOldMode ); + } + ++void ScGridWindow::GetCellSelection(std::vector& rLogicRects) ++{ ++ std::vector aPixelRects; ++ GetSelectionRects(aPixelRects); ++ updateLibreOfficeKitSelection(pViewData, pViewData->GetDocument()->GetDrawLayer(), aPixelRects, &rLogicRects); ++} ++ + void ScGridWindow::DeleteSelectionOverlay() + { + mpOOSelection.reset(); +diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx +index 555492f17538..2be84a4c8e39 100644 +--- a/sc/source/ui/view/viewfun2.cxx ++++ b/sc/source/ui/view/viewfun2.cxx +@@ -91,6 +91,7 @@ + #include + #include + #include ++#include + + using namespace com::sun::star; + using ::editeng::SvxBorderLine; +@@ -1838,20 +1839,43 @@ bool ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem, + AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP ); + SetCursor( nCol, nRow, true ); + +- // Don't move cell selection handles for find-all: selection of all but the first result would be lost. +- if (rDoc.GetDrawLayer()->isTiledRendering() && nCommand == SvxSearchCmd::FIND) ++ if (rDoc.GetDrawLayer()->isTiledRendering()) + { + Point aCurPos = GetViewData().GetScrPos(nCol, nRow, GetViewData().GetActivePart()); + + // just update the cell selection + ScGridWindow* pGridWindow = GetViewData().GetActiveWin(); +- if (pGridWindow) ++ // Don't move cell selection handles for find-all: selection of all but the first result would be lost. ++ if (pGridWindow && nCommand == SvxSearchCmd::FIND) + { + // move the cell selection handles + pGridWindow->SetCellSelectionPixel(LOK_SETTEXTSELECTION_RESET, aCurPos.X(), aCurPos.Y()); + pGridWindow->SetCellSelectionPixel(LOK_SETTEXTSELECTION_START, aCurPos.X(), aCurPos.Y()); + pGridWindow->SetCellSelectionPixel(LOK_SETTEXTSELECTION_END, aCurPos.X(), aCurPos.Y()); + } ++ ++ if (pGridWindow) ++ { ++ std::vector aLogicRects; ++ pGridWindow->GetCellSelection(aLogicRects); ++ ++ boost::property_tree::ptree aTree; ++ aTree.put("searchString", pSearchItem->GetSearchString().toUtf8().getStr()); ++ ++ boost::property_tree::ptree aSelections; ++ for (const Rectangle& rLogicRect : aLogicRects) ++ { ++ boost::property_tree::ptree aSelection; ++ aSelection.put("", rLogicRect.toString().getStr()); ++ aSelections.push_back(std::make_pair("", aSelection)); ++ } ++ aTree.add_child("searchResultSelection", aSelections); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ OString aPayload = aStream.str().c_str(); ++ rDoc.GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); ++ } + } + + if ( nCommand == SvxSearchCmd::REPLACE +-- +2.12.0 + diff --git a/SOURCES/0197-LOK-CALLBACK_SEARCH_RESULT_COUNT-is-redundant.patch b/SOURCES/0197-LOK-CALLBACK_SEARCH_RESULT_COUNT-is-redundant.patch new file mode 100644 index 0000000..892e52a --- /dev/null +++ b/SOURCES/0197-LOK-CALLBACK_SEARCH_RESULT_COUNT-is-redundant.patch @@ -0,0 +1,182 @@ +From 764878984eaaf6099dc2eb7dced5f6faa775bb8a Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 9 Oct 2015 08:08:48 +0200 +Subject: [PATCH 197/398] LOK: CALLBACK_SEARCH_RESULT_COUNT is redundant + +1) The size of the searchResultSelection array in +LOK_CALLBACK_SEARCH_RESULT_SELECTION provides the same information. + +2) None of the clients except lokdocview used it. + +3) Only sw provided this callback, not sc/sd. + +Change-Id: I9da639b6693f24634f298f9bc4773f705e944359 +(cherry picked from commit f0e3fe840b6f103c589f044bbde18b2faa345279) +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 6 ------ + libreofficekit/source/gtk/lokdocview.cxx | 14 ++++++-------- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 12 +----------- + sw/source/uibase/uiview/viewsrch.cxx | 14 +++++--------- + 4 files changed, 12 insertions(+), 34 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index b87f69a39989..0da87699b1b5 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -158,12 +158,6 @@ typedef enum + LOK_CALLBACK_SET_PART, + + /** +- * Number of search results followed by the original searched phrase. +- * count;phrase +- */ +- LOK_CALLBACK_SEARCH_RESULT_COUNT, +- +- /** + * Selection rectangles of the search result when find all is performed. + * + * Payload format example, in case of two matches: +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index a40496eb7357..3f1d5815d05d 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #include + #define LOK_USE_UNSTABLE_API +@@ -227,8 +228,6 @@ callbackTypeToString (int nType) + return "LOK_CALLBACK_STATUS_INDICATOR_FINISH"; + case LOK_CALLBACK_SEARCH_NOT_FOUND: + return "LOK_CALLBACK_SEARCH_NOT_FOUND"; +- case LOK_CALLBACK_SEARCH_RESULT_COUNT: +- return "LOK_CALLBACK_SEARCH_RESULT_COUNT"; + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + return "LOK_CALLBACK_DOCUMENT_SIZE_CHANGED"; + case LOK_CALLBACK_SET_PART: +@@ -661,12 +660,6 @@ callback (gpointer pData) + searchNotFound(pDocView, pCallback->m_aPayload); + } + break; +- case LOK_CALLBACK_SEARCH_RESULT_COUNT: +- { +- size_t nPos = pCallback->m_aPayload.find_first_of(";"); +- searchResultCount(pDocView, pCallback->m_aPayload.substr(0, nPos)); +- } +- break; + case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED: + { + payloadToSize(pCallback->m_aPayload.c_str(), priv->m_nDocumentWidthTwips, priv->m_nDocumentHeightTwips); +@@ -684,6 +677,11 @@ callback (gpointer pData) + break; + case LOK_CALLBACK_SEARCH_RESULT_SELECTION: + { ++ boost::property_tree::ptree aTree; ++ std::stringstream aStream(pCallback->m_aPayload); ++ boost::property_tree::read_json(aStream, aTree); ++ int nCount = aTree.get_child("searchResultSelection").size(); ++ searchResultCount(pDocView, std::to_string(nCount)); + } + break; + default: +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index 1eb57dea109e..eb59b62b9208 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -72,13 +72,11 @@ private: + Size m_aDocumentSize; + OString m_aTextSelection; + bool m_bFound; +- sal_Int32 m_nSearchResultCount; + std::vector m_aSearchResultSelection; + }; + + SwTiledRenderingTest::SwTiledRenderingTest() +- : m_bFound(true), +- m_nSearchResultCount(0) ++ : m_bFound(true) + { + } + +@@ -134,12 +132,6 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + m_bFound = false; + } + break; +- case LOK_CALLBACK_SEARCH_RESULT_COUNT: +- { +- std::string aStrPayload(pPayload); +- m_nSearchResultCount = std::stoi(aStrPayload.substr(0, aStrPayload.find_first_of(";"))); +- } +- break; + case LOK_CALLBACK_SEARCH_RESULT_SELECTION: + { + m_aSearchResultSelection.clear(); +@@ -485,8 +477,6 @@ void SwTiledRenderingTest::testSearchAll() + })); + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + // This was 0; should be 2 results in the body text. +- CPPUNIT_ASSERT_EQUAL(static_cast(2), m_nSearchResultCount); +- // Make sure that we get exactly as many rectangle lists as matches. + CPPUNIT_ASSERT_EQUAL(static_cast(2), m_aSearchResultSelection.size()); + + comphelper::LibreOfficeKit::setActive(false); +diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx +index c8d3e7a571ea..7f1addcc3f6b 100644 +--- a/sw/source/uibase/uiview/viewsrch.cxx ++++ b/sw/source/uibase/uiview/viewsrch.cxx +@@ -103,11 +103,8 @@ static void lcl_addContainerToJson(boost::property_tree::ptree& rTree, const OSt + } + + /// Emits LOK callbacks (count, selection) for search results. +-static void lcl_emitSearchResultCallbacks(sal_uInt16 nFound, SvxSearchItem* pSearchItem, SwWrtShell* pWrtShell) ++static void lcl_emitSearchResultCallbacks(SvxSearchItem* pSearchItem, SwWrtShell* pWrtShell) + { +- OString aPayload = OString::number(nFound) + ";" + pSearchItem->GetSearchString().toUtf8(); +- pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_COUNT, aPayload.getStr()); +- + // Emit a callback also about the selection rectangles, grouped by matches. + if (SwPaM* pPaM = pWrtShell->GetCrsr()) + { +@@ -141,7 +138,7 @@ static void lcl_emitSearchResultCallbacks(sal_uInt16 nFound, SvxSearchItem* pSea + + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); +- aPayload = aStream.str().c_str(); ++ OString aPayload = aStream.str().c_str(); + + pWrtShell->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); + } +@@ -256,7 +253,7 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + { + Scroll(m_pWrtShell->GetCharRect().SVRect()); + if (comphelper::LibreOfficeKit::isActive()) +- lcl_emitSearchResultCallbacks(1, m_pSrchItem, m_pWrtShell); ++ lcl_emitSearchResultCallbacks(m_pSrchItem, m_pWrtShell); + } + rReq.SetReturnValue(SfxBoolItem(nSlot, bRet)); + #if HAVE_FEATURE_DESKTOP +@@ -275,8 +272,7 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + break; + case SvxSearchCmd::FIND_ALL: + { +- sal_uInt16 nFound = 0; +- bool bRet = SearchAll(&nFound); ++ bool bRet = SearchAll(); + if( !bRet ) + { + #if HAVE_FEATURE_DESKTOP +@@ -290,7 +286,7 @@ void SwView::ExecSearch(SfxRequest& rReq, bool bNoMessage) + m_bFound = false; + } + else if (comphelper::LibreOfficeKit::isActive()) +- lcl_emitSearchResultCallbacks(nFound, m_pSrchItem, m_pWrtShell); ++ lcl_emitSearchResultCallbacks(m_pSrchItem, m_pWrtShell); + rReq.SetReturnValue(SfxBoolItem(nSlot, bRet)); + #if HAVE_FEATURE_DESKTOP + { +-- +2.12.0 + diff --git a/SOURCES/0198-lokdocview-log-postUnoCommand-arguments.patch b/SOURCES/0198-lokdocview-log-postUnoCommand-arguments.patch new file mode 100644 index 0000000..0f5c6be --- /dev/null +++ b/SOURCES/0198-lokdocview-log-postUnoCommand-arguments.patch @@ -0,0 +1,37 @@ +From c63b17a5bc9f15f1b04c01733e439486efe85003 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 9 Oct 2015 08:27:48 +0200 +Subject: [PATCH 198/398] lokdocview: log postUnoCommand() arguments + +Change-Id: I0febc2b89d95bde59ad9d3a90d404b3932cc3624 +(cherry picked from commit 2e1503dbd01aa62ae4ad0af4f481797521c1c8d5) +--- + libreofficekit/source/gtk/lokdocview.cxx | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 3f1d5815d05d..4af48bbea5a5 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -698,7 +698,7 @@ static void callbackWorker (int nType, const char* pPayload, void* pData) + LOKDocView* pDocView = LOK_DOC_VIEW (pData); + + CallbackData* pCallback = new CallbackData(nType, pPayload ? pPayload : "(nil)", pDocView); +- g_info("lok_doc_view_callbackWorker: %s, '%s'", callbackTypeToString(nType), pPayload); ++ g_info("callbackWorker: %s, '%s'", callbackTypeToString(nType), pPayload); + gdk_threads_add_idle(callback, pCallback); + } + +@@ -1365,6 +1365,9 @@ postCommandInThread (gpointer data) + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); ++ std::stringstream ss; ++ ss << "lok::Document::postUnoCommand(" << pLOEvent->m_pCommand << ", " << pLOEvent->m_pArguments << ")"; ++ g_info(ss.str().c_str()); + priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments); + } + +-- +2.12.0 + diff --git a/SOURCES/0199-gtktiledviewer-drop-tiles-on-set-part-event.patch b/SOURCES/0199-gtktiledviewer-drop-tiles-on-set-part-event.patch new file mode 100644 index 0000000..72b2047 --- /dev/null +++ b/SOURCES/0199-gtktiledviewer-drop-tiles-on-set-part-event.patch @@ -0,0 +1,41 @@ +From 668c19de934fbdb0c5e4ae3fecf133a3bd90ef34 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 12 Oct 2015 12:41:49 +0200 +Subject: [PATCH 199/398] gtktiledviewer: drop tiles on set-part event + +When changePart() is called, we have two type of actions: + +- the ones we want to execute only in case the part was changed by the + user (and not programatically -- e.g. because the request came from + the widget) +- the ones we want to execute all the time + +Resetting the view (so the tile buffer drops all the tiles) is something +we want to do all the time, that's one of the needed things when the +set-part event is emitted. + +Change-Id: Ic6bfbe460dc5a3fd8834f3b1ef93436fc9d3ad84 +(cherry picked from commit 27fa10fa53c7ff28c2636b6b49118c87c822f2fd) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 3d0b0deba323..3b5d456586e6 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -535,10 +535,8 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + TiledWindow& rWindow = lcl_getTiledWindow(pSelector); + + if (rWindow.m_bPartSelectorBroadcast && rWindow.m_pDocView) +- { + lok_doc_view_set_part( LOK_DOC_VIEW(rWindow.m_pDocView), nPart ); +- lok_doc_view_reset_view( LOK_DOC_VIEW(rWindow.m_pDocView) ); +- } ++ lok_doc_view_reset_view(LOK_DOC_VIEW(rWindow.m_pDocView)); + } + + static void removeChildrenFromStatusbar(GtkWidget* children, gpointer pData) +-- +2.12.0 + diff --git a/SOURCES/0200-sd-tiled-rendering-make-invalidation-in-DrawViewShel.patch b/SOURCES/0200-sd-tiled-rendering-make-invalidation-in-DrawViewShel.patch new file mode 100644 index 0000000..769505f --- /dev/null +++ b/SOURCES/0200-sd-tiled-rendering-make-invalidation-in-DrawViewShel.patch @@ -0,0 +1,66 @@ +From 3579df2e34825da4939c5b10d17c79872badc549 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 12 Oct 2015 14:25:18 +0200 +Subject: [PATCH 200/398] sd tiled rendering: make invalidation in + DrawViewShell::SwitchPage() optional + +In case of tiled rendering clients already get LOK_CALLBACK_SET_PART +when switching slides, so it's pointless to additionally invalidate +windows for help lines. + +Change-Id: Ibc15c9862ae85bd72328161fa5f7e72d82fd2a97 +(cherry picked from commit ca3436723455a0d0f3ced6f33b646b7c79ab05a1) +--- + include/svx/svdpagv.hxx | 2 +- + sd/source/ui/view/drviews1.cxx | 3 ++- + svx/source/svdraw/svdpagv.cxx | 5 +++-- + 3 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/include/svx/svdpagv.hxx b/include/svx/svdpagv.hxx +index f28e3e7cb79d..3b890c13cd70 100644 +--- a/include/svx/svdpagv.hxx ++++ b/include/svx/svdpagv.hxx +@@ -224,7 +224,7 @@ public: + const SetOfByte& GetLockedLayers() const { return aLayerLock; } + + const SdrHelpLineList& GetHelpLines() const { return aHelpLines; } +- void SetHelpLines(const SdrHelpLineList& rHLL); ++ void SetHelpLines(const SdrHelpLineList& rHLL, bool bInvalidate = true); + //void SetHelpLinePos(sal_uInt16 nNum, const Point& rNewPos); + void SetHelpLine(sal_uInt16 nNum, const SdrHelpLine& rNewHelpLine); + void DeleteHelpLine(sal_uInt16 nNum); +diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx +index 3b749419e860..c92cfde79262 100644 +--- a/sd/source/ui/view/drviews1.cxx ++++ b/sd/source/ui/view/drviews1.cxx +@@ -986,7 +986,8 @@ bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage) + } + else + { +- pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() ); ++ bool bInvalidate = !comphelper::LibreOfficeKit::isActive(); ++ pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines(), bInvalidate ); + } + } + +diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx +index 9c74d433e1c9..47fa8f52b471 100644 +--- a/svx/source/svdraw/svdpagv.cxx ++++ b/svx/source/svdraw/svdpagv.cxx +@@ -741,10 +741,11 @@ void SdrPageView::ImpInvalidateHelpLineArea(sal_uInt16 nNum) const + } + } + +-void SdrPageView::SetHelpLines(const SdrHelpLineList& rHLL) ++void SdrPageView::SetHelpLines(const SdrHelpLineList& rHLL, bool bInvalidate) + { + aHelpLines=rHLL; +- InvalidateAllWin(); ++ if (bInvalidate) ++ InvalidateAllWin(); + } + + void SdrPageView::SetHelpLine(sal_uInt16 nNum, const SdrHelpLine& rNewHelpLine) +-- +2.12.0 + diff --git a/SOURCES/0201-tdf-95002-sd-tiled-rendering-fix-handling-of-images-.patch b/SOURCES/0201-tdf-95002-sd-tiled-rendering-fix-handling-of-images-.patch new file mode 100644 index 0000000..fc787fd --- /dev/null +++ b/SOURCES/0201-tdf-95002-sd-tiled-rendering-fix-handling-of-images-.patch @@ -0,0 +1,97 @@ +From 07a7cf95d91cbd776490543762902136280994fe Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 13 Oct 2015 10:46:59 +0200 +Subject: [PATCH 201/398] tdf#95002 sd tiled rendering: fix handling of images + on page switch + +It turns out a full invalidation is still needed to trigger the loading +of graphics on the new page, so instead of not invalidating just don't +emit the notification about it during page switch. + +(cherry picked from commit 1631fa9a722553da1ebe0650a65e859862c4405d) + +Change-Id: Ic99a3d4e268b3db61cf09c78ed0f310c9d365867 +--- + include/svx/svdpagv.hxx | 2 +- + sd/source/ui/inc/DrawViewShell.hxx | 2 ++ + sd/source/ui/view/drviews1.cxx | 3 +-- + sd/source/ui/view/sdwindow.cxx | 4 ++++ + svx/source/svdraw/svdpagv.cxx | 5 ++--- + 5 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/include/svx/svdpagv.hxx b/include/svx/svdpagv.hxx +index 3b890c13cd70..f28e3e7cb79d 100644 +--- a/include/svx/svdpagv.hxx ++++ b/include/svx/svdpagv.hxx +@@ -224,7 +224,7 @@ public: + const SetOfByte& GetLockedLayers() const { return aLayerLock; } + + const SdrHelpLineList& GetHelpLines() const { return aHelpLines; } +- void SetHelpLines(const SdrHelpLineList& rHLL, bool bInvalidate = true); ++ void SetHelpLines(const SdrHelpLineList& rHLL); + //void SetHelpLinePos(sal_uInt16 nNum, const Point& rNewPos); + void SetHelpLine(sal_uInt16 nNum, const SdrHelpLine& rNewHelpLine); + void DeleteHelpLine(sal_uInt16 nNum); +diff --git a/sd/source/ui/inc/DrawViewShell.hxx b/sd/source/ui/inc/DrawViewShell.hxx +index 405e7af90876..cba478b8af7e 100644 +--- a/sd/source/ui/inc/DrawViewShell.hxx ++++ b/sd/source/ui/inc/DrawViewShell.hxx +@@ -376,6 +376,8 @@ public: + + OUString GetSidebarContextName() const; + ++ bool IsInSwitchPage() { return mbIsInSwitchPage; } ++ + //move this method to ViewShell. + //void NotifyAccUpdate(); + protected: +diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx +index c92cfde79262..3b749419e860 100644 +--- a/sd/source/ui/view/drviews1.cxx ++++ b/sd/source/ui/view/drviews1.cxx +@@ -986,8 +986,7 @@ bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage) + } + else + { +- bool bInvalidate = !comphelper::LibreOfficeKit::isActive(); +- pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines(), bInvalidate ); ++ pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() ); + } + } + +diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx +index c9c4bfe15b61..7149cf99b694 100644 +--- a/sd/source/ui/view/sdwindow.cxx ++++ b/sd/source/ui/view/sdwindow.cxx +@@ -1006,6 +1006,10 @@ Selection Window::GetSurroundingTextSelection() const + + void Window::LogicInvalidate(const Rectangle* pRectangle) + { ++ DrawViewShell* pDrawViewShell = dynamic_cast(mpViewShell); ++ if (pDrawViewShell && pDrawViewShell->IsInSwitchPage()) ++ return; ++ + OString sRectangle; + if (!pRectangle) + sRectangle = "EMPTY"; +diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx +index 47fa8f52b471..9c74d433e1c9 100644 +--- a/svx/source/svdraw/svdpagv.cxx ++++ b/svx/source/svdraw/svdpagv.cxx +@@ -741,11 +741,10 @@ void SdrPageView::ImpInvalidateHelpLineArea(sal_uInt16 nNum) const + } + } + +-void SdrPageView::SetHelpLines(const SdrHelpLineList& rHLL, bool bInvalidate) ++void SdrPageView::SetHelpLines(const SdrHelpLineList& rHLL) + { + aHelpLines=rHLL; +- if (bInvalidate) +- InvalidateAllWin(); ++ InvalidateAllWin(); + } + + void SdrPageView::SetHelpLine(sal_uInt16 nNum, const SdrHelpLine& rNewHelpLine) +-- +2.12.0 + diff --git a/SOURCES/0202-disable-test-that-causes-inf.-loop.patch b/SOURCES/0202-disable-test-that-causes-inf.-loop.patch new file mode 100644 index 0000000..924bfdd --- /dev/null +++ b/SOURCES/0202-disable-test-that-causes-inf.-loop.patch @@ -0,0 +1,25 @@ +From ad972ff3800abe1e6336d545d0ba33593bd67f84 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 20 Mar 2017 13:31:57 +0100 +Subject: [PATCH 202/398] disable test that causes inf. loop + +Change-Id: I24b58fb9fa6653a178bbee5fa9826fe3b03204c1 +--- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index eb59b62b9208..5e2b30ab7fde 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -61,7 +61,6 @@ public: + CPPUNIT_TEST(testSearchTextFrame); + CPPUNIT_TEST(testSearchTextFrameWrapAround); + CPPUNIT_TEST(testDocumentSizeChanged); +- CPPUNIT_TEST(testSearchAll); + CPPUNIT_TEST_SUITE_END(); + + private: +-- +2.12.0 + diff --git a/SOURCES/0203-sd-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch b/SOURCES/0203-sd-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch new file mode 100644 index 0000000..3c67a89 --- /dev/null +++ b/SOURCES/0203-sd-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch @@ -0,0 +1,73 @@ +From 32147fe3622284f6da6a2b3e577698a2a188a4b4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 13 Oct 2015 15:55:55 +0200 +Subject: [PATCH 203/398] sd tiled rendering: implement + LOK_CALLBACK_SEARCH_RESULT_SELECTION + +Given that sd doesn't support find-all yet, this works for normal find +only at the moment (so it may report multiple rectangles, but always a +single match). + +Change-Id: I47bd0d0161b9d1dc843bb503f5521f311fc158c4 +(cherry picked from commit 395cfab05752b87ae419304789d894c0fe9a98c2) +--- + sd/source/ui/view/Outliner.cxx | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx +index 8d88518c931f..41bf43d253f4 100644 +--- a/sd/source/ui/view/Outliner.cxx ++++ b/sd/source/ui/view/Outliner.cxx +@@ -18,6 +18,7 @@ + */ + + #include "Outliner.hxx" ++#include + #include + #include + +@@ -71,6 +72,7 @@ + #include + #include + #include ++#include + + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; +@@ -720,11 +722,32 @@ bool Outliner::SearchAndReplaceOnce() + + mpDrawDocument->GetDocSh()->SetWaitCursor( false ); + +- // notify LibreOfficeKit about changed page + if (pViewShell && pViewShell->GetDoc()->isTiledRendering() && mbStringFound) + { ++ // notify LibreOfficeKit about changed page + OString aPayload = OString::number(maCurrentPosition.mnPageIndex); + pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); ++ ++ // also about search result selections ++ std::vector aLogicRects; ++ pOutlinerView->GetSelectionRectangles(aLogicRects); ++ ++ boost::property_tree::ptree aTree; ++ aTree.put("searchString", mpSearchItem->GetSearchString().toUtf8().getStr()); ++ ++ std::vector aLogicRectStrings; ++ std::transform(aLogicRects.begin(), aLogicRects.end(), std::back_inserter(aLogicRectStrings), [](const Rectangle& rRectangle) { return rRectangle.toString(); }); ++ OString sRectangles = comphelper::string::join("; ", aLogicRectStrings); ++ boost::property_tree::ptree aChildren; ++ boost::property_tree::ptree aChild; ++ aChild.put("", sRectangles.getStr()); ++ aChildren.push_back(std::make_pair("", aChild)); ++ aTree.add_child("searchResultSelection", aChildren); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ aPayload = aStream.str().c_str(); ++ pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); + } + + return mbEndOfSearch; +-- +2.12.0 + diff --git a/SOURCES/0204-CppunitTest_sd_tiledrendering-CALLBACK_SEARCH_RESULT.patch b/SOURCES/0204-CppunitTest_sd_tiledrendering-CALLBACK_SEARCH_RESULT.patch new file mode 100644 index 0000000..cc2ae26 --- /dev/null +++ b/SOURCES/0204-CppunitTest_sd_tiledrendering-CALLBACK_SEARCH_RESULT.patch @@ -0,0 +1,74 @@ +From 01f73ec6b52c617a4d64b89de93aed3a6896fcf6 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 13 Oct 2015 16:38:37 +0200 +Subject: [PATCH 204/398] CppunitTest_sd_tiledrendering: + CALLBACK_SEARCH_RESULT_SELECTION testcase + +Change-Id: I8a2fcaad5806ef204cdac0f6eaac615d50d6d9e8 +(cherry picked from commit 28a5d4b5d3641837f3be8bc39ead111f9bba7015) +--- + sd/qa/unit/tiledrendering/tiledrendering.cxx | 20 +++++++++++++++++--- + 1 file changed, 17 insertions(+), 3 deletions(-) + +diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx +index 8ed091998ef1..f35449b12b2c 100644 +--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx ++++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx +@@ -7,6 +7,10 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + ++#include ++#include ++#include ++#include + #define LOK_USE_UNSTABLE_API + #include + #include +@@ -19,9 +23,6 @@ + #include + #include + #include +-#include +-#include +-#include + + #include + #include +@@ -78,6 +79,7 @@ private: + std::vector m_aSelection; + bool m_bFound; + sal_Int32 m_nPart; ++ std::vector m_aSearchResultSelection; + #endif + }; + +@@ -182,6 +184,16 @@ void SdTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + m_nPart = aPayload.toInt32(); + } + break; ++ case LOK_CALLBACK_SEARCH_RESULT_SELECTION: ++ { ++ m_aSearchResultSelection.clear(); ++ boost::property_tree::ptree aTree; ++ std::stringstream aStream(pPayload); ++ boost::property_tree::read_json(aStream, aTree); ++ for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("searchResultSelection")) ++ m_aSearchResultSelection.push_back(rValue.second.data().c_str()); ++ } ++ break; + } + } + +@@ -387,6 +399,8 @@ void SdTiledRenderingTest::testSearch() + lcl_search("bbb"); + CPPUNIT_ASSERT_EQUAL(static_cast(1), m_nPart); + CPPUNIT_ASSERT_EQUAL(true, m_bFound); ++ // This was 0; should be 1 match for "find". ++ CPPUNIT_ASSERT_EQUAL(static_cast(1), m_aSearchResultSelection.size()); + + // This should trigger the not-found callback. + Application::EnableHeadlessMode(false); +-- +2.12.0 + diff --git a/SOURCES/0205-Bump-gtk-version-to-2.18.patch b/SOURCES/0205-Bump-gtk-version-to-2.18.patch new file mode 100644 index 0000000..224dab5 --- /dev/null +++ b/SOURCES/0205-Bump-gtk-version-to-2.18.patch @@ -0,0 +1,292 @@ +From 98252b0c534e71b65f720af9d97a6a358268076d Mon Sep 17 00:00:00 2001 +From: Riccardo Magliocchetti +Date: Mon, 12 Oct 2015 22:13:37 +0200 +Subject: [PATCH 205/398] Bump gtk+ version to 2.18 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +2.18 is the version available in RHEL 6 released in 2010. + +Change-Id: I4cd4fc89f6b51e6f58ca72b8182f80316b1f4f88 +Reviewed-on: https://gerrit.libreoffice.org/19330 +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 068c04fb06806a9345c0059545d19a416d7e60b7) +--- + configure.ac | 4 +-- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 2 -- + sfx2/source/appl/shutdowniconunx.cxx | 6 ++--- + vcl/unx/gtk/app/gtkdata.cxx | 5 ++-- + vcl/unx/gtk/app/gtkinst.cxx | 4 +-- + vcl/unx/gtk/app/gtksys.cxx | 4 --- + vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx | 31 +++++++++------------- + vcl/unx/gtk/gdi/salprn-gtk.cxx | 14 ---------- + vcl/unx/gtk/inc/gtkprintwrapper.hxx | 6 ----- + 9 files changed, 20 insertions(+), 56 deletions(-) + +diff --git a/configure.ac b/configure.ac +index b1ec23a5afa3..12983e074c7d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -10126,7 +10126,7 @@ ENABLE_SYSTRAY_GTK="" + if test "$test_gtk" = "yes"; then + + if test "$ENABLE_GTK" = "TRUE"; then +- PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.10.0 gdk-pixbuf-2.0 >= 2.2 ,,AC_MSG_ERROR([requirements to build the gtk-plugin not met. Use --disable-gtk or install the missing packages])) ++ PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.18.0 gdk-pixbuf-2.0 >= 2.2 ,,AC_MSG_ERROR([requirements to build the gtk-plugin not met. Use --disable-gtk or install the missing packages])) + GTK_CFLAGS=$(printf '%s' "$GTK_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") + PKG_CHECK_MODULES(GTHREAD, gthread-2.0,,AC_MSG_ERROR([requirements to build the gtk-plugin not met. Use --disable-gtk or install the missing packages])) + BUILD_TYPE="$BUILD_TYPE GTK" +@@ -10185,7 +10185,7 @@ if test "$_os" != "WINNT" -a "$_os" != "Darwin" -a "$enable_telepathy" = "yes"; + ENABLE_TELEPATHY="TRUE" + AC_DEFINE(ENABLE_TELEPATHY) + AC_MSG_RESULT([yes]) +- PKG_CHECK_MODULES( TELEPATHY, telepathy-glib >= 0.18.0 glib-2.0 gobject-2.0 gthread-2.0 gio-2.0 gtk+-2.0 >= 2.10 ) ++ PKG_CHECK_MODULES( TELEPATHY, telepathy-glib >= 0.18.0 glib-2.0 gobject-2.0 gthread-2.0 gio-2.0 gtk+-2.0 >= 2.18.0 ) + TELEPATHY_CFLAGS=$(printf '%s' "$TELEPATHY_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g") + else + AC_MSG_RESULT([no]) +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 3b5d456586e6..e7e276dfce17 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -102,7 +102,6 @@ const float fZooms[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 5.0 }; + /// Get the visible area of the scrolled window + static void getVisibleAreaTwips(GtkWidget* pDocView, GdkRectangle* pArea) + { +-#if GTK_CHECK_VERSION(2,14,0) // we need gtk_adjustment_get_page_size() + TiledWindow& rWindow = lcl_getTiledWindow(pDocView); + + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); +@@ -116,7 +115,6 @@ static void getVisibleAreaTwips(GtkWidget* pDocView, GdkRectangle* pArea) + gtk_adjustment_get_page_size(pHAdjustment)); + pArea->height = lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), + gtk_adjustment_get_page_size(pVAdjustment)); +-#endif + } + + static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) +diff --git a/sfx2/source/appl/shutdowniconunx.cxx b/sfx2/source/appl/shutdowniconunx.cxx +index 90349f7261b0..2de5654fe28a 100644 +--- a/sfx2/source/appl/shutdowniconunx.cxx ++++ b/sfx2/source/appl/shutdowniconunx.cxx +@@ -370,10 +370,8 @@ void plugin_init_sys_tray() + { + ::SolarMutexGuard aGuard; + +- if( /* need gtk_status to resolve */ +- (gtk_check_version( 2, 10, 0 ) != NULL) || +- /* we need the vcl plugin and mainloop initialized */ +- !g_type_from_name( "GdkDisplay" ) ) ++ /* we need the vcl plugin and mainloop initialized */ ++ if (!g_type_from_name( "GdkDisplay" )) + return; + + OString aLabel; +diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx +index 445ae0a61772..ec2886fa4172 100644 +--- a/vcl/unx/gtk/app/gtkdata.cxx ++++ b/vcl/unx/gtk/app/gtkdata.cxx +@@ -750,9 +750,8 @@ void GtkData::Init() + pDisplay->monitorsChanged( pScreen ); + g_signal_connect( G_OBJECT(pScreen), "size-changed", + G_CALLBACK(signalScreenSizeChanged), pDisplay ); +- if( ! gtk_check_version( 2, 14, 0 ) ) // monitors-changed came in with 2.14, avoid an assertion +- g_signal_connect( G_OBJECT(pScreen), "monitors-changed", +- G_CALLBACK(signalMonitorsChanged), GetGtkDisplay() ); ++ g_signal_connect( G_OBJECT(pScreen), "monitors-changed", ++ G_CALLBACK(signalMonitorsChanged), GetGtkDisplay() ); + } + } + } +diff --git a/vcl/unx/gtk/app/gtkinst.cxx b/vcl/unx/gtk/app/gtkinst.cxx +index 601fd2152d1d..636049702280 100644 +--- a/vcl/unx/gtk/app/gtkinst.cxx ++++ b/vcl/unx/gtk/app/gtkinst.cxx +@@ -89,14 +89,12 @@ extern "C" + } + + const gchar* pVersion = gtk_check_version( 3, 2, 0 ); +-#else +- const gchar* pVersion = gtk_check_version( 2, 2, 0 ); +-#endif + if( pVersion ) + { + SAL_WARN("vcl.gtk", "gtk version conflict: " << pVersion); + return NULL; + } ++#endif + + GtkYieldMutex *pYieldMutex; + +diff --git a/vcl/unx/gtk/app/gtksys.cxx b/vcl/unx/gtk/app/gtksys.cxx +index 7d687b23943f..42d848ceb686 100644 +--- a/vcl/unx/gtk/app/gtksys.cxx ++++ b/vcl/unx/gtk/app/gtksys.cxx +@@ -195,7 +195,6 @@ bool GtkSalSystem::IsUnifiedDisplay() + } + + namespace { +-#if GTK_CHECK_VERSION(2,14,0) + static int _fallback_get_primary_monitor (GdkScreen *pScreen) + { + // Use monitor name as primacy heuristic +@@ -210,7 +209,6 @@ static int _fallback_get_primary_monitor (GdkScreen *pScreen) + } + return 0; + } +-#endif + + static int _get_primary_monitor (GdkScreen *pScreen) + { +@@ -224,10 +222,8 @@ static int _get_primary_monitor (GdkScreen *pScreen) + get_fn = reinterpret_cast(osl_getAsciiFunctionSymbol(NULL, + "gdk_screen_get_primary_monitor")); + } +-#if GTK_CHECK_VERSION(2,14,0) + if (!get_fn) + get_fn = _fallback_get_primary_monitor; +-#endif + if (get_fn) + return get_fn (pScreen); + else +diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +index 122059656f89..6512803bfaa0 100644 +--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx ++++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +@@ -3163,7 +3163,6 @@ bool GtkSalGraphics::NWPaintGTKToolbar( + { + const double shim = 0.2; + +-#if GTK_CHECK_VERSION(2,10,0) + gint separator_height, separator_width, wide_separators = 0; + + gtk_widget_style_get (gWidgetData[m_nXScreen].gSeparator, +@@ -3188,7 +3187,6 @@ bool GtkSalGraphics::NWPaintGTKToolbar( + w * (1 - 2*shim), separator_width); + } + else +-#endif + { + if (nPart == PART_SEPARATOR_VERT) + gtk_paint_vline (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable, +@@ -4017,23 +4015,20 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings ) + aStyleSet.SetHighlightColor( aHighlightColor ); + aStyleSet.SetHighlightTextColor( aHighlightTextColor ); + +- if( ! gtk_check_version( 2, 10, 0 ) ) // link colors came in with 2.10, avoid an assertion ++ // hyperlink colors ++ GdkColor *link_color = NULL; ++ gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL); ++ if (link_color) + { +- // hyperlink colors +- GdkColor *link_color = NULL; +- gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL); +- if (link_color) +- { +- aStyleSet.SetLinkColor(getColor(*link_color)); +- gdk_color_free (link_color); +- link_color = NULL; +- } +- gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL); +- if (link_color) +- { +- aStyleSet.SetVisitedLinkColor(getColor(*link_color)); +- gdk_color_free (link_color); +- } ++ aStyleSet.SetLinkColor(getColor(*link_color)); ++ gdk_color_free (link_color); ++ link_color = NULL; ++ } ++ gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL); ++ if (link_color) ++ { ++ aStyleSet.SetVisitedLinkColor(getColor(*link_color)); ++ gdk_color_free (link_color); + } + + // Tab colors +diff --git a/vcl/unx/gtk/gdi/salprn-gtk.cxx b/vcl/unx/gtk/gdi/salprn-gtk.cxx +index 650276c3a1f4..1ae010e886c9 100644 +--- a/vcl/unx/gtk/gdi/salprn-gtk.cxx ++++ b/vcl/unx/gtk/gdi/salprn-gtk.cxx +@@ -318,15 +318,9 @@ lcl_setHelpText( + const uno::Sequence& i_rHelpTexts, + const sal_Int32 i_nIndex) + { +-#if GTK_CHECK_VERSION(2,12,0) + if (i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength()) + gtk_widget_set_tooltip_text(io_pWidget, + OUStringToOString(i_rHelpTexts.getConstArray()[i_nIndex], RTL_TEXTENCODING_UTF8).getStr()); +-#else +- (void)io_pWidget; +- (void)i_rHelpTexts; +- (void)i_nIndex; +-#endif + } + + static GtkWidget* +@@ -429,12 +423,8 @@ GtkPrintDialog::impl_initDialog() + | GTK_PRINT_CAPABILITY_COLLATE + | GTK_PRINT_CAPABILITY_REVERSE + | GTK_PRINT_CAPABILITY_GENERATE_PS +-#if GTK_CHECK_VERSION(2,12,0) + | GTK_PRINT_CAPABILITY_NUMBER_UP +-#endif +-#if GTK_CHECK_VERSION(2,14,0) + | GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT +-#endif + )); + } + +@@ -787,11 +777,9 @@ GtkPrintDialog::impl_initPrintContent(uno::Sequence const& i_rDisabled + ePrintPages = GTK_PRINT_PAGES_RANGES; + break; + case 2: +-#if GTK_CHECK_VERSION(2,14,0) + if (m_xWrapper->supportsPrintSelection()) + ePrintPages = GTK_PRINT_PAGES_SELECTION; + else +-#endif + SAL_INFO("vcl.gtk", "the application wants to print a selection, but the present gtk version does not support it"); + break; + default: +@@ -999,7 +987,6 @@ void GtkPrintDialog::ExportAsPDF(const OUString &rFileURL, GtkPrintSettings *pSe + } + catch (...) {} + } +-#if GTK_CHECK_VERSION(2,17,5) + if (gtk_print_unix_dialog_get_has_selection(GTK_PRINT_UNIX_DIALOG(m_pDialog))) + { + uno::Any aSelection; +@@ -1022,7 +1009,6 @@ void GtkPrintDialog::ExportAsPDF(const OUString &rFileURL, GtkPrintSettings *pSe + aFilterData[aFilterData.getLength()-1].Value <<= aSelection; + } + } +-#endif + uno::Sequence aArgs(2); + aArgs[0].Name = "FilterData"; + aArgs[0].Value <<= aFilterData; +diff --git a/vcl/unx/gtk/inc/gtkprintwrapper.hxx b/vcl/unx/gtk/inc/gtkprintwrapper.hxx +index 009903254606..99d435cd7f8e 100644 +--- a/vcl/unx/gtk/inc/gtkprintwrapper.hxx ++++ b/vcl/unx/gtk/inc/gtkprintwrapper.hxx +@@ -13,13 +13,7 @@ + #include + + #if defined ENABLE_GTK_PRINT || GTK_CHECK_VERSION(3,0,0) +-#if GTK_CHECK_VERSION(2,14,0) + #include +-#else +-#include +-#include +-#include +-#endif + + #include + #include +-- +2.12.0 + diff --git a/SOURCES/0206-sd-tiled-rendering-initial-search-all.patch b/SOURCES/0206-sd-tiled-rendering-initial-search-all.patch new file mode 100644 index 0000000..c5ffd77 --- /dev/null +++ b/SOURCES/0206-sd-tiled-rendering-initial-search-all.patch @@ -0,0 +1,148 @@ +From fea53bcac5aaf5e18baf90c8bd6f0fb4142e2f63 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 14 Oct 2015 11:38:47 +0200 +Subject: [PATCH 206/398] sd tiled rendering: initial search all + +Change-Id: Icee3a07103fad1bf70637fbf23299f50b7ad838d +(cherry picked from commit 32d573cdd13126c13e46b4e3684446e888e8b8e6) +--- + sd/inc/Outliner.hxx | 5 ++- + sd/source/ui/view/Outliner.cxx | 71 +++++++++++++++++++++++++++++------------- + 2 files changed, 54 insertions(+), 22 deletions(-) + +diff --git a/sd/inc/Outliner.hxx b/sd/inc/Outliner.hxx +index 26ad3495357a..f01e244de308 100644 +--- a/sd/inc/Outliner.hxx ++++ b/sd/inc/Outliner.hxx +@@ -357,11 +357,14 @@ private: + bool SearchAndReplaceAll(); + + /** Do search and replace for next match. ++ @param pSelections ++ When tiled rendering and not 0, then don't emit LOK events, instead ++ assume the caller will do so. + @return + The return value specifies whether the search ended () or + another call to this method is required (). + */ +- bool SearchAndReplaceOnce(); ++ bool SearchAndReplaceOnce(std::vector* pSelections = 0); + + /** Detect changes of the document or view and react accordingly. Such + changes may occur because different calls to +diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx +index 41bf43d253f4..e02e879494b8 100644 +--- a/sd/source/ui/view/Outliner.cxx ++++ b/sd/source/ui/view/Outliner.cxx +@@ -490,7 +490,7 @@ bool Outliner::StartSearchAndReplace (const SvxSearchItem* pSearchItem) + Initialize ( ! mpSearchItem->GetBackward()); + + const SvxSearchCmd nCommand (mpSearchItem->GetCommand()); +- if (nCommand == SvxSearchCmd::REPLACE_ALL) ++ if (nCommand == SvxSearchCmd::FIND_ALL || nCommand == SvxSearchCmd::REPLACE_ALL) + bEndOfSearch = SearchAndReplaceAll (); + else + { +@@ -621,11 +621,32 @@ bool Outliner::SearchAndReplaceAll() + + // Search/replace until the end of the document is reached. + bool bFoundMatch; ++ std::vector aSelections; + do + { +- bFoundMatch = ! SearchAndReplaceOnce(); ++ bFoundMatch = ! SearchAndReplaceOnce(&aSelections); + } + while (bFoundMatch); ++ ++ if (mpSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL && pViewShell->GetDoc()->isTiledRendering() && !aSelections.empty()) ++ { ++ boost::property_tree::ptree aTree; ++ aTree.put("searchString", mpSearchItem->GetSearchString().toUtf8().getStr()); ++ ++ boost::property_tree::ptree aChildren; ++ for (const OString& rSelection : aSelections) ++ { ++ boost::property_tree::ptree aChild; ++ aChild.put("", rSelection.getStr()); ++ aChildren.push_back(std::make_pair("", aChild)); ++ } ++ aTree.add_child("searchResultSelection", aChildren); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ OString aPayload = aStream.str().c_str(); ++ pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); ++ } + } + + RestoreStartPosition (); +@@ -634,7 +655,7 @@ bool Outliner::SearchAndReplaceAll() + return true; + } + +-bool Outliner::SearchAndReplaceOnce() ++bool Outliner::SearchAndReplaceOnce(std::vector* pSelections) + { + DetectChange (); + +@@ -724,30 +745,38 @@ bool Outliner::SearchAndReplaceOnce() + + if (pViewShell && pViewShell->GetDoc()->isTiledRendering() && mbStringFound) + { +- // notify LibreOfficeKit about changed page +- OString aPayload = OString::number(maCurrentPosition.mnPageIndex); +- pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); +- +- // also about search result selections + std::vector aLogicRects; + pOutlinerView->GetSelectionRectangles(aLogicRects); + +- boost::property_tree::ptree aTree; +- aTree.put("searchString", mpSearchItem->GetSearchString().toUtf8().getStr()); +- + std::vector aLogicRectStrings; + std::transform(aLogicRects.begin(), aLogicRects.end(), std::back_inserter(aLogicRectStrings), [](const Rectangle& rRectangle) { return rRectangle.toString(); }); + OString sRectangles = comphelper::string::join("; ", aLogicRectStrings); +- boost::property_tree::ptree aChildren; +- boost::property_tree::ptree aChild; +- aChild.put("", sRectangles.getStr()); +- aChildren.push_back(std::make_pair("", aChild)); +- aTree.add_child("searchResultSelection", aChildren); +- +- std::stringstream aStream; +- boost::property_tree::write_json(aStream, aTree); +- aPayload = aStream.str().c_str(); +- pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); ++ ++ if (!pSelections) ++ { ++ // notify LibreOfficeKit about changed page ++ OString aPayload = OString::number(maCurrentPosition.mnPageIndex); ++ pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); ++ ++ // also about search result selections ++ boost::property_tree::ptree aTree; ++ aTree.put("searchString", mpSearchItem->GetSearchString().toUtf8().getStr()); ++ ++ boost::property_tree::ptree aChildren; ++ boost::property_tree::ptree aChild; ++ aChild.put("", sRectangles.getStr()); ++ aChildren.push_back(std::make_pair("", aChild)); ++ aTree.add_child("searchResultSelection", aChildren); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ aPayload = aStream.str().c_str(); ++ pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_RESULT_SELECTION, aPayload.getStr()); ++ } ++ else ++ { ++ pSelections->push_back(sRectangles); ++ } + } + + return mbEndOfSearch; +-- +2.12.0 + diff --git a/SOURCES/0207-sd-tiled-rendering-search-rectangle-is-part-specific.patch b/SOURCES/0207-sd-tiled-rendering-search-rectangle-is-part-specific.patch new file mode 100644 index 0000000..6082346 --- /dev/null +++ b/SOURCES/0207-sd-tiled-rendering-search-rectangle-is-part-specific.patch @@ -0,0 +1,106 @@ +From 303f6bd02ad4cbaec4caf67682da5aed87b2ccaa Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 14 Oct 2015 12:32:12 +0200 +Subject: [PATCH 207/398] sd tiled rendering: search rectangle is part-specific + +Change-Id: I88865db539779bc401550d7b4a3729b89d7e18b1 +(cherry picked from commit dd1fc2242a64a0b9ae8031a5edc7ecfcde4ec3df) +--- + sd/inc/Outliner.hxx | 16 +++++++++++++++- + sd/source/ui/view/Outliner.cxx | 16 +++++++++++----- + 2 files changed, 26 insertions(+), 6 deletions(-) + +diff --git a/sd/inc/Outliner.hxx b/sd/inc/Outliner.hxx +index f01e244de308..9f1f6aae3e8a 100644 +--- a/sd/inc/Outliner.hxx ++++ b/sd/inc/Outliner.hxx +@@ -41,6 +41,20 @@ class View; + class ViewShell; + class Window; + ++/// Describes a single search hit: a set of rectangles on a given page. ++struct SearchSelection ++{ ++ /// 0-based index of the page that has the selection. ++ int m_nPage; ++ /** ++ * List of selection rectangles in twips -- multiple rectangles only in ++ * case the selection spans over more layout lines. ++ */ ++ OString m_aRectangles; ++ ++ SearchSelection(int nPage, const OString& rRectangles); ++}; ++ + /** The main purpose of this class is searching and replacing as well as + spelling of impress documents. The main part of both tasks lies in + iterating over the pages and view modes of a document and apply the +@@ -364,7 +378,7 @@ private: + The return value specifies whether the search ended () or + another call to this method is required (). + */ +- bool SearchAndReplaceOnce(std::vector* pSelections = 0); ++ bool SearchAndReplaceOnce(std::vector* pSelections = 0); + + /** Detect changes of the document or view and react accordingly. Such + changes may occur because different calls to +diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx +index e02e879494b8..22db187ab7c8 100644 +--- a/sd/source/ui/view/Outliner.cxx ++++ b/sd/source/ui/view/Outliner.cxx +@@ -83,6 +83,12 @@ class SfxStyleSheetPool; + + namespace sd { + ++SearchSelection::SearchSelection(int nPage, const OString& rRectangles) ++ : m_nPage(nPage), ++ m_aRectangles(rRectangles) ++{ ++} ++ + class Outliner::Implementation + { + public: +@@ -621,7 +627,7 @@ bool Outliner::SearchAndReplaceAll() + + // Search/replace until the end of the document is reached. + bool bFoundMatch; +- std::vector aSelections; ++ std::vector aSelections; + do + { + bFoundMatch = ! SearchAndReplaceOnce(&aSelections); +@@ -634,10 +640,10 @@ bool Outliner::SearchAndReplaceAll() + aTree.put("searchString", mpSearchItem->GetSearchString().toUtf8().getStr()); + + boost::property_tree::ptree aChildren; +- for (const OString& rSelection : aSelections) ++ for (const SearchSelection& rSelection : aSelections) + { + boost::property_tree::ptree aChild; +- aChild.put("", rSelection.getStr()); ++ aChild.put("", rSelection.m_aRectangles.getStr()); + aChildren.push_back(std::make_pair("", aChild)); + } + aTree.add_child("searchResultSelection", aChildren); +@@ -655,7 +661,7 @@ bool Outliner::SearchAndReplaceAll() + return true; + } + +-bool Outliner::SearchAndReplaceOnce(std::vector* pSelections) ++bool Outliner::SearchAndReplaceOnce(std::vector* pSelections) + { + DetectChange (); + +@@ -775,7 +781,7 @@ bool Outliner::SearchAndReplaceOnce(std::vector* pSelections) + } + else + { +- pSelections->push_back(sRectangles); ++ pSelections->push_back(SearchSelection(maCurrentPosition.mnPageIndex, sRectangles)); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0208-LOK-include-part-numbers-in-CALLBACK_SEARCH_RESULT_S.patch b/SOURCES/0208-LOK-include-part-numbers-in-CALLBACK_SEARCH_RESULT_S.patch new file mode 100644 index 0000000..c5f7559 --- /dev/null +++ b/SOURCES/0208-LOK-include-part-numbers-in-CALLBACK_SEARCH_RESULT_S.patch @@ -0,0 +1,208 @@ +From 5cfe5701f287fcceee39cd2eb8ed403cda6eeea4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 14 Oct 2015 15:39:07 +0200 +Subject: [PATCH 208/398] LOK: include part numbers in + CALLBACK_SEARCH_RESULT_SELECTION payload + +Without that, the result in Calc/Impress is ambiguous. + +Change-Id: I8dfd8dafc996102ed583688fddd721c7600dc48c +(cherry picked from commit ad280b67f8fda8f832a6a83bc5665df448c6ad00) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 8 +++++++- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 14 ++++++++++---- + sc/source/ui/view/viewfun2.cxx | 3 ++- + sd/qa/unit/tiledrendering/tiledrendering.cxx | 9 ++++++++- + sd/source/ui/view/Outliner.cxx | 6 ++++-- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 8 +++++++- + sw/source/uibase/uiview/viewsrch.cxx | 3 ++- + 7 files changed, 40 insertions(+), 11 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index e77bc8984bbf..30d8ae7adaf0 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -74,6 +74,7 @@ public: + uno::Reference mxComponent; + OString m_aTextSelection; + std::vector m_aSearchResultSelection; ++ std::vector m_aSearchResultPart; + }; + + LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName, LibreOfficeKitDocumentType eType) +@@ -131,7 +132,10 @@ void DesktopLOKTest::callbackImpl(int nType, const char* pPayload) + std::stringstream aStream(pPayload); + boost::property_tree::read_json(aStream, aTree); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("searchResultSelection")) +- m_aSearchResultSelection.push_back(rValue.second.data().c_str()); ++ { ++ m_aSearchResultSelection.push_back(rValue.second.get("rectangles").c_str()); ++ m_aSearchResultPart.push_back(std::atoi(rValue.second.get("part").c_str())); ++ } + } + break; + } +@@ -269,6 +273,8 @@ void DesktopLOKTest::testSearchCalc() + CPPUNIT_ASSERT_EQUAL(static_cast(2), aSelections.size()); + // Make sure that we get exactly as many rectangle lists as matches. + CPPUNIT_ASSERT_EQUAL(static_cast(2), m_aSearchResultSelection.size()); ++ // Result is on the first sheet. ++ CPPUNIT_ASSERT_EQUAL(0, m_aSearchResultPart[0]); + + closeDoc(); + comphelper::LibreOfficeKit::setActive(false); +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 0da87699b1b5..459da5d196f4 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -165,14 +165,20 @@ typedef enum + * { + * "searchString": "...", + * "searchResultSelection": [ +- * "...", +- * "..." ++ * { ++ * "part": "...", ++ * "rectangles": "..." ++ * }, ++ * { ++ * "part": "...", ++ * "rectangles": "..." ++ * } + * ] + * } + * + * - searchString is the search query +- * - searchResultSelection is an array of rectangle list, in +- * LOK_CALLBACK_TEXT_SELECTION format. ++ * - searchResultSelection is an array of part-number and rectangle list ++ * pairs, in LOK_CALLBACK_SET_PART / LOK_CALLBACK_TEXT_SELECTION format. + */ + LOK_CALLBACK_SEARCH_RESULT_SELECTION + } +diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx +index 2be84a4c8e39..95fd13a1bf93 100644 +--- a/sc/source/ui/view/viewfun2.cxx ++++ b/sc/source/ui/view/viewfun2.cxx +@@ -1866,7 +1866,8 @@ bool ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem, + for (const Rectangle& rLogicRect : aLogicRects) + { + boost::property_tree::ptree aSelection; +- aSelection.put("", rLogicRect.toString().getStr()); ++ aSelection.put("part", OString::number(nTab).getStr()); ++ aSelection.put("rectangles", rLogicRect.toString().getStr()); + aSelections.push_back(std::make_pair("", aSelection)); + } + aTree.add_child("searchResultSelection", aSelections); +diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx +index f35449b12b2c..62ad1cdcad7e 100644 +--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx ++++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx +@@ -80,6 +80,7 @@ private: + bool m_bFound; + sal_Int32 m_nPart; + std::vector m_aSearchResultSelection; ++ std::vector m_aSearchResultPart; + #endif + }; + +@@ -187,11 +188,15 @@ void SdTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + case LOK_CALLBACK_SEARCH_RESULT_SELECTION: + { + m_aSearchResultSelection.clear(); ++ m_aSearchResultPart.clear(); + boost::property_tree::ptree aTree; + std::stringstream aStream(pPayload); + boost::property_tree::read_json(aStream, aTree); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("searchResultSelection")) +- m_aSearchResultSelection.push_back(rValue.second.data().c_str()); ++ { ++ m_aSearchResultSelection.push_back(rValue.second.get("rectangles").c_str()); ++ m_aSearchResultPart.push_back(std::atoi(rValue.second.get("part").c_str())); ++ } + } + break; + } +@@ -401,6 +406,8 @@ void SdTiledRenderingTest::testSearch() + CPPUNIT_ASSERT_EQUAL(true, m_bFound); + // This was 0; should be 1 match for "find". + CPPUNIT_ASSERT_EQUAL(static_cast(1), m_aSearchResultSelection.size()); ++ // Result is on the second slide. ++ CPPUNIT_ASSERT_EQUAL(1, m_aSearchResultPart[0]); + + // This should trigger the not-found callback. + Application::EnableHeadlessMode(false); +diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx +index 22db187ab7c8..51635d5cba14 100644 +--- a/sd/source/ui/view/Outliner.cxx ++++ b/sd/source/ui/view/Outliner.cxx +@@ -643,7 +643,8 @@ bool Outliner::SearchAndReplaceAll() + for (const SearchSelection& rSelection : aSelections) + { + boost::property_tree::ptree aChild; +- aChild.put("", rSelection.m_aRectangles.getStr()); ++ aChild.put("part", OString::number(rSelection.m_nPage).getStr()); ++ aChild.put("rectangles", rSelection.m_aRectangles.getStr()); + aChildren.push_back(std::make_pair("", aChild)); + } + aTree.add_child("searchResultSelection", aChildren); +@@ -770,7 +771,8 @@ bool Outliner::SearchAndReplaceOnce(std::vector* pSelections) + + boost::property_tree::ptree aChildren; + boost::property_tree::ptree aChild; +- aChild.put("", sRectangles.getStr()); ++ aChild.put("part", OString::number(maCurrentPosition.mnPageIndex).getStr()); ++ aChild.put("rectangles", sRectangles.getStr()); + aChildren.push_back(std::make_pair("", aChild)); + aTree.add_child("searchResultSelection", aChildren); + +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index 5e2b30ab7fde..4598c50e5842 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -72,6 +72,7 @@ private: + OString m_aTextSelection; + bool m_bFound; + std::vector m_aSearchResultSelection; ++ std::vector m_aSearchResultPart; + }; + + SwTiledRenderingTest::SwTiledRenderingTest() +@@ -138,7 +139,10 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + std::stringstream aStream(pPayload); + boost::property_tree::read_json(aStream, aTree); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("searchResultSelection")) +- m_aSearchResultSelection.push_back(rValue.second.data().c_str()); ++ { ++ m_aSearchResultSelection.push_back(rValue.second.get("rectangles").c_str()); ++ m_aSearchResultPart.push_back(std::atoi(rValue.second.get("part").c_str())); ++ } + } + break; + } +@@ -477,6 +481,8 @@ void SwTiledRenderingTest::testSearchAll() + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + // This was 0; should be 2 results in the body text. + CPPUNIT_ASSERT_EQUAL(static_cast(2), m_aSearchResultSelection.size()); ++ // Writer documents are always a single part. ++ CPPUNIT_ASSERT_EQUAL(0, m_aSearchResultPart[0]); + + comphelper::LibreOfficeKit::setActive(false); + #endif +diff --git a/sw/source/uibase/uiview/viewsrch.cxx b/sw/source/uibase/uiview/viewsrch.cxx +index 7f1addcc3f6b..53485eb9361b 100644 +--- a/sw/source/uibase/uiview/viewsrch.cxx ++++ b/sw/source/uibase/uiview/viewsrch.cxx +@@ -95,7 +95,8 @@ static void lcl_addContainerToJson(boost::property_tree::ptree& rTree, const OSt + for (const OString& rMatch : rMatches) + { + boost::property_tree::ptree aChild; +- aChild.put("", rMatch.getStr()); ++ aChild.put("part", "0"); ++ aChild.put("rectangles", rMatch.getStr()); + aChildren.push_back(std::make_pair("", aChild)); + } + +-- +2.12.0 + diff --git a/SOURCES/0209-lok-Document-paintTile-fix-non-rectangular-tiles-wrt.patch b/SOURCES/0209-lok-Document-paintTile-fix-non-rectangular-tiles-wrt.patch new file mode 100644 index 0000000..66ba62d --- /dev/null +++ b/SOURCES/0209-lok-Document-paintTile-fix-non-rectangular-tiles-wrt.patch @@ -0,0 +1,78 @@ +From e14efbfe1829ea54b5b794903282d3bf834e7e83 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 15 Oct 2015 09:41:52 +0200 +Subject: [PATCH 209/398] lok::Document::paintTile: fix non-rectangular tiles + wrt. transparency + +When copying the alpha channel, the offset was incorrect when canvas +width/height did not equal. + +Change-Id: If0ab3ec7a4ad4dd958419b566fd473732965cfda +(cherry picked from commit d30f5bc3e65463f28c3087acad6f88e12d60e53b) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 21 +++++++++++++++++++++ + desktop/source/lib/init.cxx | 2 +- + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 30d8ae7adaf0..c3cc748a5d61 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -61,6 +61,7 @@ public: + void testGetFilterTypes(); + void testGetPartPageRectangles(); + void testSearchCalc(); ++ void testPaintTile(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -69,6 +70,7 @@ public: + CPPUNIT_TEST(testGetFilterTypes); + CPPUNIT_TEST(testGetPartPageRectangles); + CPPUNIT_TEST(testSearchCalc); ++ CPPUNIT_TEST(testPaintTile); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -280,6 +282,25 @@ void DesktopLOKTest::testSearchCalc() + comphelper::LibreOfficeKit::setActive(false); + } + ++void DesktopLOKTest::testPaintTile() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ int nCanvasWidth = 100; ++ int nCanvasHeight = 300; ++ std::vector aBuffer(nCanvasWidth * nCanvasHeight * 4); ++ int nTilePosX = 0; ++ int nTilePosY = 0; ++ int nTileWidth = 1000; ++ int nTileHeight = 3000; ++ ++ // This used to crash: painTile() implementation did not handle ++ // nCanvasWidth != nCanvasHeight correctly, as usually both are just always ++ // 256. ++ pDocument->pClass->paintTile(pDocument, aBuffer.data(), nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight); ++ ++ closeDoc(); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index b69e58a4af1f..053ab440bf55 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -788,7 +788,7 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + { + for (int nCol = 0; nCol < nCanvasWidth; ++nCol) + { +- const int nOffset = (nCanvasHeight * nRow) + nCol; ++ const int nOffset = (nCanvasWidth * nRow) + nCol; + // VCL's transparent is 0, RGBA's transparent is 0xff. + pBuffer[nOffset * 4 +3] = 0xff - aAlpha[nOffset]; + } +-- +2.12.0 + diff --git a/SOURCES/0210-sd-tiled-rendering-let-find-all-at-least-select-the-.patch b/SOURCES/0210-sd-tiled-rendering-let-find-all-at-least-select-the-.patch new file mode 100644 index 0000000..a278b3a --- /dev/null +++ b/SOURCES/0210-sd-tiled-rendering-let-find-all-at-least-select-the-.patch @@ -0,0 +1,311 @@ +From a264af1921169c7e1174a8c0d0e3dfb069ac3132 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 15 Oct 2015 15:20:23 +0200 +Subject: [PATCH 210/398] sd tiled rendering: let find-all at least select the + first match physically + +The LOK API can describe a multi-selection, so find-all can signal all +matches, editeng can have a single selection only. Instead of having no +selections after a find-all, select the first match, so e.g. copy works. + +Change-Id: I0eab2565916f0c3cce5d77279c0d927ad4b7054c +(cherry picked from commit cd4976988cf3acb4f1a23f1df7fcc2bfec0f3da0) +--- + sd/qa/unit/tiledrendering/data/search-all.odp | Bin 0 -> 10744 bytes + sd/qa/unit/tiledrendering/tiledrendering.cxx | 19 +++++++++++++++++-- + sd/source/ui/view/Outliner.cxx | 13 ++++++++++++- + 3 files changed, 29 insertions(+), 3 deletions(-) + create mode 100644 sd/qa/unit/tiledrendering/data/search-all.odp + +diff --git a/sd/qa/unit/tiledrendering/data/search-all.odp b/sd/qa/unit/tiledrendering/data/search-all.odp +new file mode 100644 +index 0000000000000000000000000000000000000000..cb3cb31cf5c7d5d4025a0025871ad1314c598cdf +GIT binary patch +literal 10744 +zcmb7K1wb50mmb`PKyY^n?j%469%OLW1a}`G1P`vk-91>a;O@bl;2PY+AVCkZx0mex +z*}c0r(^b`7^}g=1ue<6!c@PXN765<<0C-u*iF42te_#Os01wCgC4iNgm65|+TO&PN +zTT3$oJqI%zYZfPKLuMO2uo;-y#@5K%(8j>g%E;P*+1B0&d>{WPBmWmrx10Kza99A~ +z;lR5GRW^0B(zn(#vjnp^{F!97wKfTomla1vCP2O~f+{H?st5o;-6sL9h%oozJco?( +zePk>ztt{QTP5+QGpA1OmCey}iHB +z-QAsBnZpbK0P|H+R7lx*c7J{*E{hk>Ur!7UW80=Dz0=aMZv*% +zbk5i8TS871$5sgU2>&6iceQ@|I8Zw~nvf(pgtDpX)Y$UGd6@C)O1>NpO7^M+d|m6y +zaCiyj4`_NM{#UXDa%QDb4u^hGq@O&Kx2X+vU5rZz?(Ot?zHascaw878li+fYtNy>rCf! +zMTo@BLK=PdIcx&jL3_aTLJUZd(4-qGVSJJY1I1fB_|zz;tQO_w8cZNs?(s`EEfu^sEAn-(S|T~6PkAq?n+Q>q +zIiJ>HRTXjEpaV$#AKLj|ybd3Fgb+@b9tZ$HpdNZ80Xh1f4B#by><;%q=YdCx;JNikW`kHWg%e~=g=BH|Bb{1xB_ +zGa5PQF*{pXhAGR0C$pkAovV>mtFdlSLWPvY7v`5}7HAaId@h%nYS5*equOpMWs8WS +zDWs51duy}tb|dlI_j&HcNV>t?=?m6Sw{Rp1I^2M;yZRe~ueadSf*8j^BoXDPW}|jk +zCXVS!<;>B9*^4F&3H?DXj9McCd~d^^PH7gF+ZVN!*X7pq^SHWqlF|LOBTZH +zGXO3B`z)-`P5ctA#pknjt?;7Nsrz*{AB}_IY)F|nbZwMLv2q8Sa@7Zs%9MKG5yXdN +zyS>PIecdkRxp>p3)}XS(l+hsDo5}h4h@QEE +zs&BWL`3#-LLiGzi2m^VSAR6oA6kE=xw28ZYE$<>fA6J3I9W;3m0%D`oJNm=>0hR>| +z0Q~bHxgY8Pu#tm=FUg_txeskX|c>7d&tUPJ^gDI*~W?ohmz*CcjI +zgl8k#T>&RsZIg1f$dpg7yiEN0q1cv!+y~2Qj1fJZCB}#2-^w-a3O#6Cf@FgLJV4N2Ec|l#PuVim6xwwh5ET4lDnl!_sxeu>+ +zUe{FUNL%k~fu$_4hdmElxE8t(>QB8g*K)(h!Ec1bWO1<&)EI`7Go?~8J?IyAP +z$R#5sE2|;;coirZ0fJfb#zl53GSIs4_TX9EMW&qHc)z?jj{a((YPbe|<@tL7nl0(X +zlvWsKWWQB2c<-x>s|*s`I1fa8uuucT87#cNH?q=h9wy&H=w^d&vqB8GB2vv5|HB7UJD>H=I=wpNLrpRIeFW)B_b%W8C +zC54631R)iQ9&Cxw%2J0oqSHBso*GX*;-x-~o|5+*uRvfXtM=-uwEoABnOu;9PDumX +znxuOloguo?p{dP5&%L5e^@l(a4BYbPcKJwj>0L1m<~rd8f6s<@>;f{pSbS|SfK%G?IGm)@tOYu15{k$&2y4X+N7$}2o!V^tOxhvo3Mio(RKQ;R1W0j?69hD+O^^3(sVhrrW#7G( +zx$yD1dqinbmAmBWq%9Ysa*t{pMG#<7`Lu>y?C!H5+<`%2qQ;( +z739s(@NTFlkwoG!Qt^>1SFaO=85PCnA+@z1)+T&u?8k+0#A{sAFo3Makhd7i*sXhoBIbpLRjvg +z#~5xXkXA$i~{$kXFz!rmqsucv66(Zf-(hP_mFeZ=0q5j964iUezI(Y2`~GlJ!&# +zt(+FSKb#|IJK}~Lj+&RBdkLZmvOs@UBv0o@QPDpjmT1p#K8%bR3YB2mRPDT*&kl12 +ze2x41tTvwbU43Z7*({PA8nPs+OC0Jo8-xx+sTj>4-B({+*+WZ?@<6hdaLLWC#{FsG +z>C*?Yjjw6*=YRtMbg2K0Y#+Wu4Q#9(9u^`$xOUKbjT^oBoDRq|n@k0&_#zNiIh|#y +zK!(D|t&yRonPuoir$AOPeE@ld^Asnyp;MOnH*gyQ8@N6#9-WZ3snpoq2~JiNQOK;Cq+jC)s< +z3O~21DK?$AS!x|Yv@CN+LMk$%;j=Qv*92qxNj>8WW$P2FepXSf8m6RiE1DkcPYvB^*<7pIDIFQ;0l)9}dJMc0aJ4 +z)a`YSutvUMigCR&gB2N4q*pjZygeq}==7%M@R{n`hY0D(;*qIc&Q0Yz>urMdSCtyMMvjy< +z;27PaI8KCpqOnICQMzpAI!s@lTu0f)Drb%%W@#bzqI`gJXRW@42~bS&6Bqr8wZD=z +zoKyci{hjIl4#+9=!xoJ2R8KXPSyT4vM8+1;>)X?d!m1fvtR~$V&-M#nQaDh%LNmFZ +z!JAX7ByHJNFIY7Z-)I4rX?B6du}=l}RIj#Qb6W=LO}7h0rf-v%Jm$I4ua=gCmnG|k +zhoGcvUsxr)%34*B(EgD1WQxVS02=uts`7#<9SmAa&}sPOUAm +z1X>8eR8(4+NiBhhZF-BO +zKaHB9sYf(WrnEcaP}({wvqtScPtwEq%i8A46UenWP{x{5j^*R$5vvU|8#k`tyt`6S +zD`~YiRyF5P*-7e^rb})KI(;{(&7(y$wT*LXO{i`iRa)T*sUaTcBiVEqBN}Q8l{1qL +z^(H6Tq9QDV$QnpZo=0ijs<~nVdc{oE)*q8KQGKbEYhHa+ZpKqt{FeW|M&2rgWRE-F +z#Ww$dIr`F~^!al%C8vu@oSRLkDkVg*dK`?tdk57m}k9C +z{D8}r|H7l>SjNP4_A;pQh{k>DDU(xA0oMCr|Iv;UPykttfh$O}rYT>)zb4f7(|Vr7 +z7kml`UJ@`6mcefSG_`jC=+~O)3QyP?TWUj%z`s*Ne#j|ydDBO{v$%|XaBBQs +z;6%2z#`4A@q}6x3ofRqYL#J%P>t>sTkO-nQ +z<8&z0M=|wUAgw19%tmUy+J3u+nx>0Kz9#^5R3Utnaj1*?y(nNMe%MpZxFdb>Zk_lQ +zb0o|rvr{$UR*w|cAwM3fgn>ZPNngMUH)In}^hwf{E==~@y#YIb`=}|i((p{SGtzFc +z8Tch*&HEMb{3o{D!78|r4LRdZdyA*A4S8X7Ol`{6&7CrY0^(^Eoxwg&p#n#taED30 +zwY&g+u_GD~&t9<3Kaj=_D2lY6I}4o51M<=7l%ev!T<4|S61pri%_+K+7_rs`CVdk( +zGm5+3H-_ry9`VA%ddY>TCn^zGtIU$@NLACj{bjtc+=;)0Ue{@g%(B=d^jRr=-ki3I +zw3>AT)N#GOn@P5~V(;zw1^IZ9?Knguh8rOkGb^J!Aw|FU<)RBB0 +z{dR<;LvxZoA!4m4ID(l*fnD&4Ff>*shb$cr@zI9jZpxQniu;#V^KeVJX{xY^=;}%I +zrUVLQ&CG-XG_83GB4)8@y2su*#J~a`lag0EDA8Ps%{5b7J8@9g>ON%Ny6(V!{ +zph+1Gy?i@J)9zqgTxBC6=7j6})tia^NHLKMY=4-uL(#T&^uuSK6R+>Q(@Fhj1qtzH +zTPK`(?4F17(w$(X;(SEi*P^LLiPznw26?ubQ>@X$wh{1%2qj;uLa!$2;!#$pWZa0` +z1-1yYzi~+@e$>KI(u=1qGV~SW?JG?VuDx85J#f$_-&m|SO!Fg1xv-~+G#nZ1o?e}J +zIsMKIR#})G7NDL_h`BQb%ejr0I6`-q?>G*hZ#OvLZE-Z?O$7X!=JKyxo)fxnGq( +zdViWjq&M_gSxs#xNh8A#&`K~U?8C&!(Qx-|j&$ij)>qwt@~nbmP=s|?U5=<@dej@? +z`CWNSjl3Uyc@xM%nL&&Kz3A?3^9@$v+=|ION<1jItqfRGYbs$DOfOXBS4mJf=9Q38(M^8ozkTVC +zN2eL7a0e#rGOaVI#|6Z9Q)B5f#9%MrDH-Pk!@W1C-(x8{S!OqeCQ|h^t%@_h02IIL +zucrCzSg;E6Lq4v492&d%oZx$(yIF38d*0|>AWoUBZ$MU~68{K!;s9j>PBhcez)&BRX3hN1k^#ZwhS{X`_b9xe32Akf=u_ITX{1dMU)tJ$@vzbw2*C(m2&Fd^h*`O +z(pfL)x7;)P#UEPTa3d|rqlC+SKF5F4k!ogK$e`+CWGwS!$+H3U(f1BD9jy>nnqy3j9RzDChYX?)MB?J4?p{y5P0C!s~&QTapl7{BfwzD +zw_kZ7Z#MC=Q%DNB3vL^83=^h1>#d5q;)DsJYUkT$G4|9P!#UjH?_lLng3+9|o$}2~(>i8t{+Das3iS{abpRmp6pY1 +zte*s)TtRF|$M43Qx0Za1iX&!|Bih6imftl|yy3`j2f97aC_%`fyQ!Jqf@2Ed3yikQ +zc(LwiTi1GUo0Kxeavasw>nlxFlA9$2q4tj5d>kMB(fsWo+U_^0&2v91Q{51-tB~lLxzRTqeVUmMz7WpYw#C~I=x{!+d#1x= +zHq)zZ4U7Zzl<&_G_|Uu@O1HflCL%V$FLP8Y2PH#&*-pkLu4_b8bCBvhZyPinU4Fa +zM5p^3Q9GBr_LB>=(KPSA+KCa>p*3i8@97h`Pp|9i;XZOAbt-^fE%DVs?s2ax1D)cl +zNKRyj4Oa~v)k#KFM~pEbV1pPc<>&TdU~)y3D+xP8;{p>mDUBz|RW%bm-S3n;i>=W) +zv?x>^U(7?73rkdU+v)%}(}JgK2|J790#&G68=*UC7Rb0g_yT1bge<=~p(i`~Ohfj` +zjNkZ7@1c_6SmEXdb)=H|r%F2rq*Ze$uITe-xro*cKRh7^5Z|h +z7^LdS-&e$=(K5qPa_bV~3VKmHboxa4i20TN&T#YC!DVIX?Ou_r%RrF>#H{ +zCm>Rz?QF)U!SX+1_n6%93W!47+{+K)6%Ob|bV#WXg(#GllEoGMyq8aU`$Z*-g}VA*c=j@3Aw|+8)0mt0rLM1qt}I8SOXq1{!GuerSnNHnB=|~y!9|VM!A0g_ +z32JlI95gcyEetbRWuN9>z>;B7x|XFu*HP+O3wnZOW6qFdp3s|HvU!{ly$!1QIM7Ls +zZn$1Z_yvBIK$-|z$T?~IKFLY*^7L$CY!Nc7X#vL68{FtNPAE(btBdGU?wN&P8RimI +z7p|lxR=#|`MI%&AUY6~H#!4fw?T!XPX?agU-?{UV2ofGXTjra`JYL2-T(+J`A +z=h^X5jBM}2Bg({sN(X2OBNT;kI}PLCP3Pv8d^~W`_WRP%Sq>>wy4;+WVOMSnvd)*4 +z=Gr$K3L=ibbU9}siLU?lJS6!h!~heEE6a%Y?J-4@)+lCwg_geEL5OQjh?r~Bv-8+S +zkb#{Q=u(}N>hUoFNr*}BmpoO`M|}*H;pLxP;*X9E6vnBI`K7a6RXQe2r8O6@T=64A +zkah6VY1pK;8fu>C9J`O;5{#&YDjcJZL~~{=FhSz6$}ZYBuw$2JStqHX`8{fzmz+Hq+fPbkFr!>bvd<6AK=c_1jzr0Z}b~p +zTb_sP-w(9cmY}+`*j{zXE_hM4D+n2j(Xkuap4sDlwyQyr8@I$Eu*(yX_0zGMJA#ow +zktHd`fMs<3Qh$o?QREfVIascAb(BgH +z-^S7oPm~wD-s?3)(+w~6zgQV(0lKan2TZewWL;5Lw<`9H!G>znAojDHcI5MvqtF!< +zn#obUH*jUXLv#VW5kx +zDzQGEExx%TZM+b_9VS&h4u|Fq${CIuqKx&5`u~iEfr|mXN5>*cTXX*GF&;0fooLO +z-CQl$s({-QH&=SkHw1(@RB6R$XWe-XtTg=;$5kXMRHKqAv%Me#4~O<<%Fvd=I-0w7 +zaAL;64fs@xSdKO<(n5eOv>_Q!wzGH=c2wdEP-aro%PE9I^u65K+mqQaz3=snuHvQ1 +zh5U)wN3>Ty1$)~vj&VyYJ1_UI-O4Hi`rdqNI>&L7Q!yxvuiZJGh`<(~?5Qq(nrEuo +z{kFYJ%(n7MK%1SJSj060Pwo*-xk%h_ls%~8*5`T6G!_WP9b1+7Ci$4BTJ+EQyY60 +z14n!N|K6^Jxi_OBJQ!60&=0}A{MCWvk86K~1ozS3VI6F2EN%6yjVxLIe|q41Zxu(d +zzMlQR=n?(qezx{DCimVh|BL2>tIO}6^xyAC`Wr1XD?Jk2ML1%GEe$G)$ijF_?zlcelR7Ark#Gh-w0 +zk4^g$B_Zn$GW5nxY@9bD$x43uo9G2B5~PC1vqIi*Z5Y%oEY&g7DzSwM?)ve>#{N3f +z`z%AMCV{=qmeUNLde|9fsco5hq&?@CVf%A~Lv)<{R8ch<^qZ^;$?Y^IpruAbfpOEK`iK7S&Z(pB)zy!JWl=H1B{r-OQWdy#U^u1y +zbi-7Ybyq`)(}5?sawHTv6|#6VX~*`@jn0Gmrm41YzIk=Puyhwdb*g(xbwSa+O8V{< +zyDY5FC?J;P^+Ec1iEJ_d*!1Ki>iA^)r4t&7E63MoG6Gh9V+4#b6XKcR(3aQho|>L+ +z6?AK+?@T&Qqx7(rf=KT^-9SIg3ga4%HjH~?^Xk15lspIu8Vm5x-dgu9`-}YPyY+Xi +zzq@1oR8hH4{*!aopD2HJ>90ocA5-^#UF9yWeu}{TX5!x`_CGM& +zpP+yG*Zl+m03IgmPl@{t=&!u?*Pj2W_jjD3-{AbpbN`IskJ<4x+RUY)P0}cS7-~YJpT~> + #include + #include ++#include + + #include + #include +@@ -51,6 +52,7 @@ public: + void testSetGraphicSelection(); + void testResetSelection(); + void testSearch(); ++ void testSearchAll(); + #endif + + CPPUNIT_TEST_SUITE(SdTiledRenderingTest); +@@ -63,6 +65,7 @@ public: + CPPUNIT_TEST(testSetGraphicSelection); + CPPUNIT_TEST(testResetSelection); + CPPUNIT_TEST(testSearch); ++ CPPUNIT_TEST(testSearchAll); + #endif + CPPUNIT_TEST_SUITE_END(); + +@@ -371,12 +374,13 @@ void SdTiledRenderingTest::testResetSelection() + CPPUNIT_ASSERT(!pView->GetTextEditObject()); + } + +-static void lcl_search(const OUString& rKey) ++static void lcl_search(const OUString& rKey, bool bFindAll = false) + { + uno::Sequence aPropertyValues(comphelper::InitPropertySequence( + { + {"SearchItem.SearchString", uno::makeAny(rKey)}, +- {"SearchItem.Backward", uno::makeAny(false)} ++ {"SearchItem.Backward", uno::makeAny(false)}, ++ {"SearchItem.Command", uno::makeAny(static_cast(bFindAll ? SvxSearchCmd::FIND_ALL : SvxSearchCmd::FIND))}, + })); + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + } +@@ -415,6 +419,17 @@ void SdTiledRenderingTest::testSearch() + CPPUNIT_ASSERT_EQUAL(false, m_bFound); + } + ++void SdTiledRenderingTest::testSearchAll() ++{ ++ SdXImpressDocument* pXImpressDocument = createDoc("search-all.odp"); ++ ++ lcl_search("match", /*bFindAll=*/true); ++ ++ OString aUsedFormat; ++ // This was empty: find-all did not highlight the first match. ++ CPPUNIT_ASSERT_EQUAL(OString("match"), pXImpressDocument->getTextSelection("text/plain;charset=utf-8", aUsedFormat)); ++} ++ + #endif + + CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest); +diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx +index 51635d5cba14..c9ab51dcc7f7 100644 +--- a/sd/source/ui/view/Outliner.cxx ++++ b/sd/source/ui/view/Outliner.cxx +@@ -594,6 +594,7 @@ void Outliner::Initialize (bool bDirectionIsForward) + + bool Outliner::SearchAndReplaceAll() + { ++ bool bRet = true; + // Save the current position to be restored after having replaced all + // matches. + RememberStartPosition (); +@@ -631,6 +632,16 @@ bool Outliner::SearchAndReplaceAll() + do + { + bFoundMatch = ! SearchAndReplaceOnce(&aSelections); ++ if (mpSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL && pViewShell->GetDoc()->isTiledRendering() && bFoundMatch && aSelections.size() == 1) ++ { ++ // Without this, RememberStartPosition() will think it already has a remembered position. ++ mnStartPageIndex = (sal_uInt16)-1; ++ ++ RememberStartPosition(); ++ ++ // So when RestoreStartPosition() restores the first match, then spellchecker doesn't kill the selection. ++ bRet = false; ++ } + } + while (bFoundMatch); + +@@ -659,7 +670,7 @@ bool Outliner::SearchAndReplaceAll() + RestoreStartPosition (); + mnStartPageIndex = (sal_uInt16)-1; + +- return true; ++ return bRet; + } + + bool Outliner::SearchAndReplaceOnce(std::vector* pSelections) +-- +2.12.0 + diff --git a/SOURCES/0211-sd-tiled-rendering-implement-CALLBACK_SET_PART-for-f.patch b/SOURCES/0211-sd-tiled-rendering-implement-CALLBACK_SET_PART-for-f.patch new file mode 100644 index 0000000..3060ec2 --- /dev/null +++ b/SOURCES/0211-sd-tiled-rendering-implement-CALLBACK_SET_PART-for-f.patch @@ -0,0 +1,411 @@ +From d9016396c76490706b92ad8f30080ae1995a00da Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 15 Oct 2015 16:56:14 +0200 +Subject: [PATCH 211/398] sd tiled rendering: implement CALLBACK_SET_PART for + find-all + +Change-Id: I607b3719e0f508f9ae24db7482323847aa8e2491 +(cherry picked from commit 6a35a75a6bb2753f40edf59f360130e452b3c7f0) +--- + sd/qa/unit/tiledrendering/data/search-all.odp | Bin 10744 -> 10938 bytes + sd/qa/unit/tiledrendering/tiledrendering.cxx | 7 +++++++ + sd/source/ui/view/Outliner.cxx | 8 ++++++++ + 3 files changed, 15 insertions(+) + +diff --git a/sd/qa/unit/tiledrendering/data/search-all.odp b/sd/qa/unit/tiledrendering/data/search-all.odp +index cb3cb31cf5c7d5d4025a0025871ad1314c598cdf..0fd069ce6c0b4201c37a6678b6b1cd9875872c8f 100644 +GIT binary patch +delta 9300 +zcmZ8H1ymi$vKM!UAi>?;U4y%OaCZ+f1PQJew*%!n3y;?ID~|RBqb%4l$10zH4P07EiEnW?d?50JOTm&LPJAiVq#KK +zQnItN3kwU&%ggKQ>pMC+`uh6D#>Qr6XP1|kH#awrj*iaH&mSKjK_Jl6)06m|GXn?& +zD<&^3q2>GiaB1JWoDmo9ZJayRDK?v}7Ovj$QyKzylzg`L)dFE$ZtN-r;|Tgk9BPgN +zF%wGgPgs25K172DApS&;fwVptgKo$b%j=kK=6P2|BQow#-n+R?1w9_ctoNo!#V;*( +zKdnAIOEW1KK5Ik4+D(yn6M`9`B)%!+GHHF<3E}lp6vo>8O6(s)>*b+^GnZq(WgCT& +z8O+-n_W6p=A~t@DRX?GuCbQ5l>J`9BL3qoGkqH78sB4Ko$IYmD_RkkS7Tnp9XKf9` +zf`$Sy>BY9Fcd9+{92$-N+MJiUl_HW%ctP0Oay=9gJ?mU5b|n@76MJ;=;^d9C$QO!R +zI)7yl-i*zr=eT@gsbVU#R!!FiocdtRDu +zK;Kf2O9#-E07X@abNSaF4@$G`m4`yOS5m~bZJ}Ke62_}eQc|_m;haG +z`-7Iv8qQlwlvWKVP~i*|`T1%tgtn5^!Em`e^FHqqBvo>AIm3Ta8g(wcAzc5x6HT0e +zM8;iz|K?qOt`#edHmbQ+T++{<*2Y=t@yetsC_L<3XZa$Ttgj~z&|Rwr9objh9Trc< +zuumR{*9&Y9iI6(s@(kaIqFSq`8UZ%%tBU(xLnxM>gy$tj>GIg$%;5etf}q#KTIy +z?i)}V$y8{aW$9jJXP{Kd?At*w_0V7y_3PIkqs>%C@?^;(|&JfgUvS)X;m<~1c7lbw|gd!e7nAt;nS>}Zlg7Q*e42`UK0le*Ig+i`np +zi}%xeC){}J?sZBFLSQ+HkXmPh=6~KVe*wA)Gxjs_mLc|er-CwI691;jq2xf$p>ofn +zU;z*k2n0M65O(a~WpeD`7e!Ey;EVWKDv$Y$yHF{hUbq+ddn!dU>Swx#_%CfeWGX07 +zkJF3h|3XhX1#>tDY$E7I4+NTjHV9&WX8(B+xo}rWEvGk9~+S(yd +zKcl_Swl0J3Dq&KF-V_aHM!0zclKb)(M`%_1KksR?6f-v$QWu*cKg( +zQ?UD|e2><((*U09w)PRs+O9zVG9Exw0Q +zQ$#={--D+-eO|N$&&&Dm(+d$1@%i)uD2bU+qLe4S$3Q9cmO}m`=lh(bclSc&s +zI;i2cKYIkwrpo0m@l`{XV|3NAf3`nxX);!{9|eet<$la9$Y@J7sN5QK(Up>d(vZT! +zLlKR4^_ZZoj0lh{87g3wb(xSIXtd=rYpv1qZ8Q?~Nq;hpOM|i+a?h-#!3b4zAgw>X +zjCLg=MzI(?s(4qrS9AH@z~5c(HLZphkj3P$mnm^3xRkS5jjfGI@LE8g^mQDXtmeEa +z{rJNCM$y;1pb1^Zuka19iC7;d_8DF^!pSf3h=Mg@l?|7y$b{n)ZlEs-K%jp%YMChJ0x4z8_(mN$~axr&{HP5)Z2Us#S +zkerZIW*23?IMazD?Oj>ckr|#?NW+H-eMK_Eu3Ptk`*SEV0n8p&CJ +zF^t=V$pJBXC2Rh8sEH1zAsqVztLhaVq{lr1y1@J1o}xr2`ZlS9YQ=`!&{5?T98oog +z(Zf(2`D}idZAD~%s}=XB9C`wBLttQeegQ*kYzpEB8I@^uY|k>TqKu~(ND$TEscDW= +zr8dfIZbYng%{rPE(?t_vfjK0{yQ%)XTX==~m;h-J`_ML&HnRp84M43~AP^oYj5{AB +zV8N(cws2J4)}!|?zjyy2`GaIEh6}dXnCKc_m}HUj`qI)7#dL~o(0}!95zyS)|M^Nd +zMAvJ7wo`&XW+MSfkgKocByvoW0?48$6di_&l+7t23$bFg_5PC6qqh4=a-eB8liGbWEvVxL5C-s##@ +zMTFT%iGKc0`klI>cIU^j*DAmkDXC6AgytGsU+tNOda<0fvD{q~@A9RhkZvP(VQR%4 +zTyt2t%_%J%Y9em_fM9;oqgfY9)n_u=|Fx;7YeBw*A}|=%D?rumh8){%F-Xy)6z_xM +zDYe83rp%v&E2pw^N!dZ%JkmRVBC_MP{VbzE*UeZ&SE;^+fa{xzha(`cC_GRu(l|5h +zQZvdzh)1v;OL{xFAoRUmWR~}uoZ<-2WNiJ>itfQuR4avhTKlUX8YoI~11V`-TD$u4 +zklPq1R=n8WV{;S8$)o67{4W`|q9=_kR>#PfUK1n`Et(N1sAisl;ge&DKq7-;HEFfF +zS$HM21bV+^cF0P@a0P(n+zPk`>Db(Fh${q?^}2WKYPRFZ?;-d_ggip3L1s61r$PlC +z_ar0Zykpm>APi@v +zQLMu&dIsuy?OG%XPjzhMoimeQa&%>DtndI3mPb*egu79n6i~ESdB`O}n93e>^7qV|ibe!Mz8qxi +zi4W?SxOlndiq|}pv1NycBQt5SW)kO~f|gy%`8c_v`UmeSQ+e2P(mff%nK{SCr8C`` +z5+;#xVkth`w(B?f?w4>%{ed=3H@);-C;3np+1_*%R)P>-1mD>J10V;IM0r(Uyul1R +z5Z4MaRHZtSZxQ+t;C2g#`yZ?LB-Ib+6BJ5|B|Qga@^H!r7jKKfvBHI$Dium +zqk;5e+B|2SmEAIWOMi~AeWrdqnhm^dJ{xq?2#a{aK4(N_y +z$~#|GG<&TDmt)!am3gXI*rGy58woeUxO^WY!lL<_cPhK^1dR^c1BR4193c{(XMjUUev!9Y!S}SA|^52OmFSzn#b2kLXnpJ>tMJ +zsz*UF=A3!VAaZdt{apyn*xjODzMDLjQu(-cwx=uM;DNL_dH;K>rM^VxH9z5{OG6bB +zjaP3D@eGleFwLnkzVvU%>V93?8;ww`Tp6MF3fQkIbBGqEU3o_yayuBW7JP__ptZ94 +z>Pk}t5T@@+T~pl8>#-`?B@zCFTL)`IiH94%bvAPgWuDl2~UdumD|bBpp(RsTI#D%Q(#Z43hf|2$M+RB +zosD`r0<|=ouV;iGUM{KY_{sXLOD?i@u7(;@ +z-)qmK?8$kD$l9b+ztl=UX_+v(R$D$R)EnLo!9%`=fLmb<4_S1`h(^1`4tAO)?6<%Q +zoH2XTEewJNad?EZC9a56{$vqjUV?aow{{W<1!G%q;zccsyvE^Yeja+k!E`{Ni_vKw +zAP8sEyXRV1`>s;#K=O|b +zaej^hyOu_PQgLf)xR%x)TcTLfx<}>(zGhv6>5ob!S=+l_0f~&qdFpYGq>Bv-S$DT +zGN{^(v6N8-c;k+8pTD2wYmydAYP~n;;H?@)h`R3gs55UUV8SPu4-vJqaIhSa0+JA! +z+)}mD=6(NkZf#~j=uXx@_J$6BtL*4gOWTMJ+qbawtNz> +zY;|&eb_@r1n?g`=`o^}x+4+GvYFst9>LlCnl-HJ>i!Vnst*LGSZ}FJH@?n4t1Dy_Y +zK$Y0I_wOSe-SaYCHv7A}sP``P?Z8FkQo+tPp-2`v1qWMpKz*Pc&&`(X`wwYkf;k#H +ztDRT;4GJuj=oZRu9v-Xy4&==Fq@PRKSwYs4l+>4kKJ`#?dofO3%|9AFlQ{nQUAJ~1IxIcWOi;F +ziO|w;HW;yIvrP0*Y_Xs8^68LGUj!2ohIjE=oz +z3;igftqcu;-L)nrWb@%;`MV)8YHW7FtzYA*4mQU#I}%IoXi;2qfE4GDxaE^86$5o49-^B>Fgeg5HcoOt(@K +zUI)1<&8g}VD~rQ-2J<}!72@CYCJEfswUwG%%QC8r77#|ttOINc5j2J$&rTQ?%7K$vnQ2SX_AO$$bnM`q4`Pj_W-G9sSkzs-lU*oNdgLg5ypsW;9uLleT2nZp +z{8`yB$@i*Sn_R7dzj@NKrsnC95Y;Sp7@Xv_sgQ#z!#31mrHE+=$z!%u($CE;SuIkp +zO*+RuK|(wUTb*eb%!Y`ut|Vf0{Ulw_`fJ! +z?1R(u-<>h7$r^2m6>pK8P@5|5PEBl~C7_9P#IwC~!~W@#IG#&NTi#Em`)$cCOrikA}ip&Jg*07J7G +zS;1ge!O-b*S=cy%r^SQh=!i^I<|oxMWibBsb8%12!WeLXbM`h-$#!_=5nB}O#XQC=`Pc1SYQlof{itmCu?-y-}U1|2d +zR8Une(Rz~uxK$ZNV^Uh=!hjv)(My(Pe~UrP*-V2)_@~-b;gHdi5IQ8pYzwx*Orj@S +z^;Fp()9QzA0rjB*?)^oxdxR(6R`0d~l?914Y^t#}gsEZGPUn2zr9Z$3nU@@1nimn> +zB?nXoid-@C=Q3;RISgwE75R;BHM>Nf?hMa8M0V5&&>uk~R$H64Q)b`%P-RF)|n3V=VY_30yN+lebF>HkCw9P$j5ip6Ca`TW!xkJI35)`kzAK1hRW +z&Xj_;N}y?76e6I4-F8sTc(zVy2JMJ1ZQGixa1E*m9&4f<_A33Qh=KRZ$s&V(QieM^ +zoGmpRki5)%^F(9N(}zVG9i!r<7-7koa9|*;QZc@ehX96RE1DcBa~cNzP=+5#9!EUg +z9d~nugNc$n4@SfP(h5FleZV^Gv{g?UzO^F<^Aa}<*G+0wQvgpwcZSE(hz6PTPX*dOhD +zu2(*P%=7w?=v5f>{RlIE`Fyr*o=|#YVe>QOm*)^~*|P5;Dt%(th_j76+*W&}CrXki +zu2AGJ%`Qa-(J@~7U5i(*^dwA77aGWxG(QlVzlTw2!`FO8Tks7kK45*bk{S!qJct~3 +z9RTr48tfrg +zTb~TGlrj1OUrT+Og=#oZD8flw(5fsrU(osO@vY?LB=V990<)+VVI!7XVzjuM{B6p4 +zPjKyL6Z|yXO@R;|H&S$n(eOAI3yV20lM9Q21bKkUOe^P$!?lRO%#*^xM*2?Kw^Vb_TXn +zT#JJak-kKhp3763BFL#&Qxb^@$L-vCh7NINLb$CTKE_^%p&nw4iar3ryMUeH`BPZ= +zJw+oQMQF^gDHyismGR&v4#bn-dD6tPbC=c`B$gPV$WXUWqMKf>0z*e*Gyc0_=xj)vN@`4ZJRt|6#&zRd&8KK^zj8I%NP-9HxzPS9kid~Q9kNJQ_@K+ +z<*AgKN#}~gTK>V1)6#?SS!)lbUnoh%{bmhh=o`O1+?ot#{(xKi2$)~RTP!c|z$?e* +zT-A{m`sF +zO@V{8kzq0Egs~d6GCC(|qb;4SCKi7EuHhUk#JL+gO}T)Q;n7T@7eQlxfOiOy`%& +z|Ju`wXj7yKv?5f%m!rvDu`RRo87Z25tqgm>n)$6uKHzz9uF=8m+d{Tt*?#qyw$DeU +zEcoOh9=G432kvV%F?Q!>>Gk2p{ELB$5cJ4qY;OjVE4)6|3mYvw^#oqg1;M`UVu|k> +z3f06~70lyOPW4jgDS(FhS7%Hv14?Vsgp5X%+R?sW`*#tP)?T3*OW3t-XFp#>rb^Zc +z!7OaL9_2^IwM&fKN9h?uk28ro&Y+oZG>0xWydI!+L8#T|i&XxBZtl$&`E?Cse)`TN +zlYixgLoe;=RN6t%?=m96Xdx6$wVl)ZZeRWOudC{}Qh7H(3h92iHg8oLp2a3#M{eix +z>@F4xR}B92T2;xKh4`FeYXX<4JPRKKFKkR7mKMqd?%pZCPZJ%Tk=4JYS0uA))d>3w +z?-nu#ra%(vjQAvWu1r3;iIBEIcH4)gr +zOf{$9dN_Z&B>S&z)$fH8T%E`tebGcXSt@E|$L-bV*B4S&Fm!{jYkA;~?fhi9EVP`2 +zangIcrj)0@aeg`Wgr4T{63&Z^_@(S5qlw1V*>J&6>d6_nJ0G682p>{m>=>1C6KRHXFl@O5x`%ts=u +zQV-`r>usn5fjz}Bom?A&-*0QIZozAX65Tlm^abJ-S>+s0_n*+1Y`v{q=eJ#&gbyqq +zki^y=gkMcER=lQqj>X7j0 +z<-XmEsGH8SRBDu1un2WU`P;)uNVR|tb{jcGJKq3nsFN4X_kPZ{mCcM)-QgMFa&<~- +zE_=s&Yd~u@?^VuXP$`>F^`M)7ay7ZAayQTt*W%hgwAJ-%%PcLm1JI2B^vcrV= +z`~H{OYQenMF^YyW+jSICa=%NnYreUdg$xve6u@xyp(4vZp!gylg|NTCfK|A?xSYUpO_kaKr5s?e7E*@ +zDT4#P$4onRFR5tmp~8r+Yt}*uaItF|c)Ku1{_Q`c?#D+j{jl5fYSD*szuSeQFHO^I +zO?O|syBCk}mlq<`{=yID?WT@bF^BtaKASo!9vgh4jf236M&exV%0H&$3i+;wix#kK +zb>Aexniij}092!DUajYcL-5?cT-(yVQSeJIE=wc@?SpA|Im)J+h>1_QFSLG2;%oZv +z{W(dIME3UH=`vQSKNujqRrJQ5OwQFP*3Y$UyxfKoUnAeHK}Hb(PwAiujV0ifY~ZAl +z#M{U>Xz)_%8)sNlWo{qpEoeDdn-pzl3i4jmUnpIIfXi$1NSCW1>qW&?7mM!5$RpiF +zXvM%WY#C%iCg#@#Xdkx*SRwOe#Ue=rbJV0uKj1ukgfWNi>&Mu!X-BWKHnu(MkY*Y3 +zdu+XlQA~!KpI*yCy>{cPxJ;yss8scZ%tOE+1EA! +zxVk|IH!zp+*&=Vk1de6WOr)~ykLU#I-tL?iUya6=%eKK-`8G*Fz&6eC&Bx=k5&!p< +z(ypNM!ZN&gy{n=a;qNjOD_OM2M+S2{bLB*VdIX2iMV!0ysbXJ;775DRjEO97;bqMd +zwQs&qDCcI*wqdCVeD*)3GWK?fd-!b9dlj7n=m8gcrBRIgn(aD{ij6mSn%d?z)m1qr +zu6ZLXQOnd#_8C?v%@z7A$ZeH-j)XI-Ip5ZNym{$J5dRdR4Rd+%k{rV<=?u-vTVyOx +zs&1fsRYibavCp$F`tqUJo&_`L0!Lfob1-P(HOBuvX`X%{n?U; +zGzJKy()mwP{`c=8e`e8S6q}0wWiW(F=mm9C +zal-%8pQF_NTS5uWp+f~vQ6m1s-cw@!N2%U|S{v#`+(yIw-~Xb3?`Q(oh;3(SHf3=$bU5!BbFC7##5Xi#C +z+0)9|^QHIv|0n;q$6ksR{|DhXf0r(-JpO&(zx??hRWJ(!CKMD{l!5N$4#Nc3h!+6#y|(}O#3p^{{UOc?Faw> + +delta 9125 +zcmZvC1yEc|u=e7%1cJM}I{|`2ki}gS+}%R3CAbDz+?`;-f;&NiySuxEMS}k1-goQ2 +z_tl%4Iy2M#O`mhRr+R9pyIJ#A9jF3=gU0~?kO2UH+c=;)y1%WmjL&29LJT|r5EEx7 +z3x2Lge(xVS__MAX#OEG#U%yu3m}LQ+yv3JMBpYHE6VdS+&3wzjseuCCtR-hqLE +zk&%%Q2qY~nEiW&xw6wIQrlz^Mxx2f2XlQ79dU|$IZd*=DT*GtmWO*SePmmzQSQ>#EYxk4F(|yMfX^+d-*;A2yO>ai_vWN%*M$ZSX +zeQ}SP3wtC8Cjt(*^SLqj1P|u$P!F1>j8rvSpP5*lx(qi}Un^9=P0dxeLTKc07lSCP +z@fE|EEaYB^NZGnF-t8rhdk>jLD8BqnTa~&0|cQ`d5dO8yCKiuISpbw*R +zx!SgJlIFkJC=6IRTfxMvMA^SSErR&yqj0=m?iu)ohdZtHTl4UW7(lRW<;XlYa+3*^ +zTb6&F&Z$(vx;0%rJ+)&kg7%`F|CY`%nE9Rb`^!_cR^09D^|{Tu#g&QB8;0BM2@4WYnJNS2d4R@iI&YRbqpD>aKB{mS>4HFhnH4D=;qDTL$2qI +zn(c@!pe1}<9{})NK(d4N7XkQ3!;Qb#-)QLv1|HSNHLD36NCMG@OC}h?(*29iE-9lRpBYU^oYvjw~PB!%?Np{|ETuh +z8BI#xRnMh)8%=n&#^{ha`I}P4h*!o5D_Kl^H}EMKr`@6RD+wSmV#_|5lxa5RFx*L+ +zgYQLDY~?_?ER9p0ol4z_%oHld!peffP;h>|BZ>;`(VCH(WN{Hwnr~SWEp{=)etP+S +zsDpV>fbGPZ;L+uL?=nK(K|NEdP|lS&s=dzmISb`yEwPwh6Ti1e$>nDFE{!wwCi_6W +zA!%{GEwQy`^IZeHr+F&UB$;8alh2q^mFke+8#tP)NxExiHwR++@MT|wA>V`YA#gmW +z4j@9vU#qpq-us{xjB##?QdQhNPxTgVIu5va1*6(Tm!psrvOd_qaM;t>_Mu+B?~xbA +znBJGVYn^DYg%2imiek8YUx1Jn?TW*;+D4ZZM9(*M=cBJl@Nq+>>3v5WkHVGU9c>#i +zng$Pl6HZ+j_ai2NJminsUkcd&?2lE55sa9C000!`k5y7oApigYqTFAAzaQiwDX3HM +zvVgzLnt~Jy09e7kK>xNY;MNFWnw-64@uXouZr~T4QYpEs>wCG)vb)3>?W=ikbPWEe +zJ9pRT*HN{m5LDj?^Dn`Ww+LjkouQ7;FmF^y^8wA2{ePHp(n?a_B#Z+7_A~ytQeEdf!TJWO;NASu}cjTS(RK`T%lK@Thj2eT5-0;h+ +zJe;UK!V3M>w~Nl5h*I^LCrysuEFusb$yvFL95u*s3P;)sbw*IC)cX;UWJZ;gpAylZ +zz~H4#m!$zjw5?u0-WEF@8O`QGr!MsV>$C`CYR#)?FpruyZDTsAz^Pdoq83frCb9)g +z6l{vUamXgG{3XZdiRPb>f|Nr8Zh84}VVf^`3K_)1NtZE!>V +zuLrM6{p^e%T(O)Wt-G;n1;)(*&pE~C;IOv0io%{M#7b}RlkY#ii@K6yAMT6cCRYf8 +z!&VUZ%%USR}Yx?;_KcFl)&|5V15JLrogxo6snd$6h&E&xY&;kEh +z5nqug!1}I4{5XDRmFLF=+yij$&nrSW%{cg~>3fP0ixt;;PGK}`-92b3I3KTs_3)BA +zCC=XqX5LYHcod%9(~xEo8~FI3^mK7EjHvQuE*j4W01k4;b_x#OzG_Ky-7`HZMk9%7 +zLP95RV*pq)5k=)v-uV}SR&-h&1moh-&C-rSz-BP}As0jh0R~F8r%FlY4)IUvM$@ajIrvJ}E&J>8m-joI*A%AKl}oSgPMl&NW!uq8fL+6030vOEM>JRaI4jilleq7tt9U{*pcJ5N6AjinyQ1UQhj& +z7itcH#(f)~E!-BoXb*#;L)rl=c-(yK6P^_tljPbFiimC#QiP$dte%~;+~YEw;FyLA +z84QJ`$-+;Ci`I2%?!4&+<|L{vWWs#KRSjRpcrr2#;*ohj>Yc8N?v2>#-EC8#-&cM; +z$i0DoiYaUq4Qc*SPkAQFv;{b;3WVjS-Q~XymGx)hUe?imOzl4R%E`#fYk^#B0>xrM +zaBBhhs6J(;`nLgo0;@-;)Qh`c!0W41nD2+{#u^Ye-hL6K+gC`<=!9cK4c@dy47ks^ +z&mnV4@nj_hDQtuKvh2~!WLSI+G`1Fm#lp)7|~g0jF~^Z&1))n`&>z&1o}q6 +zwYdbW4^*(8FMZmF(&V>2z_m+yvq9O+zqJJINv@U%3Vm19F`ejGQ(dV{0gG!=_2bG$ +z)mFMCkz6e?_cwrzN!JE-`zyY1zX!Rp+IQF2WevT4&FX~`enlSE)uu4;>KfUb5kq?k +zcIiERW(X99X!uFEus2Y)*Z7`wq|k#P;&(oxdoPe#Wc7oKBpRunx~I>+y|quPw=!?j +z@AX4Q_4N>iSfAV9x4%~I!@xnlvSEgqLD!Pe`F1u8Eviv2Vl!Qxd{Xv8j>cYrsVCd9623e&fWqldbgijc;saeL@HG +ze13+Ie2IKK9Bk?gCiPGU!j*F@XRt{`Z8V=zK(ow%HwreJeIyHaH@FV^adhk`3QQuK +zI)+ky?#(;kK_&N?}8C+)J#JFuPC4J^v>>GH|#IgRL#STu&Y*pOD7N4|13H`e7b%f!H8Fkm+y +z=SWvU)zE^eP9}$;1Wm`rlFGDVrFhvXPv;G(l(>qPTLkOITo{VOYy-WrK352WJLn+x +zkq?1ZP?&EGst2;gd{d^v7)(_&G%TI!!hAD^iX8=$V%1jfseM$;1$PbnfdApTF`4vp +zb5zUqB8oBwsvNpk68Zxtlo3n493uoX$V5iNPhXk(RIZVD&BwXHm%sFi|BrJ`Zs-c( +zMgRZ|X#xNBt@!Aq;1#_Qhb=zL_8UeZ>tZ?$sAf(yx^_O#N|geQg-*MnZX{0IErg={{Rd4Ed$t1a3A=m>2mZ612u;#hlKrDqxYA#M>AuySx +zUzfFxX9CowEkL!M^$Ks!NL_C;lZ2_fidFYJS$i#F`s8bwrQB{*w1TuvPGY83?CCFr +zRav{T@n7(S%z+Y#?5AITv-E +zsG#I+?`5z$qMlASZj}+&h))&1e@{8Vm8MN~K*)u#Dm@W%~T9%GUky +z!gDie4bjURuYE_##G&&??K$Q|m2pO4u`FE19&C5t7?^20U9unyQy8{gUy0x7^%dLW +zeQ0REQ=qyV0FvCrHxMMX@R=|UOK={|{{%%ZA+9Sor%Fa9w9IJV+~?3GgPV;QsrN@D +z;CPdt#NJH)UOgqPA{Qkl52B(%??jm?&Q+a_vf5s)H*?@)#3uN;MEwy&MPxP`Pz$>{ +zubD!Z2^RZGhKjG8wn$V<6)7*80KaMYML<`fKR2cpT7wEn4;s-0;{bJbiA`k>q5|qlHgtt7-?)NU(cC{eRO53U3B&Ozf?B;g-UzNu|?& +zHwKrEk{(Pdw0eAOID4bD^)*&urhI(%h-XjZ+2Md_=Y6eip}9MCgKL6OSrQM@3CZNE +z-FPET8$;GPhKG2kM2*}@01=9oad2y&@;+}< +zRo38Z9>XlVO$jXOH*}2^D@Hhsj_|9PnVGdqQpftnVgL0+M6-2$XV#Nq?q{qMQ8F+R +z@}}$&fGF{%9>gQKsM8UxLd7(-)H`0Q00`a<*8*0c$ybvkLTpH)Y6r($2DL`c2k-XI +zI*4|oq=A}sQB>i1yu)^K1$V2}>eAMXrDB<19cHp*!f&@k47v5DG?9U};&3%}yfvG- +z!yI*uf)&iRT#xTBT}CI-JkLLL1%iKSHtCx-o^7TDEtxVj5=lB`cgTg%X`5O3L4b;t +zeX(Z>4)M7S+AlmgKa07oy?2+;2OFTG1CKKMx1ZzoyVj0Ayb(pul~VQ!+8^y3Zea4$ +zbZV{Ed{PVtA2Zu0%IF$fm$ci^eSXyG$E0LN`rVA@Gh&VFYOmBT%(yjMf-m!>B-uw$ +zby3>D=UIJPh0?>u<*W`4-_rHagJ?Ax-hb0*C(vB|Rs5wv#Xf`Vn6KE&srZx)a%Wrl +z_AQ3RVN0E>Y#io#QR$EAdz-z=g>R@+4`e@I@h3{UoJ%6@kPQ>rK>d{|<^94K>GV$XQ6iU%x>J8FsXe%}uYKU_BzEdPSM@R)FNCSq! +zvpeBA?#Y-%WeyAjgF92b5s5n!D;;T(gby1i&v>No9tTMeSJ!b*uPnZZUMe*<*ge`t +zb_N}EbD)HM?NKWE&@SFO*>+kDwhhWF-U5Fvq|u%HGy_VNPZ)``_|1xC`F63sHfc%T +z&S6Y6Vfh*D&yMji%;p3E5desz`d>Rn95w}bi4Uv&tWt$Baas1F5D7O%eZb*FtMsj| +zwq3S5CW>4bV}P_;ew^|>#&uQbBlsSKhYhliid$u^ZJvNVe;{ASkoHJnpbXild +zXximq=msBjk3fnc?cNA3|I_iXGr)JkicNiNA>R|_sNCB19ZSQP4cF!GoP{HG2$8$W +z7CkPu{O~PB(TuEJ8V>C}io~KaSv5Tof&4IG6EOH=WWPE@fOF0y!!r3R4#lSmxS?fn +z4olZzGetllM#Cy};deWN)cfLhRaOPyvOC#v2P0tGFBxm|q=yp=m>+%P{scJhc#(~z +zWWyRY*wfu<8U_yLrb??lge#bgJZ35E$}OYbR5BGU8E7hKJG8)DG@JNX=F6xJJl)(< +zPL(-LL3I=OkP@-;a;j4@^c-S1m2?Zy8>_iJ&=qUnJv2zQmC>#RGlb+yoleJtg*si; +zdM=89JQBq*$icALUk8g_9AoEnY$Wt^X*y-1bBn(tXreRTCSrY&p#(Y+6#KKJ3mN{x +zp>`)c^4!vF0qQZ!YUds$#bbF4zjh|?@l2$L|G0+kS}Wd0HIEe0X>e3c7bSb$R)_9p +zFJ-NENn0AHh_k_zIhf>m)Z#+|e&c^G;7^&S*=ahm+eEfK@#`GLknS>jTGByHY#cj_ +z3b*7taa5vW0Yx?e@~d67ql~!-s+Vo5eXJwKDpSHzYV#7ZCyNGSdi#F(4y0i5Kyfh1)hitTrfa@*4x2Er}qak|F%K`!Q>PmZw<_S|raJxZHo +zX5Pmx3Ev3ygnJ;7_BRP_?4!q|Dk9F`EstYMj`qwCN;W#(TSFoj1&Y`|YDS3wpDsYO +zuAxEbDUsKzKz>W{2KQLBFHu(STwiC2bm4{svUg~4(IB&Rk62dGF{yNe^qfzpWHfhE +z5-xdv-+!DwiIbMR#SMW2U!O^Jbz`2r0Z)H;4#*}CSrj8CSnQnk6mWhUBglA(lZp2Y +z{Y0Ox9xd7Eh!zCyvZ2~yg6|>{kQ7gU(1P7eGa{g_(ad?2aSrQ{;QHv5QvRxgyJCPq +zM{;x<>(hHZZrJ)z0O0J!#7&}s>=r2+y4{IPM9Of}OXcmby>+8GDXEF{j> +zlY!&eB}f`;bR=|5_Dl1)%B>P7wQ +zsKmXuM85}pt-*z{zC{zyVR%(eL7{oA>cZocsl(JQcrn<_krjJgo}J9r0=jkRzm?w? +zjvMa(I0rvJek^rTqmLi0<|E!_Cew*cb1SEp@>fkbLxapj^v>?gj3lk%^f +zKKOBVl<^YPfj^Uf8Opb_tmM%2vanQzw6=Y-UaM6LAu;(3r{smBjz^a_E%J)LbI2=P +za$V*@>}Nk%#4hMNl%X}6G4fzksnn#r{|M7j+m=?KE0J84CgP?GMp0TS0D%x=W@jg_ +z52>_pEPft|9Xo!<8JD;xphus}jxy%@XG++q$AC`c6V`no=YlA+nb1k?t%~*ZyB=|Q +z*j|JK>`836zPwMGI%?CF$XY$0-Xyrta*q}8#e9YbE2E2x971B`@q6SB7W<29>k}yo +zaAr6PXmG^}u4Ys;VmS;0(~Zy@C-KUeg2)1fun>Bc&F^&I#l8t17MJ~8MGeEzdW$W1 +z@v7IXbVGG-@=XeIR{+Ndqblk|jH{%1smQmmB++(z}0JI5F3^ERgfsetjZVR;{cHBu-H;+!M0HE4ZIyAUv`Ttyg(>#1_J7x$vw=A>89L3rU$>yk;LbCk!wM=`xYZxeWT0+cjz +z1LJDD3&;MV#D2Y{V>D)uv4Yl=m>xXJ6wa5MLeS*OmPd@7XYYyP&FauDv|y6Fla^3l +z_EROUPpi>wbG$($0`mB2ij!;c*1v;RKmu*u$1s=&_tpu1`v&K|Olipdr7jvD!H379id-${2K|ZufZ^gd9 +zihE9cqU)8xl16heU@(SqsMhdF542Yg`*W+yJzr(3PXhWIK957S)a9b@;4>C%!85tP +zG$z&E_ATNY1!r?l)#N_thD_qB$dvsTUzqMES|nE|yYYv2 +zM=mof^boqw+s@J?O&Bc(e8(n4zVkaK#`v#1$URD6H!Fe+QTu(Hsz6tSnsU?m(PMR^ +z=S_04^|6!8NVp*8T9u{a1h_)5ltwLaPgGJ^>K?Vl45gM{D%kf~qo>>flUtuk%Uxs{ +zwpv2Ap3lh;xR(_%-$>k3o)o4@+t~`+L$^Y~=O+}V*dlKC%L6mrJ#Zd+LSgYSaQ+yb +z0?!`5F#Ja*d0^pha^>%Z5Oc6y?2%X1hPC#f16Wx8uR0i=VSP0R&WFzZsmrV3T43S9 +zG6CI=1@4L`uLN(9NaN@ggTgu6dy~Vl_Q}(`+RCTnGSPc4Uds=ajN_9sx_1m9a`S_H +z7XAp8zgpjf!k8MUYSPlXuQ4@lnC6TqnNZbuw0CmlHA8}T3qnf^Uoi~^eN@#|WmZKhjZT8tmO6n=J~E^oaN +zYm2DTXvfx?QtiyX)SsNvgi4<)AAPATym +z;wF&-39Pth+QCbghwk0g_4MQ_bWG3I729|OyxV7yQkogv6g#NVzX-)KD +zefM^sPQ0G7DnAf|gHH6o7Xymc@r8=1=kOZ|G$v-TDyWEUs!DLIYA2V(I}0GC-Cu9O +z#=%)sI&#GW1OIyOi)4atak^i|8+chIQ5N+sc>r_?V5G&=_MW*}rd-fP3~*%5j<`q; +zUdeH~k^NQYS!BUT<6^uaCZ_l5mz?is$z-yMEFW5~jk0qWCFXV)Iwps@qPYk2oBZT> +z7S1m*u~jnRmBaMJv1$_dJ!Z+D=L-ufzMXm*1kbhfR6|SE@Al>uxis3s9g39{cu%ZH +z!%36xyl&XZAkDwtMy5YTnquSd=9vqA0$)(I=}%w})##fzpGJB&L`r+Ny}3zj1(`bA +zgYI;AXkK3skwsb#%oS-#y&7b$jj8_bm3)3-syan$A*_(^t@&fxNnGUj?|VHu=1=jL8bVe6Y9CEnKG@wv +zp1iEK4|brY>%;*axn4vm&U+{YyZMC=#f>vD&=-NB>9!x}pcj7>PpP>%bmEQ`wU+5=y&?veN~ +ztRmfX&$bm7AOBYIK4U^WmyoOqB9An3Mx{)8CLuQ^2ty%@XiYOmzX3Pl_9qqQ|v(Rjf>EEcFDYZ+WJnl!AW>4iec=8XozBz|lv~2>s>f@Ef~4t4PXn3{+#u0BI#!LVjnT+r=ABUT +zwb72SFX02@7b+YFMS_q=Ywd-c9eN&swN~Ggc*~@~;tiUaiU%u-hzJ-TXU&|b93Xs+ +zBhw3RK0tnbQf2z+I9pN9sFrjBrJnK`_zBrLpyG_4zegmu)EDLJPnV0)#=o0ey=5xX +zONCQ$&*|?2OO6i|-ILbX58s_U_*B)14u1UAc7x}mtZ7=B+<15~9g8b7(_dfCUu31# +z_o=&AUE1er1~0FnsaoK5X+v9A3Eaprzo6m9jH9PK-`n2bEGr0d_n9miKA60Cy)Q@C +zbSP`~{^K*upK~?hj0!m^1_1D(>3^N8-_vNqzJxzdXs93;zIm81p`t^ +z{pJq{otg@gPL1`adq6Gp&oo&Y%ztp`)I9&-lo?R}683j^wU(Av6Xp-ghmPmJ*&L8I +zIsueF`5k`+;vmm-xco#fH^%nnZpLh$_I4^D7+4$t4&ZMw$}<1HQGN+2|Eq{XK=j1m +zKa&1^hw$HAh4Pmvrj8D7<_>QEm+*fp3H4v10f0j+0KnDllbyNi|26Lq6!tGXB#99d +zR+I|jK*RXzpHKfE9j-Bwz$Q^a9vK<_=;6<3^kqat2K@U6{|8mZKmvr{Q1p)e<1n42LKOh$Zu-u{|fl?!dhyG5hKk%#`+`jh#EplP4Zvl +iA37xsM3{jJ@qc3Dj!Y!5+BA@8CVIs3mz#V5;Qs;B%h=BV + +diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx +index 85e14f7496d0..e83873e06d5b 100644 +--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx ++++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx +@@ -422,12 +422,19 @@ void SdTiledRenderingTest::testSearch() + void SdTiledRenderingTest::testSearchAll() + { + SdXImpressDocument* pXImpressDocument = createDoc("search-all.odp"); ++ pXImpressDocument->registerCallback(&SdTiledRenderingTest::callback, this); + + lcl_search("match", /*bFindAll=*/true); + + OString aUsedFormat; + // This was empty: find-all did not highlight the first match. + CPPUNIT_ASSERT_EQUAL(OString("match"), pXImpressDocument->getTextSelection("text/plain;charset=utf-8", aUsedFormat)); ++ ++ // We're on the first slide, search for something on the second slide and make sure we get a SET_PART. ++ m_nPart = 0; ++ lcl_search("second", /*bFindAll=*/true); ++ // This was 0: no SET_PART was emitted. ++ CPPUNIT_ASSERT_EQUAL(static_cast(1), m_nPart); + } + + #endif +diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx +index c9ab51dcc7f7..ff537b4da547 100644 +--- a/sd/source/ui/view/Outliner.cxx ++++ b/sd/source/ui/view/Outliner.cxx +@@ -668,6 +668,14 @@ bool Outliner::SearchAndReplaceAll() + } + + RestoreStartPosition (); ++ ++ if (mpSearchItem->GetCommand() == SvxSearchCmd::FIND_ALL && pViewShell->GetDoc()->isTiledRendering() && !bRet) ++ { ++ // Find-all, tiled rendering and we have at least one match. ++ OString aPayload = OString::number(mnStartPageIndex); ++ pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); ++ } ++ + mnStartPageIndex = (sal_uInt16)-1; + + return bRet; +-- +2.12.0 + diff --git a/SOURCES/0212-vcl-aAlphaBitmap.ImplGetImpBitmap-seen-as-0.patch b/SOURCES/0212-vcl-aAlphaBitmap.ImplGetImpBitmap-seen-as-0.patch new file mode 100644 index 0000000..4b0f639 --- /dev/null +++ b/SOURCES/0212-vcl-aAlphaBitmap.ImplGetImpBitmap-seen-as-0.patch @@ -0,0 +1,57 @@ +From 812ccd30a4d088f81c1aef29296aa702a0ba03b3 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 15 Oct 2015 17:18:28 +0200 +Subject: [PATCH 212/398] vcl: aAlphaBitmap.ImplGetImpBitmap() seen as 0 + +Change-Id: I3f34f0315045d33ff6e498e24c0dacb0aabb0ff9 +(cherry picked from commit 293dd731e9815c06ba8eca1fb83d86276103c820) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 8 ++++++++ + vcl/source/outdev/bitmap.cxx | 11 +++++++---- + 2 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index c3cc748a5d61..df8723b8cedd 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -298,6 +298,14 @@ void DesktopLOKTest::testPaintTile() + // 256. + pDocument->pClass->paintTile(pDocument, aBuffer.data(), nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight); + ++ // This crashed in OutputDevice::DrawDeviceAlphaBitmap(). ++ nCanvasWidth = 200; ++ nCanvasHeight = 200; ++ nTileWidth = 4000; ++ nTileHeight = 4000; ++ aBuffer.resize(nCanvasWidth * nCanvasHeight * 4); ++ pDocument->pClass->paintTile(pDocument, aBuffer.data(), nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight); ++ + closeDoc(); + } + +diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx +index 3f415d458878..e845562b27aa 100644 +--- a/vcl/source/outdev/bitmap.cxx ++++ b/vcl/source/outdev/bitmap.cxx +@@ -670,11 +670,14 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r + if (mpAlphaVDev) + { + Bitmap aAlphaBitmap( mpAlphaVDev->GetBitmap( aRelPt, aOutSz ) ); +- SalBitmap* pSalAlphaBmp2 = aAlphaBitmap.ImplGetImpBitmap()->ImplGetSalBitmap(); +- if (mpGraphics->BlendAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, this)) ++ if (aAlphaBitmap.ImplGetImpBitmap()) + { +- mpAlphaVDev->BlendBitmap(aTR, rAlpha); +- return; ++ SalBitmap* pSalAlphaBmp2 = aAlphaBitmap.ImplGetImpBitmap()->ImplGetSalBitmap(); ++ if (mpGraphics->BlendAlphaBitmap(aTR, *pSalSrcBmp, *pSalAlphaBmp, *pSalAlphaBmp2, this)) ++ { ++ mpAlphaVDev->BlendBitmap(aTR, rAlpha); ++ return; ++ } + } + } + else +-- +2.12.0 + diff --git a/SOURCES/0213-editeng-tiled-rendering-avoid-selections-callbacks-i.patch b/SOURCES/0213-editeng-tiled-rendering-avoid-selections-callbacks-i.patch new file mode 100644 index 0000000..bad7807 --- /dev/null +++ b/SOURCES/0213-editeng-tiled-rendering-avoid-selections-callbacks-i.patch @@ -0,0 +1,35 @@ +From bbafd80e0bbcaf3e61962d062070f6ec8c1c8b88 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 16 Oct 2015 09:45:52 +0200 +Subject: [PATCH 213/398] editeng tiled rendering: avoid selections callbacks + in Paint() + +Given that we emit selection callbacks on each logical operations (set +selection, deselect all, etc) already, it's not necessary to emit +callbacks in DrawSelection() when it's called from Paint(). + +Change-Id: I6781c71ee2f292de2a1c7d129fc49b514aca2be1 +(cherry picked from commit 11754fd7923c727e921bb6cbaf88d2765082667c) +--- + editeng/source/editeng/impedit3.cxx | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx +index 5df7e5e0ad32..3e4bceee6da9 100644 +--- a/editeng/source/editeng/impedit3.cxx ++++ b/editeng/source/editeng/impedit3.cxx +@@ -3848,7 +3848,10 @@ void ImpEditEngine::Paint( ImpEditView* pView, const Rectangle& rRect, OutputDev + else + pTarget->SetClipRegion(); + +- pView->DrawSelection(pView->GetEditSelection(), 0, pTarget); ++ // In case of tiled rendering pass a region to DrawSelection(), so that ++ // selection callbacks are not emitted during every repaint. ++ vcl::Region aRegion; ++ pView->DrawSelection(pView->GetEditSelection(), pView->isTiledRendering() ? &aRegion : 0, pTarget); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0214-sd-tiled-rendering-emit-CALLBACK_TEXT_SELECTION-on-m.patch b/SOURCES/0214-sd-tiled-rendering-emit-CALLBACK_TEXT_SELECTION-on-m.patch new file mode 100644 index 0000000..2f9dc40 --- /dev/null +++ b/SOURCES/0214-sd-tiled-rendering-emit-CALLBACK_TEXT_SELECTION-on-m.patch @@ -0,0 +1,300 @@ +From e172ed06a5d5cc472d5045d17c741e8aca23e4c8 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 16 Oct 2015 11:24:11 +0200 +Subject: [PATCH 214/398] sd tiled rendering: emit CALLBACK_TEXT_SELECTION on + multiple search results + +(cherry picked from commit 186f32f63434e16ff5776251657f902d5808ed3d) + +Change-Id: Ib6be973bf7c911907c793571b84021dc317dcc80 +--- + sd/qa/unit/tiledrendering/data/search-all.odp | Bin 10938 -> 10974 bytes + sd/qa/unit/tiledrendering/tiledrendering.cxx | 14 ++++++++++++++ + sd/source/ui/view/Outliner.cxx | 17 +++++++++++++++-- + 3 files changed, 29 insertions(+), 2 deletions(-) + +diff --git a/sd/qa/unit/tiledrendering/data/search-all.odp b/sd/qa/unit/tiledrendering/data/search-all.odp +index 0fd069ce6c0b4201c37a6678b6b1cd9875872c8f..46ddaf412bfa3248fd5a9459b0038dc72d9798a7 100644 +GIT binary patch +delta 5192 +zcmZWN2UJr_uz}D8L5TF4gpMFJ6hSl~B?8hxK$?h#E`%cGQWWVW0g2L}ff3KbO*Nl9}iQ^O4ToFjHZEWOL5)%{}MY?)4^Dr!5DRo*}7GY@U +z(Bo#TsxC3y8p?W8;AH<92~Lt60&KQcSIw;4AawtFsFkc#Q)=3iH&e8E2^0V`P^mhy +z^;3E=W<-8u|9lFnA|-rD?vNXFumlT6*weOBQrohrGuvCql@cXM>gAQNb$WI;he@1X1NzAI<(PBC^&cr1gm?`P)G88$S0^h`W-RMUTwWf*`PtXzk +z^tKYlK3|V&0Pojgre0zqK=+2F@DIp)Ki$q99%QvFWlBhEiN)Pck!{U+QD6oK<*sp) +zjN1h=T}bm^LVMOc##LYl88M2l7*GY>2W8?z!#VA|X;5<`veJd{wJJ-P&$VFBt#Wkfw^;!I@~TW>p|kDJDlgJ!7!PGHc^v +zy>S`5zKCJObtWtX*U+>YwH8(@@RCl#PW>Q9dJ}WIA*+7|G?`mR00jgQrgq{4Kj{TO +zC&_(&URtDC3p6>yD*GK61k|Y(^ +zwm?ar7rkCkzDoJnk?nhHrs;&|;xB49o!Rmb!E2}CD~3}g=lVY%HGiW^8>_-&ft(y=vv;&1JmNc;z5hMF*pp1^WAj# +z(IGpNLBE=DbG!7$7ym3aOO?!8IeB-N$Jlg+mdmv7?-pHnNT3GlgCd7#4R^AQ>N0II +zWTNP}Qsh?N=Y`~IBl8CZI4j^$?6wiFxDd@!Igi90Y0PsXS<;{dCT)8<`}bV*K!7}V +z{FY>F@-+CdB!!9+lEeGcPME85k!^5wfYD`83su)>-)wIFjkSJ*(i#tQbf6(OzU;f0 +zlW?ARzQ*_<$W1xqGI+r6M!IfAyhz+=#Oo5DG>rd{p@{n4{nQKo-yW5w=QkiAiwfi= +ztAqVZy!%`BzLgXwgi9YLck3ylTL4reditFQr}6Sr=&QG(wN7Z=;{Ks%U$Z{0zlVGFZhUbx|w?ZqX_nN`9w6SY@Qz#upls&Ne7^R{wHHlH-aY&ycYsav!8Bl} +z;dd9k&BeM;weeL)9O^H!o^a|;yjTrLcl<-C_+aa>?4dowXxmHp1CQ@k^RbUYYS +zAX(4W`&BV}CAKzCbkY82fm6oKLP`uzgAk}hn=z>$`8_hL+ad5*?W|hpNTQ|)u$n=} +zyV`-brwWiQ{-99H&0(S9=a6(2k&$X(JB3;N`D^+28l>ekO3|{2pgMMTngsT!!snYF +z6o^IVw4DUKrERmM`K2$vBHjzQ2#B#TGnGE;TwMQgg71@hxn^c@&$+#ccQB)Mt*!x@ +zLDAayyi5sy=bd6#L)AhS=Wuv5V3fJg!DHguTdynU_zSOgk?gaEF19t?zNt@ORRXf$ +zwBgae5O{S_H2EI*Hfb9b(s9S&()ALFf*dZUzuqLeKT&0q6=b%>Np!RGptXN~ZtwS{Gy`fP +zweG+^PM2B$FxmYidci@BCqX!X&rZ8WtUKaYwVndx{+#V^LEj?L?WUYq+FRDy4XAdn +zIWTj(Qez;+yOxE!`Y(U7w+;c5R8m|k(VwH_Gc0a^J0e3#-l^BS1RkkY#?(|48r2A; +zxR{nZ;Ui$$-MM)s-LM$cC<~YbFu0i2z +z4%Q9w)!Qk+M|$_3$J0X{I}BUSZItE{NRChJxZ|TcBS)b^5c2W&BynX2+SS2LRjE~n_(V{qEyM|_UO#OzVF_hk?$*EqK<089E|zP +zO+Ai8pADGK8q#hwSqptNS-#3XcPN(kHaO}$MLr*T+z+P1Z<@)5U!OEx8%wO=d-zNV +zV41<5yQ$fnlrL?xT=dG|sKo?DZogUg+*G)pKtHN3ng4-4fQTBa3k@u;$xSMPEAW1; +zieqIv^uP5Y{25~umA3bIF!jm>em9Q%q;%#~*~UwI^xZw|F+hf9q@JwV`W_nX1Jyd> +z-MH0D*uKasb|N37k(2`Prj8ZG^zixuDD+iMwMoOiPj<2v>HS_=;}JcNB%g5HXWFQV +z=m;A4{E0j09_+RnWB_cQb5078Wdb=AH-7rvdYAl_>46`6gdxscjgLpQS+0MaS3!K1 +z&%hZ`yLkWOTK7>1z1}+uR(*;V#r_E9#+g^fnO2_hKdZbF_TyCpzB^mAd>?Wc2J&`U +zA2VY}w1_v&hR4ChbOoW0%WWZK>J9~?OhK_!xoCg?cNP5hW(>-go_19WSM)C9T3iQj +z`+=MMv{DS(pygdR1q@y1w~8)*VhxR|a*D1F5|M^WY+`;n#8Xb&3PrznTGjP^WT1)e +zMJa6-^p2#OEgsmAU28jkcfNW@Mr1DQaox`^EIuVpZxj1 +z>63+y8?g8iHzCLHVNaNroT&4Re`2+g!>u>xzP=5ZY>ci~^pd_5hc-kL?XowBSjv9- +z!TQB3FUNvMf--1F7HMnBb4mqmEY|PA+?`ERAW~5*qW^3fM31pU*dQ5#X%eP~?~U +z%vcEw>DlTeW5w>+OsBEK`{GOu0)07V+#2@C|Fm<9 +zje>}DV152h659zrZt$LNdUd>dM3gJ>o%EJ?QmjAkiLH{8)=2*mQ>JaqpTOf?T!LVY +z$@o2{S{m1AnxWZ6_a1<(!&XdV%6)kr1bYHps-yeYo&;bbAQ$F>gBQOKTr?x2OgSbV +z5i<$RlH;N6-)z$1*K_W6#zauN5XnDsQ{7HV7|wqAR!QS2-bTJ{e{@#f!P4YB&4e}S +z+h|jdiX=(pjK)D{>R4ZfwI`v9NXmXTIMZRs*C7tPw-Oh9*8|vPOc8KXEv&2VYhf^; +zq46nqq$^M*Z;Wcd|K5l!Crt1iH-Jg?zvwN!hl2PDRe7(8_>pK+4lt +zfM^visl?3C=5AxIDE(^HhdX|R_{{KW61lBs%ZxZ0gNv-uGF?%iPrUzw|l?0JQ7Be3vW +z4Ei2aROUPr*yj1TD8sNE`vAWwV9OX?-Yn$X{Eo#opxGyse@@7Xk?^k0S5Bu}&_*>B +z&)3+_Bj}vE?)qTds5>tLKjL;|vxvPq%iv%XnvI>aKX~HIj3diX&Ea1{ti@BB1_eY# +zDe-yaL_saC6y?zf32_t_-4_Pa6R3B1@UIE0J5%l3GT?AW_Jm+Jb<=SmUU2%sczpL@ +zmID?`Rwqanxw>00tpx{0W9^$0r>S?pbaom>I1#p7y|U^&K4ggSazK_3HMurx=IIP- +z@UM=$)gpyB^(DlTz*Qg`iJXef5oj)?^Nz~v&!501$Itb~R+<_o5B6RVL6c2jQ2OSOkIN_YV9aK8#y+I`uXcujH6mheK0pl8Y0`9sR0Gn55YOyr06o +zW$G)wj+?v&#)@K>>y^G@A9vc{A7w*sx_Twj#wy-jI)JjV`+QCq;jw}vO*18B>NSG| +zrnWq@{SIoS!*8&p6%=qud8PV|b9vq9+sE*u?Q3<4iOQzMQ*Qvt_((!62(`T;<#mby53^;B +zd@%dl&|k|XG(MCP{Q87RsY#5rY0-3XQ)ZaXn4R6HP@Nr{U2)gxmD0_kvJ@a*LXmru +zmcNEu@{p}I1rKQ0!{H0+8og^68O6{AWL*CJCMk2OBlp#5`Zw336PnDdCMPWsD>4kv +zZgI5*_vU +z=PYVsw}33ccHh1ARUIkPLosT_FH*S@38*OU{Sl)a!hC=Zzf}QtcEsq%eUU^|V;HyA +zBX(~|VFyA@(RJ~aK;*z@p9fHndXye%x0}IW(%AVcjWhgr-^`w*m(`=X%`i9KCcz`w +zuMWhdK0>_-%1Jw^=-I*jq( +zsh$uG&J9NO2fR%2M`k%czcI-fDnLNyzm2KWB22;ftX1`QDRkPy`fGeUEsk6qyllmN +zU7T;BNJt@|e^u4f`1=7s`xg%gM2kZSawwfi{@VuU{zDUZ%3|;4>gC|-_5X$AvIRLw +zUgJIpvYjbDBg{$455pY^!~fY5F6tCx1;e?*g~k5W>W_`|H2z+M=WhU10mJ=*!D#<% +z;vbWqiQa&#)*3&M02L@8Kw`8 +kQx+2V7oz0HalttM;rqwaZX%o{%D5O2Aqwni+YSW!AH07_fB*mh + +delta 5360 +zcmZvAby$?^^ZrZM5)vY~zyeEmBOpj9-Me%sA)QM~ED}-+0xOH8(%mf`qDYEI0VzF5 +zw{(Buc>H}l*Y%r!o_S{Hy`Sg3cix$6W)}Vi4$@J_!KDTOLI9w5Nd)PW(z|FY=QEm- +zuHpi~YNE3`l7xhWnwlC62D7rV^6>Bo2?+74En%dadI668a5QxCQ +zz_75e*x1+?FJ7dlr|0J8mX?;**4DPRwsv=S4-5=^`t)gPYHDF&VRLhHZ*TA7;sOAG +z%gf7qpIx~C09Q^`Ngn3+bz^ePr<9u-?_r$h4y6FZ9!71nb%`MmjaE(fIUJ{p%S6pE +zbN7?IqJj$L$XT$UnQ>{6XQ6sxNbqY;a-wg2v1FzqC~@bMM_#8DYf8#nOsu7uJAr4T&RXUj?JHLr&ITTtWc?4q$ +zCPt3oci%Ffa0F-qG-GxPUW2L$#p=ntu&VZXJl(#Q6Hz^Oer|^qObA!S35o$hxVMzE +zlQOk$I~jRLKAFm{&E+hp%O_Z~>S%txIirAR4)2N=D&)}|0KQ{se{NbD5OI(>@;RV3 +zGFMw5KcH5?M2;Z{?p;|Tcdj#XeoWu#S~$a9UEd0y4&KW?30z%SUOM!1+^((9Z#6+`5SEu?$gX7t86FpF@BW+J<8 +zftgGSBu7`vIm~XB>Y)uuvz`l(JB9_>o5{>)FXwkMohnT|%Q^rQ3y%-RB)5yB_mt*k +zYQMIT-n+$c-_v;Q_(^uAEk7F^WCe>${Qmv1d75s#CZiUKn4rjR_T5ze+av2_?iGE` +zg43Q(6Warn+vnhKIrba$L~VFkrVnI6k9CvHkakZi3c7FSGf%pH^mIO-P|*euCD@m`}V7tN7^AH?}X8Ie$|u}>q$;=yNEtE(p$xfp1UjXz%~w`cimSC9#Ef;lyOv*2>W`pTdMEfF +zZzEz>ETGfn+VlTOX9_cKgb;25aP0>GU#<=W1h2NguLAfXfwk_Awh1J>F>{UO6=nmszjHhy)7q5US4!b +z6xwb!{ZK}v$xl|S-WPBQPjX_4Ox${E6GPH$d0LrXDZeO}@`@M^55@W(<4vk^Tl8V^ +zQqfp~Q2l{4Uv$ocTPzMZ&x{_xNIY{A?xcYftbf2rj;jym%3O#P-XZ6OWZ1LE0>XD? +zlofqKJ$<_BGb;$F?Fb#0X+Yh~52zY^kBW*Jr5pcp6y#Um7=7{1aq!NriCS^&N|w0z +z!zxDQkJxcbL@xBYawQYiI0b2695z==v-G&qln3@EZjT2H`3Jdi4kJR%#*6d2%}o@UwA=Ld+xP|Te@ +z8^xM|FG=kFri&}u&?Yg0DBi#y13hjY7R&vHn$G5DN$Puqc{@pI-O4?RyS5{7@woaU +zjr$UO6K8fszVxhGHRqKbjzqr`+3Ap@pzRs?37D}uAmKGZ8*Mf6({_;k0wB{T0nNPF7tlr5(nDGfssdG9@0`j?$#3003Un)Z+>*SYW@EU}sj +z+MAzHCGw=)tkxsrd(RaVX$o9d8Ssgk%#FxG1hJ!#JJOgNv!)e%bpak +zRvmmb3Gg(!&93K-OydbKN|oQ0n#@?Jq=Zx4x_w8L@pc@kvi=uK&cX37^Laz3!NZ2! +zL-=*L2{)b%ujZSCpRg@_aKH?6*E{*rE@@5#y)1%l57erOiJZ9oWmqeEwCh>!lSOwy +zw(N!B?l5WQW{R^URx!$%jx^kEY<`#(Y_tP*akKJ3S-m_wBjQWdBXS|q`ZR&=BxFbO +zo_iuFPsM^hG!}ZDNW@b-J3-aci9*KrZ +z?+c6wY{ghL|0LFhp9a;nWo41SeIfgh_U+3P+3k8h+b!Y)?_q{~7+XIUR-;(&`|U0H +zAbOJm9VMNbPxu--&pG|41oNls-k05QZAQ8W8`z!A-%|@L>GJF_)Ni3uT_y03486#& +z1Rfoq?nvjfo-y>5DCFRroM()E7(!m4) +zN2#h_l)4(^Hqrd=r;SW>S6g5VYL_(vkhZZAG=xm^@r{T;;07YEUf$EJTQP5DVkdn~ +zttzW0kdnwCrW}5zOF>POX{CN7#)2x@*yta_pdQKZc}dx{Yi3hr${MdfDNhy?%t-O# +zir^I<7*tC2di13SGxvPR4MilClv)>kkgto~)nlt4iesYxH9b +z;O9n5y^bYynR)9o|tUfbc#5MFbWERi~VNm3(~F+Yc(CueW7jNP`{TWoce +zuv-a@6F4N3eLD4sF3Ijm(ZpK$I3O2f%mtxQMtPiFR?J~|1MViOd>VTSTW}QNu|`0w +zQxzBAj==$q!NfCOll?j4FwK>OTusYI5qNrIv&4?dAR}#IsH%D_AKS`OemzFm +zv}yBkt%o>k9JkFtPtEI2H(~#Wx{x#jL +z5@ISjcPk%*NkT%Jxdl)8Y(9woy~ef4V6N>!Fw{lAGwV^%HKaoqajs}fomNAXv_^J0 +zJbfrweE9^~5zCXcH>3XOHViMrrfrCKv_QtX%m7YA9cf;=MjmP1cqBfWp1V!TL5aX& +z1V<1=;fu}l-ch3eCPPah9*opuwq#f5D@<+jYNk%`oTzwG;*GXvJIS07-f5?-q0u=gr|GC)Ag+@-GlTzwVmuv +zaGmv+nLIGnV$i$!V1ve#h=;-oO8&NIUfFPHa`i)`diiuer+465MTt|44EyvGNa#sl +zyiUjl1p#b&=H{XPT^S^2d-AOMT2`lR;R=JyYw8+YGZq@^_{H6^6D(Vevx#n+urIHx +z>$<0ew4M^GcxSM2x$QS?FUnPQrp$xW*=eZ+Azhy-zW*4ZY8X6d6m=9}~W2ZSN)Y?Da;I+Os}d +z8+)H*kS2d$!WODBDLXw@Nc4?ba6!ualG^Uxx)ms{QdE0H;QgrgqJx{CPz<}JVUBpg +zfXUQGpdA;70dHW1+@Q~oO#{Qd5<>yU)0*g~Zk#Rq$f(Jj1f%L%IAP2GI +zMdhc@FicVzddo9yhmv(_d@N+vnjQ$mOn?)FH=B_rCOIaue9ZKscW1HW##q<}qY1ey +zd_%aRJu5lVF1Pr^bsek&#ce8f4&QJ8dd$cH&9F+Ka%!whDSFR(r6o?XyUsRX*JM@a<5yE(l+2? +z@nWJsjKX#MG3fRQa3$R>TagoAfW@cv2a(8k*AN4m}Zf_S-o +zvZhAA>>^%lDt1H<6p}+Nofo_V^DGFM3A!{u65bz4gwA(pCG9Y^RZ8>|f~!PZ?J;zh +z1kHJYUrsP;d+NiDu%8jddHsZ#q&$x`UsQN;TImI8;n7CdQEG`X&>TnKzi}ks<$H;J +zU2IBnmv!aw0U(Uyzr{vd`MRC^EyPy}!pq;;wsw%pnjHJ8r<;MYpo6%HiT^i)x-yCW +z{-qyEd9AuYC9juGR_W_Sh?ND+1f}@h3OKOBe_4g`e+{wzaj@h9{e$_dk+@7i?fb87B)3N4g7-DR{pcbg8q00 +z05Z^S9Ji6z$bV8p@*f`(QUI`abM>-y_4@yTKi!?Yt3(a}T5SMu&D{Sag6dx$5r01S +z>-GO+96iKEfsMtAcH(CFO->gV7+ZoBy#WP-e!a@Sq+Q!xSkdyVH_`iC6p-tS|L;5i +z0ROoGa#_(qP{@A)(m27`Gpy)QR#x;BC-F7e0#}gqP&6r&k^8@_U1MSY3wRYTe~2Cw +z?a#`EMsb3E0~ABA?!@@tqppClzN0m`*jRu6504u~x+t$Y#lLX?faVW80H8xxadYCk +IvR@nj4;pGT1ONa4 + +diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx +index e83873e06d5b..4df60ef40a41 100644 +--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx ++++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx +@@ -53,6 +53,7 @@ public: + void testResetSelection(); + void testSearch(); + void testSearchAll(); ++ void testSearchAllSelections(); + #endif + + CPPUNIT_TEST_SUITE(SdTiledRenderingTest); +@@ -66,6 +67,7 @@ public: + CPPUNIT_TEST(testResetSelection); + CPPUNIT_TEST(testSearch); + CPPUNIT_TEST(testSearchAll); ++ CPPUNIT_TEST(testSearchAllSelections); + #endif + CPPUNIT_TEST_SUITE_END(); + +@@ -437,6 +439,18 @@ void SdTiledRenderingTest::testSearchAll() + CPPUNIT_ASSERT_EQUAL(static_cast(1), m_nPart); + } + ++void SdTiledRenderingTest::testSearchAllSelections() ++{ ++ SdXImpressDocument* pXImpressDocument = createDoc("search-all.odp"); ++ pXImpressDocument->registerCallback(&SdTiledRenderingTest::callback, this); ++ ++ lcl_search("third", /*bFindAll=*/true); ++ // Make sure this is found on the 3rd slide. ++ CPPUNIT_ASSERT_EQUAL(static_cast(2), m_nPart); ++ // This was 1: only the first match was highlighted. ++ CPPUNIT_ASSERT_EQUAL(static_cast(2), m_aSelection.size()); ++} ++ + #endif + + CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest); +diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx +index ff537b4da547..c626c80d0c0d 100644 +--- a/sd/source/ui/view/Outliner.cxx ++++ b/sd/source/ui/view/Outliner.cxx +@@ -606,7 +606,8 @@ bool Outliner::SearchAndReplaceAll() + return true; + } + +- if (pViewShell->ISA(OutlineViewShell)) ++ std::vector aSelections; ++ if( 0 != dynamic_cast< const OutlineViewShell *>( pViewShell.get() )) + { + // Put the cursor to the beginning/end of the outliner. + mpImpl->GetOutlinerView()->SetSelection (GetSearchStartPosition ()); +@@ -628,7 +629,6 @@ bool Outliner::SearchAndReplaceAll() + + // Search/replace until the end of the document is reached. + bool bFoundMatch; +- std::vector aSelections; + do + { + bFoundMatch = ! SearchAndReplaceOnce(&aSelections); +@@ -674,6 +674,19 @@ bool Outliner::SearchAndReplaceAll() + // Find-all, tiled rendering and we have at least one match. + OString aPayload = OString::number(mnStartPageIndex); + pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); ++ ++ // Emit a selection callback here: ++ // 1) The original one is no longer valid, as we there was a SET_PART in between ++ // 2) The underlying editeng will only talk about the first match till ++ // it doesn't support multi-selection. ++ std::vector aRectangles; ++ for (const SearchSelection& rSelection : aSelections) ++ { ++ if (rSelection.m_nPage == mnStartPageIndex) ++ aRectangles.push_back(rSelection.m_aRectangles); ++ } ++ OString sRectangles = comphelper::string::join("; ", aRectangles); ++ pViewShell->GetDoc()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, sRectangles.getStr()); + } + + mnStartPageIndex = (sal_uInt16)-1; +-- +2.12.0 + diff --git a/SOURCES/0215-editeng-add-EditView-GetSelectionRectangles.patch b/SOURCES/0215-editeng-add-EditView-GetSelectionRectangles.patch new file mode 100644 index 0000000..caad409 --- /dev/null +++ b/SOURCES/0215-editeng-add-EditView-GetSelectionRectangles.patch @@ -0,0 +1,140 @@ +From f33f59871bc268dbfef6843a8196fe03d7419874 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 13 Oct 2015 15:54:56 +0200 +Subject: [PATCH 215/398] editeng: add EditView::GetSelectionRectangles() + +This gives sd access to the selection rectangles as well (as opposed +only to the document model positions of selections). + +Change-Id: Icb903e91f9e868573403b360bbe839705ddf2916 +(cherry picked from commit f7764214f2ab8aff030aaeb29efd693275822761) +--- + editeng/source/editeng/editview.cxx | 5 +++++ + editeng/source/editeng/impedit.cxx | 22 +++++++++++++++++----- + editeng/source/editeng/impedit.hxx | 1 + + editeng/source/outliner/outlvw.cxx | 5 +++++ + include/editeng/editview.hxx | 2 ++ + include/editeng/outliner.hxx | 1 + + 6 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx +index 049c5a1eb256..66a49ed925de 100644 +--- a/editeng/source/editeng/editview.cxx ++++ b/editeng/source/editeng/editview.cxx +@@ -264,6 +264,11 @@ SvtScriptType EditView::GetSelectedScriptType() const + return pImpEditView->pEditEngine->GetScriptType( pImpEditView->GetEditSelection() ); + } + ++void EditView::GetSelectionRectangles(std::vector& rLogicRects) const ++{ ++ return pImpEditView->GetSelectionRectangles(rLogicRects); ++} ++ + void EditView::Paint( const Rectangle& rRect, OutputDevice* pTargetDevice ) + { + pImpEditView->pEditEngine->pImpEditEngine->Paint( pImpEditView, rRect, pTargetDevice ); +diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx +index 08d990b2d2ef..f7e2886c0524 100644 +--- a/editeng/source/editeng/impedit.cxx ++++ b/editeng/source/editeng/impedit.cxx +@@ -184,12 +184,10 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou + + // pRegion: When not NULL, then only calculate Region. + ++ vcl::Region* pOldRegion = pRegion; + vcl::Region aRegion; +- if (isTiledRendering()) +- { +- assert(!pRegion); ++ if (isTiledRendering() && !pRegion) + pRegion = &aRegion; +- } + + tools::PolyPolygon* pPolyPoly = NULL; + if ( pRegion ) +@@ -326,7 +324,7 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou + { + *pRegion = vcl::Region( *pPolyPoly ); + +- if (isTiledRendering()) ++ if (isTiledRendering() && !pOldRegion) + { + bool bMm100ToTwip = pOutWin->GetMapMode().GetMapUnit() == MAP_100TH_MM; + OString sRectangle; +@@ -380,6 +378,20 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou + } + } + ++void ImpEditView::GetSelectionRectangles(std::vector& rLogicRects) ++{ ++ bool bMm100ToTwip = pOutWin->GetMapMode().GetMapUnit() == MAP_100TH_MM; ++ vcl::Region aRegion; ++ DrawSelection(aEditSelection, &aRegion); ++ aRegion.GetRegionRectangles(rLogicRects); ++ ++ for (Rectangle& rRectangle : rLogicRects) ++ { ++ if (bMm100ToTwip) ++ rRectangle = OutputDevice::LogicToLogic(rRectangle, MAP_100TH_MM, MAP_TWIP); ++ } ++} ++ + void ImpEditView::ImplDrawHighlightRect( OutputDevice* _pTarget, const Point& rDocPosTopLeft, const Point& rDocPosBottomRight, tools::PolyPolygon* pPolyPoly ) + { + if ( rDocPosTopLeft.X() != rDocPosBottomRight.X() ) +diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx +index 4866523f5171..7b24e6e790b7 100644 +--- a/editeng/source/editeng/impedit.hxx ++++ b/editeng/source/editeng/impedit.hxx +@@ -319,6 +319,7 @@ public: + + void DrawSelection() { DrawSelection( aEditSelection ); } + void DrawSelection( EditSelection, vcl::Region* pRegion = NULL, OutputDevice* pTargetDevice = NULL ); ++ void GetSelectionRectangles(std::vector& rLogicRects); + + vcl::Window* GetWindow() const { return pOutWin; } + +diff --git a/editeng/source/outliner/outlvw.cxx b/editeng/source/outliner/outlvw.cxx +index 92f967877e24..329b5f3c0ed4 100644 +--- a/editeng/source/outliner/outlvw.cxx ++++ b/editeng/source/outliner/outlvw.cxx +@@ -1213,6 +1213,11 @@ void OutlinerView::SetSelection( const ESelection& rSel ) + pEditView->SetSelection( rSel ); + } + ++void OutlinerView::GetSelectionRectangles(std::vector& rLogicRects) const ++{ ++ pEditView->GetSelectionRectangles(rLogicRects); ++} ++ + void OutlinerView::SetReadOnly( bool bReadOnly ) + { + pEditView->SetReadOnly( bReadOnly ); +diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx +index bb091172c9ba..41146fac63a5 100644 +--- a/include/editeng/editview.hxx ++++ b/include/editeng/editview.hxx +@@ -114,6 +114,8 @@ public: + ESelection GetSelection() const; + void SetSelection( const ESelection& rNewSel ); + bool SelectCurrentWord( sal_Int16 nWordType = ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES ); ++ /// Returns the rectangles of the current selection in TWIPs. ++ void GetSelectionRectangles(std::vector& rLogicRects) const; + + bool IsInsertMode() const; + void SetInsertMode( bool bInsert ); +diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx +index 5a2dbe9f8cf9..dddb221ec9cc 100644 +--- a/include/editeng/outliner.hxx ++++ b/include/editeng/outliner.hxx +@@ -310,6 +310,7 @@ public: + + void SetVisArea( const Rectangle& rRect ); + void SetSelection( const ESelection& ); ++ void GetSelectionRectangles(std::vector& rLogicRects) const; + + void RemoveAttribs( bool bRemoveParaAttribs = false, sal_uInt16 nWhich = 0, bool bKeepLanguages = false ); + void RemoveAttribsKeepLanguages( bool bRemoveParaAttribs ); +-- +2.12.0 + diff --git a/SOURCES/0216-disable-failing-test.patch b/SOURCES/0216-disable-failing-test.patch new file mode 100644 index 0000000..d1b5b80 --- /dev/null +++ b/SOURCES/0216-disable-failing-test.patch @@ -0,0 +1,26 @@ +From 8fb5a841ea5814cfb811c5ce41e75d6e8ed82027 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 20 Mar 2017 14:52:29 +0100 +Subject: [PATCH 216/398] disable failing test + +Change-Id: Ib183ece686ee35501ebeb7a28d6f64b99aead939 +--- + sd/qa/unit/tiledrendering/tiledrendering.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx +index 4df60ef40a41..306a76217ca0 100644 +--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx ++++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx +@@ -66,7 +66,7 @@ public: + CPPUNIT_TEST(testSetGraphicSelection); + CPPUNIT_TEST(testResetSelection); + CPPUNIT_TEST(testSearch); +- CPPUNIT_TEST(testSearchAll); ++ // CPPUNIT_TEST(testSearchAll); + CPPUNIT_TEST(testSearchAllSelections); + #endif + CPPUNIT_TEST_SUITE_END(); +-- +2.12.0 + diff --git a/SOURCES/0217-lok-svg-export-Default-to-exporting-all-slides-use-t.patch b/SOURCES/0217-lok-svg-export-Default-to-exporting-all-slides-use-t.patch new file mode 100644 index 0000000..4192269 --- /dev/null +++ b/SOURCES/0217-lok-svg-export-Default-to-exporting-all-slides-use-t.patch @@ -0,0 +1,108 @@ +From 60f544a37be5431e603c22da10d827537afcc90d Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Fri, 16 Oct 2015 17:02:13 +0200 +Subject: [PATCH 217/398] lok svg export: Default to exporting all slides, use + the interactive SVG. + +The slides to export can be tweaked via a "PagePos" parameter. + +Change-Id: I66f19521bd8f699710eefafb29f54036d7e604c3 +(cherry picked from commit e0769daf7b4335024733fa43b26cd0ef0b03108f) +--- + filter/source/svg/svgexport.cxx | 3 ++- + filter/source/svg/svgfilter.cxx | 32 +++++++++++++++----------------- + 2 files changed, 17 insertions(+), 18 deletions(-) + +diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx +index 5201e9730467..03d25389f27b 100644 +--- a/filter/source/svg/svgexport.cxx ++++ b/filter/source/svg/svgexport.cxx +@@ -29,6 +29,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -716,7 +717,7 @@ bool SVGFilter::implExportDocument() + SvtMiscOptions aMiscOptions; + const bool bExperimentalMode = aMiscOptions.IsExperimentalMode(); + +- mbSinglePage = (nLastPage == 0) || !bExperimentalMode; ++ mbSinglePage = ((nLastPage == 0) || !bExperimentalMode) && !comphelper::LibreOfficeKit::isActive(); + mnVisiblePage = -1; + + const Reference< XPropertySet > xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY ); +diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx +index e44c37d9136f..0f268c221fa7 100644 +--- a/filter/source/svg/svgfilter.cxx ++++ b/filter/source/svg/svgfilter.cxx +@@ -20,6 +20,7 @@ + + #include + ++#include + #include + #include + #include +@@ -105,15 +106,24 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto + { + // #i124608# detext selection + bool bSelectionOnly = false; +- bool bGotSelection(false); ++ bool bGotSelection = false; + +- // #i124608# extract Single selection wanted from dialog return values +- for ( sal_Int32 nInd = 0; nInd < rDescriptor.getLength(); nInd++ ) ++ // when using LibreOfficeKit, default to exporting everything (-1) ++ bool bPageProvided = comphelper::LibreOfficeKit::isActive(); ++ sal_Int32 nPageToExport = -1; ++ ++ for (sal_Int32 nInd = 0; nInd < rDescriptor.getLength(); nInd++) + { +- if ( rDescriptor[nInd].Name == "SelectionOnly" ) ++ if (rDescriptor[nInd].Name == "SelectionOnly") + { ++ // #i124608# extract single selection wanted from dialog return values + rDescriptor[nInd].Value >>= bSelectionOnly; + } ++ else if (rDescriptor[nInd].Name == "PagePos") ++ { ++ rDescriptor[nInd].Value >>= nPageToExport; ++ bPageProvided = true; ++ } + } + + uno::Reference< frame::XDesktop2 > xDesktop(frame::Desktop::create(mxContext)); +@@ -122,7 +132,7 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto + uno::Reference xController(xFrame->getController(), + uno::UNO_QUERY_THROW); + +- if( !mSelectedPages.hasElements() ) ++ if (!bPageProvided) + { + uno::Reference xDrawView(xController, + uno::UNO_QUERY_THROW); +@@ -188,18 +198,6 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto + */ + if( !mSelectedPages.hasElements() ) + { +- sal_Int32 nLength = rDescriptor.getLength(); +- const PropertyValue* pValue = rDescriptor.getConstArray(); +- sal_Int32 nPageToExport = -1; +- +- for ( sal_Int32 i = 0 ; i < nLength; ++i) +- { +- if ( pValue[ i ].Name == "PagePos" ) +- { +- pValue[ i ].Value >>= nPageToExport; +- } +- } +- + uno::Reference< drawing::XMasterPagesSupplier > xMasterPagesSupplier( mxSrcDoc, uno::UNO_QUERY ); + uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY ); + +-- +2.12.0 + diff --git a/SOURCES/0218-lok-Document-saveAs-add-Writer-Impress-Draw-png-mapp.patch b/SOURCES/0218-lok-Document-saveAs-add-Writer-Impress-Draw-png-mapp.patch new file mode 100644 index 0000000..6636cae --- /dev/null +++ b/SOURCES/0218-lok-Document-saveAs-add-Writer-Impress-Draw-png-mapp.patch @@ -0,0 +1,108 @@ +From b15cf8984c13436ce3d9c8ee58d9be075f7316dc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 20 Oct 2015 17:13:30 +0200 +Subject: [PATCH 218/398] lok::Document::saveAs: add Writer/Impress/Draw png + mapping + +Change-Id: I7530281302b9787a9cb9f98f0dee9d98d39cfb05 +(cherry picked from commit d42c3e0ddd9078c00de591b7470d73ad8a186cb1) +--- + desktop/CppunitTest_desktop_lib.mk | 2 ++ + desktop/qa/desktop_lib/test_desktop_lib.cxx | 11 +++++++++++ + desktop/source/lib/init.cxx | 3 +++ + 3 files changed, 16 insertions(+) + +diff --git a/desktop/CppunitTest_desktop_lib.mk b/desktop/CppunitTest_desktop_lib.mk +index 0c963f9088c2..a1f712585507 100644 +--- a/desktop/CppunitTest_desktop_lib.mk ++++ b/desktop/CppunitTest_desktop_lib.mk +@@ -26,6 +26,7 @@ $(eval $(call gb_CppunitTest_use_libraries,desktop_lib, \ + sw \ + test \ + unotest \ ++ utl \ + vcl \ + $(gb_UWINAPI) \ + )) +@@ -64,6 +65,7 @@ $(eval $(call gb_CppunitTest_use_components,desktop_lib,\ + unoxml/source/service/unoxml \ + xmloff/util/xo \ + i18npool/source/search/i18nsearch \ ++ filter/source/graphic/graphicfilter \ + )) + + $(eval $(call gb_CppunitTest_use_configuration,desktop_lib)) +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index df8723b8cedd..c3464a243a3c 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include "../../inc/lib/init.hxx" + +@@ -62,6 +63,7 @@ public: + void testGetPartPageRectangles(); + void testSearchCalc(); + void testPaintTile(); ++ void testSaveAs(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -71,6 +73,7 @@ public: + CPPUNIT_TEST(testGetPartPageRectangles); + CPPUNIT_TEST(testSearchCalc); + CPPUNIT_TEST(testPaintTile); ++ CPPUNIT_TEST(testSaveAs); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -309,6 +312,14 @@ void DesktopLOKTest::testPaintTile() + closeDoc(); + } + ++void DesktopLOKTest::testSaveAs() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ utl::TempFile aTempFile; ++ aTempFile.EnableKillingFile(); ++ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "png", 0)); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 053ab440bf55..97fb6f6a235c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -116,6 +116,7 @@ static const ExtensionMap aWriterExtensionMap[] = + { "pdf", "writer_pdf_Export" }, + { "txt", "Text" }, + { "xhtml", "XHTML Writer File" }, ++ { "png", "writer_png_Export" }, + { NULL, NULL } + }; + +@@ -149,6 +150,7 @@ static const ExtensionMap aImpressExtensionMap[] = + { "svg", "impress_svg_Export" }, + { "swf", "impress_flash_Export" }, + { "xhtml", "XHTML Impress File" }, ++ { "png", "impress_png_Export"}, + { NULL, NULL } + }; + +@@ -161,6 +163,7 @@ static const ExtensionMap aDrawExtensionMap[] = + { "svg", "draw_svg_Export" }, + { "swf", "draw_flash_Export" }, + { "xhtml", "XHTML Draw File" }, ++ { "png", "draw_png_Export"}, + { NULL, NULL } + }; + +-- +2.12.0 + diff --git a/SOURCES/0219-Add-DLOPEN_LIBS-to-configure-for-some-cases-where-ld.patch b/SOURCES/0219-Add-DLOPEN_LIBS-to-configure-for-some-cases-where-ld.patch new file mode 100644 index 0000000..0681d4a --- /dev/null +++ b/SOURCES/0219-Add-DLOPEN_LIBS-to-configure-for-some-cases-where-ld.patch @@ -0,0 +1,383 @@ +From 6f12d64c52776792604d9a7c7bc084f9d3044a84 Mon Sep 17 00:00:00 2001 +From: Richard PALO +Date: Tue, 15 Sep 2015 15:58:51 +0200 +Subject: [PATCH 219/398] Add DLOPEN_LIBS to configure for some cases where + -ldl is needed use std::sqrt in vcldemo.cxx + +Change-Id: I24d8ba15ee267d0cad3b063df9b7cfd8d284f4ee +Reviewed-on: https://gerrit.libreoffice.org/18591 +Tested-by: Jenkins +Reviewed-by: Norbert Thiebaud +(cherry picked from commit fd612a144c0028972513a18167a13d29326a1798) +--- + Repository.mk | 8 ++++---- + config_host.mk.in | 1 + + configure.ac | 9 +++++++++ + desktop/Library_sofficeapp.mk | 12 +++++------- + include/LibreOfficeKit/LibreOfficeKitInit.h | 4 +++- + libreofficekit/Executable_gtktiledviewer.mk | 5 ++--- + libreofficekit/Executable_tilebench.mk | 3 +-- + libreofficekit/Library_libreofficekitgtk.mk | 5 ++--- + libreofficekit/Module_libreofficekit.mk | 4 ++-- + svx/Executable_gengal.mk | 6 +++--- + vcl/Executable_icontest.mk | 5 ++--- + vcl/Executable_mtfdemo.mk | 5 ++--- + vcl/Executable_ui-previewer.mk | 5 ++--- + vcl/Executable_vcldemo.mk | 5 ++--- + vcl/Library_desktop_detector.mk | 5 ++--- + vcl/Library_vcl.mk | 7 +++---- + vcl/Module_vcl.mk | 2 +- + vcl/workben/vcldemo.cxx | 6 +++--- + 18 files changed, 49 insertions(+), 48 deletions(-) + +diff --git a/Repository.mk b/Repository.mk +index a84dc9a12211..dd0afca39b7a 100644 +--- a/Repository.mk ++++ b/Repository.mk +@@ -67,13 +67,13 @@ $(eval $(call gb_Helper_register_executables,NONE, \ + svptest \ + svpclient \ + pixelctl ) \ +- $(if $(and $(ENABLE_GTK), $(filter LINUX,$(OS))), tilebench) \ +- $(if $(filter LINUX MACOSX WNT,$(OS)),icontest \ ++ $(if $(and $(ENABLE_GTK), $(filter LINUX %BSD SOLARIS,$(OS))), tilebench) \ ++ $(if $(filter LINUX MACOSX SOLARIS WNT %BSD,$(OS)),icontest \ + outdevgrind) \ + vcldemo \ + tiledrendering \ + mtfdemo \ +- $(if $(and $(ENABLE_GTK), $(filter LINUX,$(OS))), gtktiledviewer) \ ++ $(if $(and $(ENABLE_GTK), $(filter LINUX %BSD SOLARIS,$(OS))), gtktiledviewer) \ + )) + + $(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \ +@@ -582,7 +582,7 @@ $(eval $(call gb_Helper_register_libraries_for_install,PLAINLIBS_OOO,ooo, \ + i18nlangtag \ + i18nutil \ + index_data \ +- $(if $(and $(ENABLE_GTK3), $(filter LINUX,$(OS))), libreofficekitgtk) \ ++ $(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), libreofficekitgtk) \ + localedata_en \ + localedata_es \ + localedata_euro \ +diff --git a/config_host.mk.in b/config_host.mk.in +index 5e5851e57da3..4ce14b085201 100644 +--- a/config_host.mk.in ++++ b/config_host.mk.in +@@ -99,6 +99,7 @@ export DISABLE_DYNLOADING=@DISABLE_DYNLOADING@ + export DISABLE_EXPORT=@DISABLE_EXPORT@ + export DISABLE_OPENSSL=@DISABLE_OPENSSL@ + export DISABLE_PYTHON=@DISABLE_PYTHON@ ++export DLOPEN_LIBS=@DLOPEN_LIBS@ + export DLLTOOL=@DLLTOOL@ + export DOCDIR=@DOCDIR@ + export DOXYGEN=@DOXYGEN@ +diff --git a/configure.ac b/configure.ac +index 12983e074c7d..f3fe04da124b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -822,6 +822,15 @@ AC_SUBST(WITH_MINGW) + AC_SUBST(PTHREAD_CFLAGS) + AC_SUBST(PTHREAD_LIBS) + ++if test $_os != "WINNT"; then ++ save_LIBS="$LIBS" ++ AC_SEARCH_LIBS([dlopen], [dl], ++ [case "$ac_cv_search_dlopen" in -l*) DLOPEN_LIBS="$ac_cv_search_dlopen";; esac], ++ [AC_MSG_ERROR([dlopen not found in either libc nor libdl])]) ++ LIBS="$save_LIBS" ++fi ++AC_SUBST(DLOPEN_LIBS) ++ + ############################################################################### + # Extensions switches --enable/--disable + ############################################################################### +diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk +index ccad5a7ea5ca..2e3acb79b3c6 100644 +--- a/desktop/Library_sofficeapp.mk ++++ b/desktop/Library_sofficeapp.mk +@@ -17,8 +17,8 @@ $(eval $(call gb_Library_set_include,sofficeapp,\ + )) + + $(eval $(call gb_Library_add_libs,sofficeapp,\ +- $(if $(filter $(OS),LINUX), \ +- -ldl \ ++ $(if $(filter LINUX %BSD SOLARIS, $(OS)), \ ++ $(DLOPEN_LIBS) \ + -lpthread \ + ) \ + )) +@@ -99,19 +99,17 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\ + + ifeq ($(ENABLE_HEADLESS),TRUE) + $(eval $(call gb_Library_add_libs,sofficeapp,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + )) + else +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Library_use_static_libraries,sofficeapp,\ + glxtest \ + )) + + $(eval $(call gb_Library_add_libs,sofficeapp,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ +diff --git a/include/LibreOfficeKit/LibreOfficeKitInit.h b/include/LibreOfficeKit/LibreOfficeKitInit.h +index c2f342661e31..f18e3ca3c8e4 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitInit.h ++++ b/include/LibreOfficeKit/LibreOfficeKitInit.h +@@ -17,7 +17,9 @@ extern "C" + { + #endif + +-#if defined(__linux__) || defined (__FreeBSD_kernel__) || defined(_AIX) || defined(_WIN32) || defined(__APPLE__) ++#if defined(__linux__) || defined (__FreeBSD_kernel__) || defined(_AIX) ||\ ++ defined(_WIN32) || defined(__APPLE__) || defined (__NetBSD__) ||\ ++ defined (__sun) + + #include + #include +diff --git a/libreofficekit/Executable_gtktiledviewer.mk b/libreofficekit/Executable_gtktiledviewer.mk +index 31028a67fafb..f6e297b5dbfe 100644 +--- a/libreofficekit/Executable_gtktiledviewer.mk ++++ b/libreofficekit/Executable_gtktiledviewer.mk +@@ -38,10 +38,9 @@ $(eval $(call gb_Executable_add_libs,gtktiledviewer,\ + -lICE \ + )) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Executable_add_libs,gtktiledviewer,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + )) + endif +diff --git a/libreofficekit/Executable_tilebench.mk b/libreofficekit/Executable_tilebench.mk +index 11e73dead0bd..4da51d3ca686 100644 +--- a/libreofficekit/Executable_tilebench.mk ++++ b/libreofficekit/Executable_tilebench.mk +@@ -20,8 +20,7 @@ $(eval $(call gb_Executable_use_libraries,tilebench,\ + )) + + $(eval $(call gb_Executable_add_libs,tilebench,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + )) + +diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk +index 7d25abf944b1..3eba939ad56c 100644 +--- a/libreofficekit/Library_libreofficekitgtk.mk ++++ b/libreofficekit/Library_libreofficekitgtk.mk +@@ -28,10 +28,9 @@ $(eval $(call gb_Library_add_libs,libreofficekitgtk,\ + $(GTK3_LIBS) \ + )) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS),$(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Library_add_libs,libreofficekitgtk,\ +- -ldl \ +- -lm \ ++ $(DLOPEN_LIBS) -lm \ + )) + endif + +diff --git a/libreofficekit/Module_libreofficekit.mk b/libreofficekit/Module_libreofficekit.mk +index 0b2fd4ae103d..7d1c5ead764e 100644 +--- a/libreofficekit/Module_libreofficekit.mk ++++ b/libreofficekit/Module_libreofficekit.mk +@@ -9,7 +9,7 @@ + + $(eval $(call gb_Module_Module,libreofficekit)) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + + $(eval $(call gb_Module_add_subsequentcheck_targets,libreofficekit,\ + CppunitTest_libreofficekit_tiledrendering \ +@@ -23,6 +23,6 @@ $(eval $(call gb_Module_add_targets,libreofficekit,\ + )) + endif # ($(ENABLE_GTK3),) + +-endif # ($(OS),LINUX) ++endif + + # vim: set ts=4 sw=4 et: +diff --git a/svx/Executable_gengal.mk b/svx/Executable_gengal.mk +index 38d5697f32a2..e075b0522d2a 100644 +--- a/svx/Executable_gengal.mk ++++ b/svx/Executable_gengal.mk +@@ -63,13 +63,13 @@ endif + + ifeq ($(ENABLE_HEADLESS),TRUE) + $(eval $(call gb_Executable_add_libs,gengal,\ +- -ldl \ ++ $(DLOPEN_LIBS) \ + -lpthread \ + )) + else +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Executable_add_libs,gengal,\ +- -ldl \ ++ $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ +diff --git a/vcl/Executable_icontest.mk b/vcl/Executable_icontest.mk +index 11cc69d086fc..e9a30f8a2076 100644 +--- a/vcl/Executable_icontest.mk ++++ b/vcl/Executable_icontest.mk +@@ -25,10 +25,9 @@ $(eval $(call gb_Executable_use_static_libraries,icontest,\ + vclmain \ + )) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Executable_add_libs,icontest,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ +diff --git a/vcl/Executable_mtfdemo.mk b/vcl/Executable_mtfdemo.mk +index 52af4a309040..01156f82296a 100644 +--- a/vcl/Executable_mtfdemo.mk ++++ b/vcl/Executable_mtfdemo.mk +@@ -40,10 +40,9 @@ $(eval $(call gb_Executable_use_static_libraries,mtfdemo,\ + vclmain \ + )) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Executable_add_libs,mtfdemo,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ +diff --git a/vcl/Executable_ui-previewer.mk b/vcl/Executable_ui-previewer.mk +index 9aa4fa3bb0cb..4ef1b05c9fcb 100644 +--- a/vcl/Executable_ui-previewer.mk ++++ b/vcl/Executable_ui-previewer.mk +@@ -34,10 +34,9 @@ $(eval $(call gb_Executable_add_exception_objects,ui-previewer,\ + vcl/source/uipreviewer/previewer \ + )) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Executable_add_libs,ui-previewer,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ +diff --git a/vcl/Executable_vcldemo.mk b/vcl/Executable_vcldemo.mk +index 3aee6ac11dc9..5dc630bcb5e7 100644 +--- a/vcl/Executable_vcldemo.mk ++++ b/vcl/Executable_vcldemo.mk +@@ -46,10 +46,9 @@ $(eval $(call gb_Executable_use_static_libraries,vcldemo,\ + vclmain \ + )) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Executable_add_libs,vcldemo,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ +diff --git a/vcl/Library_desktop_detector.mk b/vcl/Library_desktop_detector.mk +index 6baf4abcb346..3edd0015e243 100644 +--- a/vcl/Library_desktop_detector.mk ++++ b/vcl/Library_desktop_detector.mk +@@ -63,10 +63,9 @@ $(eval $(call gb_Library_add_exception_objects,desktop_detector,\ + vcl/unx/generic/desktopdetect/desktopdetector \ + )) + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Library_add_libs,desktop_detector,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + )) + endif +diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk +index c6b33e64272d..7a9a6053ab32 100644 +--- a/vcl/Library_vcl.mk ++++ b/vcl/Library_vcl.mk +@@ -58,7 +58,7 @@ $(eval $(call gb_Library_use_custom_headers,vcl,\ + )) + + $(eval $(call gb_Library_use_externals,vcl,\ +- $(if $(filter LINUX MACOSX,$(OS)), \ ++ $(if $(filter LINUX MACOSX %BSD SOLARIS,$(OS)), \ + curl) \ + jpeg \ + $(if $(filter-out WNT,$(OS)), \ +@@ -718,10 +718,9 @@ $(eval $(call gb_Library_use_system_win32_libs,vcl,\ + $(eval $(call gb_Library_add_nativeres,vcl,vcl/salsrc)) + endif + +-ifeq ($(OS),LINUX) ++ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Library_add_libs,vcl,\ +- -lm \ +- -ldl \ ++ -lm $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ +diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk +index 93a944605177..8a1dce995d19 100644 +--- a/vcl/Module_vcl.mk ++++ b/vcl/Module_vcl.mk +@@ -27,7 +27,7 @@ $(eval $(call gb_Module_add_targets,vcl,\ + StaticLibrary_vclmain \ + $(if $(ENABLE_HEADLESS),, \ + Executable_ui-previewer) \ +- $(if $(filter LINUX MACOSX WNT,$(OS)), \ ++ $(if $(filter LINUX MACOSX SOLARIS WNT %BSD,$(OS)), \ + Executable_outdevgrind \ + $(if $(ENABLE_HEADLESS),, \ + Executable_vcldemo \ +diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx +index fd8c01f8ab57..82bb86998ce8 100644 +--- a/vcl/workben/vcldemo.cxx ++++ b/vcl/workben/vcldemo.cxx +@@ -141,11 +141,11 @@ public: + maIntroBW.Filter(BMP_FILTER_EMBOSS_GREY); + + InitRenderers(); +- mnSegmentsX = rtl::math::round(sqrt(maRenderers.size()), 0, ++ mnSegmentsX = rtl::math::round(std::sqrt(maRenderers.size()), 0, + rtl_math_RoundingMode_Up); +- mnSegmentsY = rtl::math::round(sqrt(maRenderers.size()), 0, ++ mnSegmentsY = rtl::math::round(std::sqrt(maRenderers.size()), 0, + rtl_math_RoundingMode_Down); +- mnSegmentsY = floor(sqrt(maRenderers.size())); ++ mnSegmentsY = floor(std::sqrt(maRenderers.size())); + } + + OUString getRendererList(); +-- +2.12.0 + diff --git a/SOURCES/0220-sc-initial-png-export.patch b/SOURCES/0220-sc-initial-png-export.patch new file mode 100644 index 0000000..36a94ed --- /dev/null +++ b/SOURCES/0220-sc-initial-png-export.patch @@ -0,0 +1,139 @@ +From f141fd351034d8e7210cf95973052149c84c2234 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 20 Oct 2015 18:12:22 +0200 +Subject: [PATCH 220/398] sc: initial png export + +Change-Id: Iae0e89646eab794879529274f09839ad34aa4696 +(cherry picked from commit 03bb5d52fecd6c613c6cc36508eb44e5e1c3456a) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 10 ++++++++++ + desktop/source/lib/init.cxx | 1 + + filter/Configuration_filter.mk | 9 +++++++++ + .../config/fragments/filters/calc_png_Export.xcu | 20 ++++++++++++++++++++ + postprocess/CustomTarget_registry.mk | 2 ++ + svtools/source/filter/DocumentToGraphicRenderer.cxx | 2 ++ + 6 files changed, 44 insertions(+) + create mode 100644 filter/source/config/fragments/filters/calc_png_Export.xcu + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index c3464a243a3c..3730fd106362 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -64,6 +64,7 @@ public: + void testSearchCalc(); + void testPaintTile(); + void testSaveAs(); ++ void testSaveAsCalc(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -74,6 +75,7 @@ public: + CPPUNIT_TEST(testSearchCalc); + CPPUNIT_TEST(testPaintTile); + CPPUNIT_TEST(testSaveAs); ++ CPPUNIT_TEST(testSaveAsCalc); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -320,6 +322,14 @@ void DesktopLOKTest::testSaveAs() + CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "png", 0)); + } + ++void DesktopLOKTest::testSaveAsCalc() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("search.ods"); ++ utl::TempFile aTempFile; ++ aTempFile.EnableKillingFile(); ++ CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "png", 0)); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 97fb6f6a235c..01fe099ccbe9 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -131,6 +131,7 @@ static const ExtensionMap aCalcExtensionMap[] = + { "xhtml", "XHTML Calc File" }, + { "xls", "MS Excel 97" }, + { "xlsx", "Calc MS Excel 2007 XML" }, ++ { "png", "calc_png_Export" }, + { NULL, NULL } + }; + +diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk +index 29e672bee4d2..0a0dddbe4c5a 100644 +--- a/filter/Configuration_filter.mk ++++ b/filter/Configuration_filter.mk +@@ -837,6 +837,15 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_writergraphics + writer_png_Export \ + )) + ++# fcfg_calcgraphics ++$(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_calcgraphics_types.xcu,filter/source/config/fragments/types,\ ++ png_Portable_Network_Graphic \ ++)) ++ ++$(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_calcgraphics_filters.xcu,filter/source/config/fragments/filters,\ ++ calc_png_Export \ ++)) ++ + # fcfg_internalgraphics + $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_internalgraphics_types.xcu,filter/source/config/fragments/types,\ + bmp_MS_Windows \ +diff --git a/filter/source/config/fragments/filters/calc_png_Export.xcu b/filter/source/config/fragments/filters/calc_png_Export.xcu +new file mode 100644 +index 000000000000..999bef299a75 +--- /dev/null ++++ b/filter/source/config/fragments/filters/calc_png_Export.xcu +@@ -0,0 +1,20 @@ ++ ++ ++ EXPORT ALIEN 3RDPARTYFILTER ++ com.sun.star.comp.GraphicExportDialog ++ com.sun.star.comp.GraphicExportFilter ++ ++ ++ PNG - Portable Network Graphic ++ ++ 0 ++ png_Portable_Network_Graphic ++ ++ com.sun.star.sheet.SpreadsheetDocument ++ +diff --git a/postprocess/CustomTarget_registry.mk b/postprocess/CustomTarget_registry.mk +index 2502011863f8..0a46d6650052 100644 +--- a/postprocess/CustomTarget_registry.mk ++++ b/postprocess/CustomTarget_registry.mk +@@ -87,6 +87,8 @@ postprocess_FILES_graphicfilter := \ + $(call gb_XcuFilterTypesTarget_get_target,fcfg_drawgraphics_types.xcu) \ + $(call gb_XcuFilterFiltersTarget_get_target,fcfg_impressgraphics_filters.xcu) \ + $(call gb_XcuFilterTypesTarget_get_target,fcfg_impressgraphics_types.xcu) \ ++ $(call gb_XcuFilterFiltersTarget_get_target,fcfg_calcgraphics_filters.xcu) \ ++ $(call gb_XcuFilterTypesTarget_get_target,fcfg_calcgraphics_types.xcu) \ + $(call gb_XcuFilterFiltersTarget_get_target,fcfg_writergraphics_filters.xcu) \ + $(call gb_XcuFilterTypesTarget_get_target,fcfg_writergraphics_types.xcu) + +diff --git a/svtools/source/filter/DocumentToGraphicRenderer.cxx b/svtools/source/filter/DocumentToGraphicRenderer.cxx +index e33a94ec416e..e78b0f1ad8ab 100644 +--- a/svtools/source/filter/DocumentToGraphicRenderer.cxx ++++ b/svtools/source/filter/DocumentToGraphicRenderer.cxx +@@ -148,6 +148,8 @@ Graphic DocumentToGraphicRenderer::renderToGraphic( + sal_Int32 DocumentToGraphicRenderer::getCurrentPageWriter() + { + Reference xTextViewCursorSupplier(mxModel->getCurrentController(), UNO_QUERY); ++ if (!xTextViewCursorSupplier.is()) ++ return 1; + Reference xCursor(xTextViewCursorSupplier->getViewCursor(), UNO_QUERY); + return xCursor->getPage(); + } +-- +2.12.0 + diff --git a/SOURCES/0221-lokdocview-Use-G_PARAM_STATIC_STRINGS.patch b/SOURCES/0221-lokdocview-Use-G_PARAM_STATIC_STRINGS.patch new file mode 100644 index 0000000..653e5ef --- /dev/null +++ b/SOURCES/0221-lokdocview-Use-G_PARAM_STATIC_STRINGS.patch @@ -0,0 +1,136 @@ +From 8d464eb04df9fe579f8ee24a476c18af8afe3fcb Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Mon, 19 Oct 2015 22:36:12 +0530 +Subject: [PATCH 221/398] lokdocview: Use G_PARAM_STATIC_STRINGS + +... as `name`, `nick`, and `blurb` are guaranteed to remain valid +and unmodified for the lifetime of the parameters. + +Change-Id: Ic6463b470546669d5a815842daedb170df85d161 +Reviewed-on: https://gerrit.libreoffice.org/19472 +Reviewed-by: Miklos Vajna +Tested-by: Miklos Vajna +(cherry picked from commit d2d5a00e0e3972c0021e2e664301a32da6e54c1a) +--- + libreofficekit/source/gtk/lokdocview.cxx | 42 ++++++++++++++++++++------------ + 1 file changed, 26 insertions(+), 16 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 4af48bbea5a5..dc1ae5544558 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1638,8 +1638,9 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "LO Path", + "LibreOffice Install Path", + 0, +- static_cast(G_PARAM_READWRITE +- | G_PARAM_CONSTRUCT_ONLY))); ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:lopointer: +@@ -1650,10 +1651,11 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_object_class_install_property (pGObjectClass, + PROP_LO_POINTER, + g_param_spec_pointer("lopointer", +- "LO Pointer", +- "A LibreOfficeKit* from lok_init()", +- static_cast(G_PARAM_READWRITE +- | G_PARAM_CONSTRUCT_ONLY))); ++ "LO Pointer", ++ "A LibreOfficeKit* from lok_init()", ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:docpath: +@@ -1666,7 +1668,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Document Path", + "The URI of the document to open", + 0, +- static_cast(G_PARAM_READWRITE))); ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:docpointer: +@@ -1677,9 +1680,10 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_object_class_install_property (pGObjectClass, + PROP_DOC_POINTER, + g_param_spec_pointer("docpointer", +- "Document Pointer", +- "A LibreOfficeKitDocument* from documentLoad()", +- static_cast(G_PARAM_READWRITE))); ++ "Document Pointer", ++ "A LibreOfficeKitDocument* from documentLoad()", ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:editable: +@@ -1692,7 +1696,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Editable", + "Whether the content is in edit mode or not", + FALSE, +- static_cast(G_PARAM_READWRITE))); ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:load-progress: +@@ -1708,7 +1713,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Estimated Load Progress", + "Shows the progress of the document load operation", + 0.0, 1.0, 0.0, +- G_PARAM_READABLE)); ++ static_cast(G_PARAM_READABLE | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:zoom-level: +@@ -1723,7 +1729,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "The current zoom level of the content", + 0, 5.0, 1.0, + static_cast(G_PARAM_READWRITE | +- G_PARAM_CONSTRUCT))); ++ G_PARAM_CONSTRUCT | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:is-loading: +@@ -1737,7 +1744,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Is Loading", + "Whether the view is loading a document", + FALSE, +- static_cast(G_PARAM_READABLE))); ++ static_cast(G_PARAM_READABLE | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:doc-width: +@@ -1750,7 +1758,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Document Width", + "Width of the document in twips", + 0, G_MAXLONG, 0, +- static_cast(G_PARAM_READWRITE))); ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:doc-height: +@@ -1763,7 +1772,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "Document Height", + "Height of the document in twips", + 0, G_MAXLONG, 0, +- static_cast(G_PARAM_READWRITE))); ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS))); + + /** + * LOKDocView:can-zoom-in: +-- +2.12.0 + diff --git a/SOURCES/0222-lok-Avoid-adding-to-recent-documents-completely.patch b/SOURCES/0222-lok-Avoid-adding-to-recent-documents-completely.patch new file mode 100644 index 0000000..3b2ea55 --- /dev/null +++ b/SOURCES/0222-lok-Avoid-adding-to-recent-documents-completely.patch @@ -0,0 +1,59 @@ +From 03ea9bee49bbd6961677ab020695f8d2f7af9d4e Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Wed, 21 Oct 2015 09:21:34 +0200 +Subject: [PATCH 222/398] lok: Avoid adding to recent documents completely. + +(cherry picked from commit dcdba6ed8984fd135a346a921b3a7888ecef9cb0) + +Change-Id: I292281e300e8976bf5ae286262a6a3e20de41858 +--- + sfx2/source/appl/sfxpicklist.cxx | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/sfx2/source/appl/sfxpicklist.cxx b/sfx2/source/appl/sfxpicklist.cxx +index 0f3196df45cc..24754ca01b74 100644 +--- a/sfx2/source/appl/sfxpicklist.cxx ++++ b/sfx2/source/appl/sfxpicklist.cxx +@@ -19,6 +19,7 @@ + + #include + ++#include + #include + #include + #include +@@ -161,6 +162,9 @@ SfxPickList::PickListEntry* SfxPickList::GetPickListEntry( sal_uInt32 nIndex ) + + void SfxPickList::AddDocumentToPickList( SfxObjectShell* pDocSh ) + { ++ if (comphelper::LibreOfficeKit::isActive()) ++ return; ++ + SfxMedium *pMed = pDocSh->GetMedium(); + if( !pMed ) + return; +@@ -193,10 +197,9 @@ void SfxPickList::AddDocumentToPickList( SfxObjectShell* pDocSh ) + if ( pFilter ) + aFilter = pFilter->GetFilterName(); + +- // generate a thumbnail + boost::optional aThumbnail; +- // don't generate thumbnail when in headless mode, or on non-desktop (?) +-#if HAVE_FEATURE_DESKTOP ++ ++ // generate the thumbnail + if (!pDocSh->IsModified() && !Application::IsHeadlessModeEnabled()) + { + // not modified => the document matches what is in the shell +@@ -224,7 +227,7 @@ void SfxPickList::AddDocumentToPickList( SfxObjectShell* pDocSh ) + } + } + } +-#endif ++ + // add to svtool history options + SvtHistoryOptions().AppendItem( ePICKLIST, + aURL.GetURLNoPass( INetURLObject::NO_DECODE ), +-- +2.12.0 + diff --git a/SOURCES/0223-lokdocview-Emit-a-warning-after-error.patch b/SOURCES/0223-lokdocview-Emit-a-warning-after-error.patch new file mode 100644 index 0000000..8c1af5b --- /dev/null +++ b/SOURCES/0223-lokdocview-Emit-a-warning-after-error.patch @@ -0,0 +1,330 @@ +From d70bb33567306d21142c13e0de8a1db91a5df5d2 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 20 Oct 2015 01:02:56 +0530 +Subject: [PATCH 223/398] lokdocview: Emit a warning after error + +Change-Id: Id8e20e6561239096438d420c65d0da6dcc7f5e2e +Reviewed-on: https://gerrit.libreoffice.org/19474 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit 54409159b8a12ca3d387e2ff2a2e1ff9dad1a2a3) +--- + libreofficekit/source/gtk/lokdocview.cxx | 106 +++++++++++++++++++++++++++---- + libreofficekit/source/gtk/tilebuffer.cxx | 23 ++++++- + 2 files changed, 112 insertions(+), 17 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index dc1ae5544558..bbb87115fa4f 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -266,6 +266,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + int nCharCode = 0; + int nKeyCode = 0; ++ GError* error = NULL; + + if (!priv->m_bEdit) + { +@@ -339,7 +340,12 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_POST_KEY: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + } + else +@@ -350,7 +356,12 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_POST_KEY: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + } + +@@ -950,6 +961,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ GError* error = NULL; + + g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", + (int)pEvent->x, (int)pEvent->y, +@@ -992,7 +1004,12 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + + return FALSE; +@@ -1011,7 +1028,12 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + + return FALSE; +@@ -1060,7 +1082,12 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + + return FALSE; +@@ -1102,7 +1129,12 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + priv->m_nLastButtonPressed = pLOEvent->m_nPostMouseEventButton; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_POST_MOUSE_EVENT: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + break; + } +@@ -1134,7 +1166,12 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + priv->m_nLastButtonPressed = pLOEvent->m_nPostMouseEventButton; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_POST_MOUSE_EVENT: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + break; + } +@@ -1168,6 +1205,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GdkPoint aPoint; ++ GError* error = NULL; + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + if (priv->m_bInDragMiddleHandle) +@@ -1222,7 +1260,12 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + + return FALSE; +@@ -1241,7 +1284,12 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_MOUSEEVENT_MOUSEMOVE: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + + return FALSE; +@@ -1986,6 +2034,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + { + GTask* task = g_task_new(pDocView, cancellable, callback, userdata); + LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ GError* error = NULL; + + LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC); + pLOEvent->m_pPath = pPath; +@@ -1993,7 +2042,12 @@ lok_doc_view_open_document (LOKDocView* pDocView, + priv->m_aDocPath = pPath; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_LOAD_DOC: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + } + +@@ -2051,11 +2105,17 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); ++ GError* error = NULL; + + pLOEvent->m_nPart = nPart; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_PART: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + } + +@@ -2074,10 +2134,16 @@ lok_doc_view_set_partmode(LOKDocView* pDocView, + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); ++ GError* error = NULL; + pLOEvent->m_nPartMode = nPartMode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_PARTMODE: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + } + +@@ -2133,10 +2199,16 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); ++ GError* error = NULL; + pLOEvent->m_bEdit = bEdit; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_EDIT: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + } + +@@ -2156,11 +2228,17 @@ lok_doc_view_post_command (LOKDocView* pDocView, + LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); ++ GError* error = NULL; + pLOEvent->m_pCommand = pCommand; + pLOEvent->m_pArguments = g_strdup(pArguments); + + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_POST_COMMAND: %s", error->message); ++ g_clear_error(&error); ++ } + g_object_unref(task); + } + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 992f06cd5e00..2f4e6cf123c1 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -61,6 +61,7 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, + GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; ++ GError* error = NULL; + if (m_mTiles.find(index) != m_mTiles.end()) + { + m_mTiles[index].valid = false; +@@ -70,7 +71,12 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, + pLOEvent->m_nPaintTileY = y; + pLOEvent->m_fPaintTileZoom = fZoom; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_PAINT_TILE: %s", error->message); ++ g_clear_error(&error); ++ } + } + } + +@@ -78,6 +84,7 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; ++ GError* error = NULL; + + if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid) + { +@@ -86,7 +93,12 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + pLOEvent->m_nPaintTileY = y; + pLOEvent->m_fPaintTileZoom = fZoom; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_PAINT_TILE: %s", error->message); ++ g_clear_error(&error); ++ } + return m_mTiles[index]; + } + else if(m_mTiles.find(index) == m_mTiles.end()) +@@ -96,7 +108,12 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + pLOEvent->m_nPaintTileY = y; + pLOEvent->m_fPaintTileZoom = fZoom; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- g_thread_pool_push(lokThreadPool, g_object_ref(task), NULL); ++ g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_PAINT_TILE: %s", error->message); ++ g_clear_error(&error); ++ } + return m_DummyTile; + } + +-- +2.12.0 + diff --git a/SOURCES/0224-vcl-add-ITiledRenderable-getWindow-and-implement-in-.patch b/SOURCES/0224-vcl-add-ITiledRenderable-getWindow-and-implement-in-.patch new file mode 100644 index 0000000..8c49039 --- /dev/null +++ b/SOURCES/0224-vcl-add-ITiledRenderable-getWindow-and-implement-in-.patch @@ -0,0 +1,68 @@ +From 48e3532611ca0d7de71f9796bf3e8bf3263929dd Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 22 Oct 2015 10:15:34 +0200 +Subject: [PATCH 224/398] vcl: add ITiledRenderable::getWindow() and implement + in sw + +(cherry picked from commit 981a974824642a81f86c526dea682cd27cd437db) + +Change-Id: I9d0fad3904e74b44b0b126974ace4025f7a4fc5b +--- + include/vcl/ITiledRenderable.hxx | 6 ++++++ + sw/inc/unotxdoc.hxx | 4 +++- + sw/source/uibase/uno/unotxdoc.cxx | 7 +++++++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index c294d20dc9cf..bb891ab97f7b 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -147,6 +147,12 @@ public: + { + return OUString(); + } ++ ++ /// Returns the current vcl::Window of the component. ++ virtual vcl::Window* getWindow() ++ { ++ return 0; ++ } + }; + + } // namespace vcl +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index 346cab63ca02..d0eada25b6ef 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -433,7 +433,9 @@ public: + /// @see vcl::ITiledRenderable::resetSelection(). + virtual void resetSelection() SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::getPartPageRectangles(). +- virtual OUString getPartPageRectangles() SAL_OVERRIDE; ++ virtual OUString getPartPageRectangles() override; ++ /// @see vcl::ITiledRenderable::getWindow(). ++ virtual vcl::Window* getWindow() override; + + // ::com::sun::star::tiledrendering::XTiledRenderable + virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) SAL_OVERRIDE; +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index fc1c6f411b74..658057d7a977 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3188,6 +3188,13 @@ OUString SwXTextDocument::getPartPageRectangles() + return pWrtShell->getPageRectangles(); + } + ++vcl::Window* SwXTextDocument::getWindow() ++{ ++ SolarMutexGuard aGuard; ++ ++ return &pDocShell->GetView()->GetEditWin(); ++} ++ + int SwXTextDocument::getPart() + { + SolarMutexGuard aGuard; +-- +2.12.0 + diff --git a/SOURCES/0225-LOK-add-Document-paste.patch b/SOURCES/0225-LOK-add-Document-paste.patch new file mode 100644 index 0000000..fd28b91 --- /dev/null +++ b/SOURCES/0225-LOK-add-Document-paste.patch @@ -0,0 +1,311 @@ +From 89ad7ba2b6f480c20d332bc3c171045afe21e23b Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 22 Oct 2015 11:26:13 +0200 +Subject: [PATCH 225/398] LOK: add Document::paste() + +Change-Id: I34998229e7f5cac4c62c859861783be3c161f9bf +(cherry picked from commit 6552767aa5ed61215eb64dac0cc026a5f7a9aad1) +--- + desktop/Library_sofficeapp.mk | 2 + + desktop/source/lib/init.cxx | 38 ++++++++++++++ + desktop/source/lib/lokclipboard.cxx | 83 +++++++++++++++++++++++++++++++ + desktop/source/lib/lokclipboard.hxx | 58 +++++++++++++++++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 6 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 12 +++++ + 6 files changed, 199 insertions(+) + create mode 100644 desktop/source/lib/lokclipboard.cxx + create mode 100644 desktop/source/lib/lokclipboard.hxx + +diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk +index 2e3acb79b3c6..fb73cfa78f4b 100644 +--- a/desktop/Library_sofficeapp.mk ++++ b/desktop/Library_sofficeapp.mk +@@ -122,6 +122,7 @@ ifneq ($(filter $(OS),ANDROID IOS),) + $(eval $(call gb_Library_add_exception_objects,sofficeapp,\ + desktop/source/lib/init \ + desktop/source/lib/lokinteractionhandler \ ++ desktop/source/lib/lokclipboard \ + $(if $(filter $(OS),ANDROID), \ + desktop/source/lib/lokandroid) \ + )) +@@ -130,6 +131,7 @@ ifeq ($(GUIBASE),unx) + $(eval $(call gb_Library_add_exception_objects,sofficeapp,\ + desktop/source/lib/init \ + desktop/source/lib/lokinteractionhandler \ ++ desktop/source/lib/lokclipboard \ + )) + endif + endif +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 01fe099ccbe9..0459176c24a0 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -78,6 +79,7 @@ + #include "../../inc/lib/init.hxx" + + #include "lokinteractionhandler.hxx" ++#include + + using namespace css; + using namespace vcl; +@@ -246,6 +248,10 @@ static void doc_setTextSelection (LibreOfficeKitDocument* pThis, + static char* doc_getTextSelection(LibreOfficeKitDocument* pThis, + const char* pMimeType, + char** pUsedMimeType); ++static bool doc_paste(LibreOfficeKitDocument* pThis, ++ const char* pMimeType, ++ const char* pData, ++ size_t nSize); + static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + int nType, + int nX, +@@ -286,6 +292,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference postUnoCommand = doc_postUnoCommand; + m_pDocumentClass->setTextSelection = doc_setTextSelection; + m_pDocumentClass->getTextSelection = doc_getTextSelection; ++ m_pDocumentClass->paste = doc_paste; + m_pDocumentClass->setGraphicSelection = doc_setGraphicSelection; + m_pDocumentClass->resetSelection = doc_resetSelection; + m_pDocumentClass->getCommandValues = doc_getCommandValues; +@@ -989,6 +996,37 @@ static char* doc_getTextSelection(LibreOfficeKitDocument* pThis, const char* pMi + return pMemory; + } + ++static bool doc_paste(LibreOfficeKitDocument* pThis, const char* pMimeType, const char* pData, size_t nSize) ++{ ++ ITiledRenderable* pDoc = getTiledRenderable(pThis); ++ if (!pDoc) ++ { ++ gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; ++ return false; ++ } ++ ++ uno::Reference xTransferable(new LOKTransferable(pMimeType, pData, nSize)); ++ uno::Reference xClipboard(new LOKClipboard()); ++ xClipboard->setContents(xTransferable, uno::Reference()); ++ vcl::Window* pWindow = pDoc->getWindow(); ++ if (!pWindow) ++ { ++ gImpl->maLastExceptionMsg = "Document did not provide a window"; ++ return false; ++ } ++ ++ pWindow->SetClipboard(xClipboard); ++ OUString aCommand(".uno:Paste"); ++ uno::Sequence aPropertyValues; ++ if (!comphelper::dispatchCommand(aCommand, aPropertyValues)) ++ { ++ gImpl->maLastExceptionMsg = "Failed to dispatch the .uno: command"; ++ return false; ++ } ++ ++ return true; ++} ++ + static void doc_setGraphicSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY) + { + ITiledRenderable* pDoc = getTiledRenderable(pThis); +diff --git a/desktop/source/lib/lokclipboard.cxx b/desktop/source/lib/lokclipboard.cxx +new file mode 100644 +index 000000000000..a81902b15b6b +--- /dev/null ++++ b/desktop/source/lib/lokclipboard.cxx +@@ -0,0 +1,83 @@ ++/* -*- 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 ++ ++using namespace com::sun::star; ++ ++uno::Reference SAL_CALL LOKClipboard::getContents() ++throw (uno::RuntimeException, std::exception) ++{ ++ return m_xTransferable; ++} ++ ++void SAL_CALL LOKClipboard::setContents(const uno::Reference& xTransferable, ++ const uno::Reference& /*xClipboardOwner*/) ++throw (uno::RuntimeException, std::exception) ++{ ++ m_xTransferable = xTransferable; ++} ++ ++OUString SAL_CALL LOKClipboard::getName() throw (uno::RuntimeException, std::exception) ++{ ++ return OUString(); ++} ++ ++LOKTransferable::LOKTransferable(const char* pMimeType, const char* pData, size_t nSize) ++ : m_aMimeType(pMimeType), ++ m_aText(pData, nSize) ++{ ++} ++ ++uno::Any SAL_CALL LOKTransferable::getTransferData(const datatransfer::DataFlavor& rFlavor) ++throw(datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException, std::exception) ++{ ++ uno::Any aRet; ++ if (m_aMimeType == "text/plain;charset=utf-8" && rFlavor.MimeType == "text/plain;charset=utf-16") ++ aRet <<= OStringToOUString(m_aText, RTL_TEXTENCODING_UTF8); ++ return aRet; ++} ++ ++std::vector LOKTransferable::getTransferDataFlavorsAsVector() ++{ ++ std::vector aRet; ++ datatransfer::DataFlavor aFlavor; ++ aFlavor.MimeType = OUString::fromUtf8(m_aMimeType.getStr()); ++ aFlavor.DataType = cppu::UnoType< uno::Sequence >::get(); ++ ++ sal_Int32 nIndex(0); ++ if (m_aMimeType.getToken(0, ';', nIndex) == "text/plain") ++ { ++ if (m_aMimeType.getToken(0, ';', nIndex) != "charset=utf-16") ++ aFlavor.MimeType = "text/plain;charset=utf-16"; ++ aFlavor.DataType = cppu::UnoType::get(); ++ } ++ aRet.push_back(aFlavor); ++ ++ return aRet; ++} ++ ++uno::Sequence SAL_CALL LOKTransferable::getTransferDataFlavors() ++throw(uno::RuntimeException, std::exception) ++{ ++ return comphelper::containerToSequence(getTransferDataFlavorsAsVector()); ++} ++ ++sal_Bool SAL_CALL LOKTransferable::isDataFlavorSupported(const datatransfer::DataFlavor& rFlavor) ++throw(uno::RuntimeException, std::exception) ++{ ++ const std::vector aFlavors = getTransferDataFlavorsAsVector(); ++ return std::find_if(aFlavors.begin(), aFlavors.end(), [&rFlavor](const datatransfer::DataFlavor& i) ++ { ++ return i.MimeType == rFlavor.MimeType && i.DataType == rFlavor.DataType; ++ }) != aFlavors.end(); ++} ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/desktop/source/lib/lokclipboard.hxx b/desktop/source/lib/lokclipboard.hxx +new file mode 100644 +index 000000000000..b982e1c734ee +--- /dev/null ++++ b/desktop/source/lib/lokclipboard.hxx +@@ -0,0 +1,58 @@ ++/* -*- 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/. ++ */ ++ ++#ifndef INCLUDED_DESKTOP_SOURCE_LIB_LOKCLIPBOARD_HXX ++#define INCLUDED_DESKTOP_SOURCE_LIB_LOKCLIPBOARD_HXX ++ ++#include ++ ++#include ++#include ++ ++/// A clipboard implementation for LibreOfficeKit. ++class LOKClipboard : public cppu::WeakImplHelper ++{ ++ css::uno::Reference m_xTransferable; ++ ++public: ++ virtual css::uno::Reference SAL_CALL getContents() ++ throw(css::uno::RuntimeException, std::exception) override; ++ ++ virtual void SAL_CALL setContents(const css::uno::Reference& xTransferable, ++ const css::uno::Reference& xClipboardOwner) ++ throw(css::uno::RuntimeException, std::exception) override; ++ ++ virtual OUString SAL_CALL getName() throw(css::uno::RuntimeException, std::exception) override; ++}; ++ ++/// Represents the contents of LOKClipboard. ++class LOKTransferable : public cppu::WeakImplHelper ++{ ++ OString m_aMimeType; ++ OString m_aText; ++ ++ /// Provides a list of flavors, used by getTransferDataFlavors() and isDataFlavorSupported(). ++ std::vector getTransferDataFlavorsAsVector(); ++ ++public: ++ LOKTransferable(const char* pMimeType, const char* pData, size_t nSize); ++ ++ virtual css::uno::Any SAL_CALL getTransferData(const css::datatransfer::DataFlavor& rFlavor) ++ throw(css::datatransfer::UnsupportedFlavorException, css::io::IOException, css::uno::RuntimeException, std::exception) override; ++ ++ virtual css::uno::Sequence SAL_CALL getTransferDataFlavors() ++ throw(css::uno::RuntimeException, std::exception) override; ++ ++ virtual sal_Bool SAL_CALL isDataFlavorSupported(const css::datatransfer::DataFlavor& rFlavor) ++ throw(css::uno::RuntimeException, std::exception) override; ++}; ++ ++#endif ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 83dcc9803d8a..d83717b4a809 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -157,6 +157,12 @@ struct _LibreOfficeKitDocumentClass + const char* pMimeType, + char** pUsedMimeType); + ++ /// @see lok::Document::paste(). ++ bool (*paste) (LibreOfficeKitDocument* pThis, ++ const char* pMimeType, ++ const char* pData, ++ size_t nSize); ++ + /// @see lok::Document::setGraphicSelection + void (*setGraphicSelection) (LibreOfficeKitDocument* pThis, + int nType, +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index e9167c510110..db7807d999ea 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -247,6 +247,18 @@ public: + } + + /** ++ * Pastes content at the current cursor position. ++ * ++ * @param pMimeType format of pData, for example text/plain;charset=utf-8. ++ * @param pData the actual data to be pasted. ++ * @return if the supplied data was pasted successfully. ++ */ ++ inline bool paste(const char* pMimeType, const char* pData, size_t nSize) ++ { ++ return mpDoc->pClass->paste(mpDoc, pMimeType, pData, nSize); ++ } ++ ++ /** + * Adjusts the graphic selection. + * + * @param nType @see LibreOfficeKitSetGraphicSelectionType +-- +2.12.0 + diff --git a/SOURCES/0226-gtktiledviewer-initial-paste-support.patch b/SOURCES/0226-gtktiledviewer-initial-paste-support.patch new file mode 100644 index 0000000..268b157 --- /dev/null +++ b/SOURCES/0226-gtktiledviewer-initial-paste-support.patch @@ -0,0 +1,57 @@ +From 0fdc6de8c969eb185d1057fdb64a3be88b3dd770 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 22 Oct 2015 13:32:31 +0200 +Subject: [PATCH 226/398] gtktiledviewer: initial paste support + +Change-Id: I50b4dfa456d3518f5ef7faf5f634642973441a3e +(cherry picked from commit 173fc95b3551c1e69c49626211be8422cb29fb3e) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index e7e276dfce17..b0ea03ee6796 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -279,6 +280,17 @@ static void doCopy(GtkWidget* pButton, gpointer /*pItem*/) + free(pSelection); + } + ++static void doPaste(GtkWidget* pButton, gpointer /*pItem*/) ++{ ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); ++ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); ++ ++ GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(rWindow.m_pDocView), GDK_SELECTION_CLIPBOARD); ++ gchar* pText = gtk_clipboard_wait_for_text(pClipboard); ++ if (pText) ++ pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", pText, strlen(pText)); ++} + + /// Searches for the next or previous text of TiledWindow::m_pFindbarEntry. + static void doSearch(GtkWidget* pButton, bool bBackwards) +@@ -661,6 +673,12 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_tool_item_set_tooltip_text(pCopyButton, "Copy"); + gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pCopyButton, -1); + g_signal_connect(G_OBJECT(pCopyButton), "clicked", G_CALLBACK(doCopy), NULL); ++ ++ GtkToolItem* pPasteButton = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pPasteButton), "edit-paste-symbolic"); ++ gtk_tool_item_set_tooltip_text(pPasteButton, "Paste"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pPasteButton, -1); ++ g_signal_connect(G_OBJECT(pPasteButton), "clicked", G_CALLBACK(doPaste), NULL); + gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); + + GtkToolItem* pEnableEditing = gtk_toggle_tool_button_new(); +-- +2.12.0 + diff --git a/SOURCES/0227-desktop-add-lok-Document-paste-testcase.patch b/SOURCES/0227-desktop-add-lok-Document-paste-testcase.patch new file mode 100644 index 0000000..30d144f --- /dev/null +++ b/SOURCES/0227-desktop-add-lok-Document-paste-testcase.patch @@ -0,0 +1,121 @@ +From fcf74dd4cd42152234f405f645eecf58c74120e5 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 22 Oct 2015 15:51:41 +0200 +Subject: [PATCH 227/398] desktop: add lok::Document::paste() testcase + +Also, closeDoc() is called by tearDown(), so no need to call it manually +at the end of tests. + +Change-Id: Ib8f61a09fa3fc0885d7ea90ce96210bff4cc9f98 +(cherry picked from commit d491ae5692f0b1fb4653510e694bbf5227375858) +--- + desktop/CppunitTest_desktop_lib.mk | 1 + + desktop/qa/desktop_lib/test_desktop_lib.cxx | 24 +++++++++++++++++------- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/desktop/CppunitTest_desktop_lib.mk b/desktop/CppunitTest_desktop_lib.mk +index a1f712585507..ca9d8db32c9f 100644 +--- a/desktop/CppunitTest_desktop_lib.mk ++++ b/desktop/CppunitTest_desktop_lib.mk +@@ -45,6 +45,7 @@ $(eval $(call gb_CppunitTest_use_vcl,desktop_lib)) + $(eval $(call gb_CppunitTest_use_components,desktop_lib,\ + comphelper/util/comphelp \ + configmgr/source/configmgr \ ++ dtrans/util/mcnttype \ + filter/source/config/cache/filterconfig1 \ + filter/source/storagefilterdetect/storagefd \ + framework/util/fwk \ +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 3730fd106362..9f0124993ee3 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -65,6 +65,7 @@ public: + void testPaintTile(); + void testSaveAs(); + void testSaveAsCalc(); ++ void testPasteWriter(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -76,6 +77,7 @@ public: + CPPUNIT_TEST(testPaintTile); + CPPUNIT_TEST(testSaveAs); + CPPUNIT_TEST(testSaveAsCalc); ++ CPPUNIT_TEST(testPasteWriter); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -174,7 +176,6 @@ void DesktopLOKTest::testGetStyles() + CPPUNIT_FAIL("Unknown style family: " + rPair.first); + } + } +- closeDoc(); + } + + void DesktopLOKTest::testGetFonts() +@@ -194,7 +195,6 @@ void DesktopLOKTest::testGetFonts() + // check that we have font sizes available for each font + CPPUNIT_ASSERT( rPair.second.size() > 0); + } +- closeDoc(); + } + + void DesktopLOKTest::testCreateView() +@@ -213,7 +213,6 @@ void DesktopLOKTest::testCreateView() + + pDocument->m_pDocumentClass->destroyView(pDocument, nId); + CPPUNIT_ASSERT_EQUAL(1, pDocument->m_pDocumentClass->getViews(pDocument)); +- closeDoc(); + } + + void DesktopLOKTest::testGetPartPageRectangles() +@@ -236,7 +235,6 @@ void DesktopLOKTest::testGetPartPageRectangles() + CPPUNIT_ASSERT_EQUAL(static_cast(1), aRectangles.size()); + + free(pRectangles); +- closeDoc(); + } + + void DesktopLOKTest::testGetFilterTypes() +@@ -283,7 +281,6 @@ void DesktopLOKTest::testSearchCalc() + // Result is on the first sheet. + CPPUNIT_ASSERT_EQUAL(0, m_aSearchResultPart[0]); + +- closeDoc(); + comphelper::LibreOfficeKit::setActive(false); + } + +@@ -310,8 +307,6 @@ void DesktopLOKTest::testPaintTile() + nTileHeight = 4000; + aBuffer.resize(nCanvasWidth * nCanvasHeight * 4); + pDocument->pClass->paintTile(pDocument, aBuffer.data(), nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight); +- +- closeDoc(); + } + + void DesktopLOKTest::testSaveAs() +@@ -330,6 +325,21 @@ void DesktopLOKTest::testSaveAsCalc() + CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "png", 0)); + } + ++void DesktopLOKTest::testPasteWriter() ++{ ++ comphelper::LibreOfficeKit::setActive(true); ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ OString aText("hello"); ++ ++ pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength()); ++ ++ pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", 0); ++ char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", 0); ++ CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText)); ++ free(pText); ++ comphelper::LibreOfficeKit::setActive(false); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +-- +2.12.0 + diff --git a/SOURCES/0228-loplugin-defaultparams.patch b/SOURCES/0228-loplugin-defaultparams.patch new file mode 100644 index 0000000..f547dc2 --- /dev/null +++ b/SOURCES/0228-loplugin-defaultparams.patch @@ -0,0 +1,27 @@ +From e46f191d3091b1fda977fb723aeec4b54f832412 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Thu, 22 Oct 2015 21:41:02 +0200 +Subject: [PATCH 228/398] loplugin:defaultparams + +Change-Id: I12e314ef09ac4b3517135933169de50e8a525dfc +(cherry picked from commit ee5d1b07af43de4778a6289307a6364a1693f25a) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 9f0124993ee3..5816c032a7a5 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -327,7 +327,7 @@ void DesktopLOKTest::testSaveAsCalc() + + void DesktopLOKTest::testPasteWriter() + { +- comphelper::LibreOfficeKit::setActive(true); ++ comphelper::LibreOfficeKit::setActive(); + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); + OString aText("hello"); + +-- +2.12.0 + diff --git a/SOURCES/0229-vcl-ITiledRenderable-getWindow-can-be-pure-virtual-n.patch b/SOURCES/0229-vcl-ITiledRenderable-getWindow-can-be-pure-virtual-n.patch new file mode 100644 index 0000000..39094b8 --- /dev/null +++ b/SOURCES/0229-vcl-ITiledRenderable-getWindow-can-be-pure-virtual-n.patch @@ -0,0 +1,31 @@ +From bfba36e614c7df26b2c8047b18332181387d69c8 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 26 Oct 2015 10:26:37 +0100 +Subject: [PATCH 229/398] vcl: ITiledRenderable::getWindow() can be + pure-virtual now + +Change-Id: I393ec4427674cd5d77d0e9a069ffe159d14e38b1 +(cherry picked from commit e531f846d798e1b9097fcb2a5f4e58d5e3d423de) +--- + include/vcl/ITiledRenderable.hxx | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index bb891ab97f7b..5b3d4681088a 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -149,10 +149,7 @@ public: + } + + /// Returns the current vcl::Window of the component. +- virtual vcl::Window* getWindow() +- { +- return 0; +- } ++ virtual vcl::Window* getWindow() = 0; + }; + + } // namespace vcl +-- +2.12.0 + diff --git a/SOURCES/0230-lok-Document-paste-check-if-the-given-mime-type-is-s.patch b/SOURCES/0230-lok-Document-paste-check-if-the-given-mime-type-is-s.patch new file mode 100644 index 0000000..d40529f --- /dev/null +++ b/SOURCES/0230-lok-Document-paste-check-if-the-given-mime-type-is-s.patch @@ -0,0 +1,108 @@ +From 18c49bbbce655d805447b95fc92733551eb6af51 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 26 Oct 2015 11:28:55 +0100 +Subject: [PATCH 230/398] lok::Document::paste: check if the given mime type is + supported + +Change-Id: Ib59ea43700815c53cdd4be819e2e9cf35c6f89e9 +(cherry picked from commit 7efbbe98d7fe951909234dcacd37f67975f00da2) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 5 ++++- + desktop/source/lib/init.cxx | 7 +++++++ + include/vcl/ITiledRenderable.hxx | 5 +++++ + sw/inc/unotxdoc.hxx | 2 ++ + sw/source/uibase/uno/unotxdoc.cxx | 10 ++++++++++ + 5 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 5816c032a7a5..12831318dde3 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -331,12 +331,15 @@ void DesktopLOKTest::testPasteWriter() + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); + OString aText("hello"); + +- pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength()); ++ CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength())); + + pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", 0); + char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", 0); + CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText)); + free(pText); ++ ++ CPPUNIT_ASSERT(!pDocument->pClass->paste(pDocument, "textt/plain;charset=utf-8", aText.getStr(), aText.getLength())); ++ + comphelper::LibreOfficeKit::setActive(false); + } + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 0459176c24a0..75df1528fd51 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1016,6 +1016,13 @@ static bool doc_paste(LibreOfficeKitDocument* pThis, const char* pMimeType, cons + } + + pWindow->SetClipboard(xClipboard); ++ if (!pDoc->isMimeTypeSupported()) ++ { ++ if (gImpl) ++ gImpl->maLastExceptionMsg = "Document doesn't support this mime type"; ++ return false; ++ } ++ + OUString aCommand(".uno:Paste"); + uno::Sequence aPropertyValues; + if (!comphelper::dispatchCommand(aCommand, aPropertyValues)) +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 5b3d4681088a..3301b7754f15 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -150,6 +150,11 @@ public: + + /// Returns the current vcl::Window of the component. + virtual vcl::Window* getWindow() = 0; ++ ++ virtual bool isMimeTypeSupported() ++ { ++ return false; ++ } + }; + + } // namespace vcl +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index d0eada25b6ef..180ceb891b89 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -436,6 +436,8 @@ public: + virtual OUString getPartPageRectangles() override; + /// @see vcl::ITiledRenderable::getWindow(). + virtual vcl::Window* getWindow() override; ++ /// @see vcl::ITiledRenderable::isMimeTypeSupported(). ++ virtual bool isMimeTypeSupported() override; + + // ::com::sun::star::tiledrendering::XTiledRenderable + virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) SAL_OVERRIDE; +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 658057d7a977..618e6b373162 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3195,6 +3195,16 @@ vcl::Window* SwXTextDocument::getWindow() + return &pDocShell->GetView()->GetEditWin(); + } + ++bool SwXTextDocument::isMimeTypeSupported() ++{ ++ SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); ++ if (!pWrtShell) ++ return false; ++ ++ TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&pWrtShell->GetView().GetEditWin())); ++ return aDataHelper.GetXTransferable().is() && SwTransferable::IsPaste(*pWrtShell, aDataHelper); ++} ++ + int SwXTextDocument::getPart() + { + SolarMutexGuard aGuard; +-- +2.12.0 + diff --git a/SOURCES/0231-sc-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch b/SOURCES/0231-sc-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch new file mode 100644 index 0000000..1fe5a79 --- /dev/null +++ b/SOURCES/0231-sc-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch @@ -0,0 +1,103 @@ +From ce5f6c1ac1880ff18eb3b663a2862f742a6ddad4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 26 Oct 2015 13:42:02 +0100 +Subject: [PATCH 231/398] sc: implement + vcl::ITiledRenderable::isMimeTypeSupported() + +(cherry picked from commit 5b4c29b1b15dcebfe4e76aaa8bdb2dd45e2b67f3) + +Change-Id: I0b9de068ddf0f4ff92d8fbf003b7529516f1f80a +--- + include/vcl/ITiledRenderable.hxx | 6 ++---- + sc/inc/docuno.hxx | 8 +++++++- + sc/source/ui/unoobj/docuno.cxx | 24 ++++++++++++++++++++++++ + sw/source/uibase/uno/unotxdoc.cxx | 2 ++ + 4 files changed, 35 insertions(+), 5 deletions(-) + +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 3301b7754f15..4fa23386bfbc 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -151,10 +151,8 @@ public: + /// Returns the current vcl::Window of the component. + virtual vcl::Window* getWindow() = 0; + +- virtual bool isMimeTypeSupported() +- { +- return false; +- } ++ /// If the current contents of the clipboard is something we can paste. ++ virtual bool isMimeTypeSupported() = 0; + }; + + } // namespace vcl +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index cc132278bdf8..1e3aae1d302b 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -414,7 +414,13 @@ public: + virtual void setGraphicSelection(int nType, int nX, int nY) SAL_OVERRIDE; + + /// @see lok::Document::resetSelection(). +- virtual void resetSelection() SAL_OVERRIDE; ++ virtual void resetSelection() override; ++ ++ /// @see vcl::ITiledRenderable::getWindow(). ++ virtual vcl::Window* getWindow() override; ++ ++ /// @see vcl::ITiledRenderable::isMimeTypeSupported(). ++ virtual bool isMimeTypeSupported() override; + }; + + class ScDrawPagesObj : public cppu::WeakImplHelper2< +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index 958495f7ea7b..af6bd11ba742 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -846,6 +846,30 @@ void ScModelObj::resetSelection() + pDocShell->GetDocument().GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, ""); + } + ++vcl::Window* ScModelObj::getWindow() ++{ ++ SolarMutexGuard aGuard; ++ ++ ScViewData* pViewData = ScDocShell::GetViewData(); ++ if (!pViewData) ++ return 0; ++ ++ return pViewData->GetActiveWin(); ++} ++ ++bool ScModelObj::isMimeTypeSupported() ++{ ++ SolarMutexGuard aGuard; ++ ++ ScViewData* pViewData = ScDocShell::GetViewData(); ++ if (!pViewData) ++ return 0; ++ ++ ++ TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewData->GetActiveWin())); ++ return EditEngine::HasValidData(aDataHelper.GetTransferable()); ++} ++ + void ScModelObj::initializeForTiledRendering() + { + SolarMutexGuard aGuard; +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 618e6b373162..68ec3df2a9c0 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3197,6 +3197,8 @@ vcl::Window* SwXTextDocument::getWindow() + + bool SwXTextDocument::isMimeTypeSupported() + { ++ SolarMutexGuard aGuard; ++ + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + if (!pWrtShell) + return false; +-- +2.12.0 + diff --git a/SOURCES/0232-vcl-add-Window-SetClipboard.patch b/SOURCES/0232-vcl-add-Window-SetClipboard.patch new file mode 100644 index 0000000..db1e6f6 --- /dev/null +++ b/SOURCES/0232-vcl-add-Window-SetClipboard.patch @@ -0,0 +1,45 @@ +From 2ff05dd30cb865b4a44d988370eb554acdca522a Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 22 Oct 2015 09:41:29 +0200 +Subject: [PATCH 232/398] vcl: add Window::SetClipboard() + +Change-Id: I385f64b7d5015c9a34f34a436b0ee2ce6b3a83d3 +(cherry picked from commit 98cdb563c1c63e93b4722721354d86848d2cd2c2) +--- + include/vcl/window.hxx | 2 ++ + vcl/source/window/window.cxx | 6 ++++++ + 2 files changed, 8 insertions(+) + +diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx +index ae2894001974..eb8cf4bc1df1 100644 +--- a/include/vcl/window.hxx ++++ b/include/vcl/window.hxx +@@ -1298,6 +1298,8 @@ public: + + // Clipboard/Selection interfaces + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard > GetClipboard(); ++ /// Sets a custom clipboard for the window's frame, instead of creating it on-demand using css::datatransfer::clipboard::SystemClipboard. ++ void SetClipboard(css::uno::Reference xClipboard); + ::com::sun::star::uno::Reference< ::com::sun::star::datatransfer::clipboard::XClipboard > GetPrimarySelection(); + + /* +diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx +index e8d2b9615d92..0a01a14f4530 100644 +--- a/vcl/source/window/window.cxx ++++ b/vcl/source/window/window.cxx +@@ -3355,6 +3355,12 @@ void Window::ImplCallActivateListeners( vcl::Window *pOld ) + } + } + ++void Window::SetClipboard(Reference xClipboard) ++{ ++ if (mpWindowImpl->mpFrameData) ++ mpWindowImpl->mpFrameData->mxClipboard = xClipboard; ++} ++ + Reference< XClipboard > Window::GetClipboard() + { + +-- +2.12.0 + diff --git a/SOURCES/0233-lok-clipboard-support-rich-text-paste.patch b/SOURCES/0233-lok-clipboard-support-rich-text-paste.patch new file mode 100644 index 0000000..d8d53b0 --- /dev/null +++ b/SOURCES/0233-lok-clipboard-support-rich-text-paste.patch @@ -0,0 +1,73 @@ +From cb62457c638e4bd4d951bcf664040326c840824c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 26 Oct 2015 14:20:26 +0100 +Subject: [PATCH 233/398] lok clipboard: support rich text paste + +Change-Id: Ida5028969782be792b32b952d3adba0c30dd8bae +(cherry picked from commit faa316e670414363dcfb6db6001fdb209f4a48c1) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 3 +++ + desktop/source/lib/lokclipboard.cxx | 11 ++++++++--- + desktop/source/lib/lokclipboard.hxx | 2 +- + 3 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 12831318dde3..d4135b66d1d8 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -338,7 +338,10 @@ void DesktopLOKTest::testPasteWriter() + CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText)); + free(pText); + ++ // textt/plain should be rejected. + CPPUNIT_ASSERT(!pDocument->pClass->paste(pDocument, "textt/plain;charset=utf-8", aText.getStr(), aText.getLength())); ++ // Writer is expected to support text/html. ++ CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/html", aText.getStr(), aText.getLength())); + + comphelper::LibreOfficeKit::setActive(false); + } +diff --git a/desktop/source/lib/lokclipboard.cxx b/desktop/source/lib/lokclipboard.cxx +index a81902b15b6b..50d570577e27 100644 +--- a/desktop/source/lib/lokclipboard.cxx ++++ b/desktop/source/lib/lokclipboard.cxx +@@ -32,7 +32,7 @@ OUString SAL_CALL LOKClipboard::getName() throw (uno::RuntimeException, std::exc + + LOKTransferable::LOKTransferable(const char* pMimeType, const char* pData, size_t nSize) + : m_aMimeType(pMimeType), +- m_aText(pData, nSize) ++ m_aSequence(reinterpret_cast(pData), nSize) + { + } + +@@ -40,8 +40,13 @@ uno::Any SAL_CALL LOKTransferable::getTransferData(const datatransfer::DataFlavo + throw(datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeException, std::exception) + { + uno::Any aRet; +- if (m_aMimeType == "text/plain;charset=utf-8" && rFlavor.MimeType == "text/plain;charset=utf-16") +- aRet <<= OStringToOUString(m_aText, RTL_TEXTENCODING_UTF8); ++ if (rFlavor.DataType == cppu::UnoType::get()) ++ { ++ sal_Char* pText = reinterpret_cast(m_aSequence.getArray()); ++ aRet <<= OUString(pText, rtl_str_getLength(pText), RTL_TEXTENCODING_UTF8); ++ } ++ else ++ aRet <<= m_aSequence; + return aRet; + } + +diff --git a/desktop/source/lib/lokclipboard.hxx b/desktop/source/lib/lokclipboard.hxx +index b982e1c734ee..a0ab6451e0c0 100644 +--- a/desktop/source/lib/lokclipboard.hxx ++++ b/desktop/source/lib/lokclipboard.hxx +@@ -35,7 +35,7 @@ public: + class LOKTransferable : public cppu::WeakImplHelper + { + OString m_aMimeType; +- OString m_aText; ++ css::uno::Sequence m_aSequence; + + /// Provides a list of flavors, used by getTransferDataFlavors() and isDataFlavorSupported(). + std::vector getTransferDataFlavorsAsVector(); +-- +2.12.0 + diff --git a/SOURCES/0234-gtktiledviwer-try-to-paste-as-html-then-as-plain-tex.patch b/SOURCES/0234-gtktiledviwer-try-to-paste-as-html-then-as-plain-tex.patch new file mode 100644 index 0000000..6585d65 --- /dev/null +++ b/SOURCES/0234-gtktiledviwer-try-to-paste-as-html-then-as-plain-tex.patch @@ -0,0 +1,75 @@ +From cd8468af6c005d3ba1f11eff0fdc04344a282c31 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 26 Oct 2015 14:25:26 +0100 +Subject: [PATCH 234/398] gtktiledviwer: try to paste as html, then as plain + text + +Change-Id: I8e1c93fd36fb903c0625b29f9f73825438c9e113 +(cherry picked from commit 080bd44f0b0300075ff18d377f31deebbc4009ed) +--- + desktop/source/lib/lokclipboard.cxx | 2 +- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 28 ++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/lokclipboard.cxx b/desktop/source/lib/lokclipboard.cxx +index 50d570577e27..376bcd72d238 100644 +--- a/desktop/source/lib/lokclipboard.cxx ++++ b/desktop/source/lib/lokclipboard.cxx +@@ -43,7 +43,7 @@ throw(datatransfer::UnsupportedFlavorException, io::IOException, uno::RuntimeExc + if (rFlavor.DataType == cppu::UnoType::get()) + { + sal_Char* pText = reinterpret_cast(m_aSequence.getArray()); +- aRet <<= OUString(pText, rtl_str_getLength(pText), RTL_TEXTENCODING_UTF8); ++ aRet <<= OUString(pText, m_aSequence.getLength(), RTL_TEXTENCODING_UTF8); + } + else + aRet <<= m_aSequence; +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index b0ea03ee6796..72afd52131ad 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -15,6 +15,7 @@ + #include + + #include ++#include + #include + + #define LOK_USE_UNSTABLE_API +@@ -287,6 +288,33 @@ static void doPaste(GtkWidget* pButton, gpointer /*pItem*/) + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(rWindow.m_pDocView), GDK_SELECTION_CLIPBOARD); ++ ++ GdkAtom* pTargets; ++ gint nTargets; ++ boost::optional oTarget; ++ if (gtk_clipboard_wait_for_targets(pClipboard, &pTargets, &nTargets)) ++ { ++ for (gint i = 0; i < nTargets; ++i) ++ { ++ gchar* pName = gdk_atom_name(pTargets[i]); ++ if (std::string(pName) == "text/html") ++ oTarget = pTargets[i]; ++ g_free(pName); ++ } ++ g_free(pTargets); ++ } ++ ++ if (oTarget) ++ { ++ GtkSelectionData* pSelectionData = gtk_clipboard_wait_for_contents(pClipboard, *oTarget); ++ gint nLength; ++ const guchar* pData = gtk_selection_data_get_data_with_length(pSelectionData, &nLength); ++ bool bSuccess = pDocument->pClass->paste(pDocument, "text/html", reinterpret_cast(pData), nLength); ++ gtk_selection_data_free(pSelectionData); ++ if (bSuccess) ++ return; ++ } ++ + gchar* pText = gtk_clipboard_wait_for_text(pClipboard); + if (pText) + pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", pText, strlen(pText)); +-- +2.12.0 + diff --git a/SOURCES/0235-sw-tiled-rendering-don-t-offer-HTML-paste-for-shape-.patch b/SOURCES/0235-sw-tiled-rendering-don-t-offer-HTML-paste-for-shape-.patch new file mode 100644 index 0000000..52d75c3 --- /dev/null +++ b/SOURCES/0235-sw-tiled-rendering-don-t-offer-HTML-paste-for-shape-.patch @@ -0,0 +1,33 @@ +From a4c1fef85d4d97c934eb3927b3aef56a397bb80c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 26 Oct 2015 15:39:28 +0100 +Subject: [PATCH 235/398] sw tiled rendering: don't offer HTML paste for shape + text + +Change-Id: Icd6df15347c48a5e42860092f4ee664e3a3d5699 +(cherry picked from commit c791bef561dcf38a4b47dd06534914f7c28ae67e) +--- + sw/source/uibase/uno/unotxdoc.cxx | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 68ec3df2a9c0..b50096bbbaa8 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3204,6 +3204,13 @@ bool SwXTextDocument::isMimeTypeSupported() + return false; + + TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(&pWrtShell->GetView().GetEditWin())); ++ if (SdrView* pSdrView = pWrtShell->GetDrawView()) ++ { ++ if (pSdrView->GetTextEditObject()) ++ // Editing shape text ++ return EditEngine::HasValidData(aDataHelper.GetTransferable()); ++ } ++ + return aDataHelper.GetXTransferable().is() && SwTransferable::IsPaste(*pWrtShell, aDataHelper); + } + +-- +2.12.0 + diff --git a/SOURCES/0236-fix-includes-that-are-not-stand-alone.patch b/SOURCES/0236-fix-includes-that-are-not-stand-alone.patch new file mode 100644 index 0000000..5a24faa --- /dev/null +++ b/SOURCES/0236-fix-includes-that-are-not-stand-alone.patch @@ -0,0 +1,478 @@ +From d3d251ac5a08c88a9de24dbf198f921037057e38 Mon Sep 17 00:00:00 2001 +From: Norbert Thiebaud +Date: Fri, 16 Oct 2015 17:15:50 -0500 +Subject: [PATCH 236/398] fix includes that are not stand-alone + +includes should be able to be included on their own +fix some of the ones that do not respect +that rule. + +Change-Id: Id161224a1978461d3cea43252f232f18888a4f61 +Reviewed-on: https://gerrit.libreoffice.org/19612 +Tested-by: Jenkins +Reviewed-by: Norbert Thiebaud +(cherry picked from commit fd9d9976bf346929d872db0e5d8abc4180c9996c) +--- + include/LibreOfficeKit/LibreOfficeKit.hxx | 1 + + include/basebmp/basebmpdllapi.h | 2 ++ + include/basegfx/raster/bzpixelraster.hxx | 1 + + include/basic/sbxcore.hxx | 8 ++++---- + include/canvas/base/canvascustomspritehelper.hxx | 9 +++++---- + include/canvas/base/disambiguationhelper.hxx | 1 + + include/canvas/rendering/icachedprimitive.hxx | 1 + + include/connectivity/SQLStatementHelper.hxx | 1 + + include/connectivity/StdTypeDefs.hxx | 9 ++++----- + include/drawinglayer/processor2d/canvasprocessor.hxx | 14 +++++++------- + include/editeng/eedata.hxx | 2 ++ + include/filter/msfilter/msocximex.hxx | 1 + + include/filter/msfilter/svdfppt.hxx | 1 + + include/filter/msfilter/svxmsbas.hxx | 10 ++++++---- + include/formula/IControlReferenceHandler.hxx | 1 + + include/jvmaccess/unovirtualmachine.hxx | 3 +-- + include/oox/export/utils.hxx | 2 ++ + include/svx/globl3d.hxx | 2 ++ + include/tools/appendunixshellword.hxx | 2 +- + include/tools/getprocessworkingdir.hxx | 2 +- + include/tools/mapunit.hxx | 2 ++ + include/unotest/gettestargument.hxx | 3 +-- + include/unotest/toabsolutefileurl.hxx | 2 +- + include/vcl/fontcapabilities.hxx | 2 ++ + include/vcl/salgtype.hxx | 2 ++ + include/xmloff/DashStyle.hxx | 3 +-- + include/xmloff/styleexp.hxx | 1 + + include/xmloff/xmlcnimp.hxx | 5 +++-- + 28 files changed, 58 insertions(+), 35 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index db7807d999ea..0e83a63c3fe5 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -11,6 +11,7 @@ + #define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX + + #include "LibreOfficeKit.h" ++#include "LibreOfficeKitInit.h" + + /* + * The reasons this C++ code is not as pretty as it could be are: +diff --git a/include/basebmp/basebmpdllapi.h b/include/basebmp/basebmpdllapi.h +index c44eee01ce7b..88241af7a812 100644 +--- a/include/basebmp/basebmpdllapi.h ++++ b/include/basebmp/basebmpdllapi.h +@@ -20,6 +20,8 @@ + #ifndef INCLUDED_BASEBMP_BASEBMPDLLAPI_H + #define INCLUDED_BASEBMP_BASEBMPDLLAPI_H + ++#include ++ + #if defined BASEBMP_DLLIMPLEMENTATION + #define BASEBMP_DLLPUBLIC SAL_DLLPUBLIC_EXPORT + #else +diff --git a/include/basegfx/raster/bzpixelraster.hxx b/include/basegfx/raster/bzpixelraster.hxx +index cddca2186578..f11dcf26a9f9 100644 +--- a/include/basegfx/raster/bzpixelraster.hxx ++++ b/include/basegfx/raster/bzpixelraster.hxx +@@ -22,6 +22,7 @@ + + #include + #include ++#include + + namespace basegfx + { +diff --git a/include/basic/sbxcore.hxx b/include/basic/sbxcore.hxx +index 98f984196dd6..38bb80aeb817 100644 +--- a/include/basic/sbxcore.hxx ++++ b/include/basic/sbxcore.hxx +@@ -20,11 +20,11 @@ + #ifndef INCLUDED_BASIC_SBXCORE_HXX + #define INCLUDED_BASIC_SBXCORE_HXX + +-#include +-#include +- +-#include + #include ++#include ++#include ++#include ++#include + + class SvStream; + +diff --git a/include/canvas/base/canvascustomspritehelper.hxx b/include/canvas/base/canvascustomspritehelper.hxx +index b77144d8a50c..e90aca153f9d 100644 +--- a/include/canvas/base/canvascustomspritehelper.hxx ++++ b/include/canvas/base/canvascustomspritehelper.hxx +@@ -20,14 +20,15 @@ + #ifndef INCLUDED_CANVAS_BASE_CANVASCUSTOMSPRITEHELPER_HXX + #define INCLUDED_CANVAS_BASE_CANVASCUSTOMSPRITEHELPER_HXX + +-#include +-#include ++#include + #include +-#include ++#include + #include +-#include ++#include + #include + #include ++#include ++#include + + namespace canvas + { +diff --git a/include/canvas/base/disambiguationhelper.hxx b/include/canvas/base/disambiguationhelper.hxx +index 9b07498cb754..358e82b7a7d2 100644 +--- a/include/canvas/base/disambiguationhelper.hxx ++++ b/include/canvas/base/disambiguationhelper.hxx +@@ -20,6 +20,7 @@ + #ifndef INCLUDED_CANVAS_BASE_DISAMBIGUATIONHELPER_HXX + #define INCLUDED_CANVAS_BASE_DISAMBIGUATIONHELPER_HXX + ++#include + #include + + +diff --git a/include/canvas/rendering/icachedprimitive.hxx b/include/canvas/rendering/icachedprimitive.hxx +index 8df4cc94a136..969e8c088138 100644 +--- a/include/canvas/rendering/icachedprimitive.hxx ++++ b/include/canvas/rendering/icachedprimitive.hxx +@@ -20,6 +20,7 @@ + #ifndef INCLUDED_CANVAS_RENDERING_ICACHEDPRIMITIVE_HXX + #define INCLUDED_CANVAS_RENDERING_ICACHEDPRIMITIVE_HXX + ++#include + #include + + #include +diff --git a/include/connectivity/SQLStatementHelper.hxx b/include/connectivity/SQLStatementHelper.hxx +index 7472719328b1..36f6befac73a 100644 +--- a/include/connectivity/SQLStatementHelper.hxx ++++ b/include/connectivity/SQLStatementHelper.hxx +@@ -22,6 +22,7 @@ + + #include + #include ++#include + + namespace dbtools + { +diff --git a/include/connectivity/StdTypeDefs.hxx b/include/connectivity/StdTypeDefs.hxx +index 9c68fc34c834..78720651e723 100644 +--- a/include/connectivity/StdTypeDefs.hxx ++++ b/include/connectivity/StdTypeDefs.hxx +@@ -19,18 +19,17 @@ + #ifndef INCLUDED_CONNECTIVITY_STDTYPEDEFS_HXX + #define INCLUDED_CONNECTIVITY_STDTYPEDEFS_HXX + +-#include +- + #include + #include +-#include ++ ++#include + + + namespace connectivity + { + typedef ::std::vector< OUString> TStringVector; +- typedef ::std::vector< sal_Int32> TIntVector; +- typedef ::std::map TInt2IntMap; ++ typedef ::std::vector< sal_Int32> TIntVector; ++ typedef ::std::map TInt2IntMap; + typedef ::std::map< OUString,sal_Int32> TString2IntMap; + typedef ::std::map< sal_Int32,OUString> TInt2StringMap; + } +diff --git a/include/drawinglayer/processor2d/canvasprocessor.hxx b/include/drawinglayer/processor2d/canvasprocessor.hxx +index 5385582330f5..9ed260033e5d 100644 +--- a/include/drawinglayer/processor2d/canvasprocessor.hxx ++++ b/include/drawinglayer/processor2d/canvasprocessor.hxx +@@ -20,17 +20,17 @@ + #ifndef INCLUDED_DRAWINGLAYER_PROCESSOR2D_CANVASPROCESSOR_HXX + #define INCLUDED_DRAWINGLAYER_PROCESSOR2D_CANVASPROCESSOR_HXX + +-#include +- +-#include +-#include + #include +-#include +-#include ++#include ++#include + #include ++#include ++#include ++#include + #include +-#include ++#include + #include ++#include + + namespace basegfx { + class BColor; +diff --git a/include/editeng/eedata.hxx b/include/editeng/eedata.hxx +index cd1db6e0775c..321cf04e43e7 100644 +--- a/include/editeng/eedata.hxx ++++ b/include/editeng/eedata.hxx +@@ -25,6 +25,8 @@ + // later. + #include + ++#include ++ + namespace EEngineData + { + // spell checking wrong vector containing the redlining data +diff --git a/include/filter/msfilter/msocximex.hxx b/include/filter/msfilter/msocximex.hxx +index f0dd8510ae1d..5b53bb5d7d56 100644 +--- a/include/filter/msfilter/msocximex.hxx ++++ b/include/filter/msfilter/msocximex.hxx +@@ -19,6 +19,7 @@ + #ifndef INCLUDED_FILTER_MSFILTER_MSOCXIMEX_HXX + #define INCLUDED_FILTER_MSFILTER_MSOCXIMEX_HXX + ++#include + #include + + namespace com{namespace sun{namespace star{ +diff --git a/include/filter/msfilter/svdfppt.hxx b/include/filter/msfilter/svdfppt.hxx +index 2292064c756c..f6db48abc3fe 100644 +--- a/include/filter/msfilter/svdfppt.hxx ++++ b/include/filter/msfilter/svdfppt.hxx +@@ -20,6 +20,7 @@ + #ifndef INCLUDED_FILTER_MSFILTER_SVDFPPT_HXX + #define INCLUDED_FILTER_MSFILTER_SVDFPPT_HXX + ++#include + #include + #include + #include +diff --git a/include/filter/msfilter/svxmsbas.hxx b/include/filter/msfilter/svxmsbas.hxx +index 312e18c87b11..5b549d29ac20 100644 +--- a/include/filter/msfilter/svxmsbas.hxx ++++ b/include/filter/msfilter/svxmsbas.hxx +@@ -20,14 +20,16 @@ + #ifndef INCLUDED_FILTER_MSFILTER_SVXMSBAS_HXX + #define INCLUDED_FILTER_MSFILTER_SVXMSBAS_HXX + +-#include +-#include +- + #include + #include + ++#include ++#include ++#include ++#include ++#include ++ + class SfxObjectShell; +-class SotStorage; + + /* Construct with the root storage of the MS document, with bImportCode + * set the visual basic code will be imported into the stardocument when Import +diff --git a/include/formula/IControlReferenceHandler.hxx b/include/formula/IControlReferenceHandler.hxx +index 11cf043255eb..5d74fb1d6845 100644 +--- a/include/formula/IControlReferenceHandler.hxx ++++ b/include/formula/IControlReferenceHandler.hxx +@@ -20,6 +20,7 @@ + #define INCLUDED_FORMULA_ICONTROLREFERENCEHANDLER_HXX + + #include ++#include + + namespace formula + { +diff --git a/include/jvmaccess/unovirtualmachine.hxx b/include/jvmaccess/unovirtualmachine.hxx +index 5b0e785dec23..6d021257fd5c 100644 +--- a/include/jvmaccess/unovirtualmachine.hxx ++++ b/include/jvmaccess/unovirtualmachine.hxx +@@ -21,14 +21,13 @@ + #define INCLUDED_JVMACCESS_UNOVIRTUALMACHINE_HXX + + #include ++#include + #include + #include + #include + + namespace jvmaccess { + +-class VirtualMachine; +- + /** An encapsulating wrapper around a Java virtual machine and an appropriate + UNO class loader. + */ +diff --git a/include/oox/export/utils.hxx b/include/oox/export/utils.hxx +index 417e552fff30..66854f61998f 100644 +--- a/include/oox/export/utils.hxx ++++ b/include/oox/export/utils.hxx +@@ -20,6 +20,8 @@ + #ifndef INCLUDED_OOX_EXPORT_UTILS_HXX + #define INCLUDED_OOX_EXPORT_UTILS_HXX + ++#include ++ + #define I32S(x) OString::number( (sal_Int32) x ).getStr() + #define I64S(x) OString::number( (sal_Int64) x ).getStr() + #define IS(x) OString::number( x ).getStr() +diff --git a/include/svx/globl3d.hxx b/include/svx/globl3d.hxx +index 233a64196742..88fec321b895 100644 +--- a/include/svx/globl3d.hxx ++++ b/include/svx/globl3d.hxx +@@ -20,6 +20,8 @@ + #ifndef INCLUDED_SVX_GLOBL3D_HXX + #define INCLUDED_SVX_GLOBL3D_HXX + ++#include ++ + const sal_uInt32 E3dInventor = sal_uInt32('E')*0x00000001+ + sal_uInt32('3')*0x00000100+ + sal_uInt32('D')*0x00010000+ +diff --git a/include/tools/appendunixshellword.hxx b/include/tools/appendunixshellword.hxx +index 4585bf36cf8f..dbe66c628851 100644 +--- a/include/tools/appendunixshellword.hxx ++++ b/include/tools/appendunixshellword.hxx +@@ -20,7 +20,7 @@ + #ifndef INCLUDED_TOOLS_APPENDUNIXSHELLWORD_HXX + #define INCLUDED_TOOLS_APPENDUNIXSHELLWORD_HXX + +-#include ++#include + + #if defined UNX + #include +diff --git a/include/tools/getprocessworkingdir.hxx b/include/tools/getprocessworkingdir.hxx +index 985a683a872c..b0dbe709dcdb 100644 +--- a/include/tools/getprocessworkingdir.hxx ++++ b/include/tools/getprocessworkingdir.hxx +@@ -20,7 +20,7 @@ + #ifndef INCLUDED_TOOLS_GETPROCESSWORKINGDIR_HXX + #define INCLUDED_TOOLS_GETPROCESSWORKINGDIR_HXX + +-#include ++#include + #include + + +diff --git a/include/tools/mapunit.hxx b/include/tools/mapunit.hxx +index a68b6b45b251..660db9183e6f 100644 +--- a/include/tools/mapunit.hxx ++++ b/include/tools/mapunit.hxx +@@ -20,6 +20,8 @@ + #ifndef INCLUDED_TOOLS_MAPUNIT_HXX + #define INCLUDED_TOOLS_MAPUNIT_HXX + ++#include ++ + enum MapUnit { MAP_100TH_MM, MAP_10TH_MM, MAP_MM, MAP_CM, + MAP_1000TH_INCH, MAP_100TH_INCH, MAP_10TH_INCH, MAP_INCH, + MAP_POINT, MAP_TWIP, MAP_PIXEL, MAP_SYSFONT, MAP_APPFONT, +diff --git a/include/unotest/gettestargument.hxx b/include/unotest/gettestargument.hxx +index e2160ba51938..734b77e57b8a 100644 +--- a/include/unotest/gettestargument.hxx ++++ b/include/unotest/gettestargument.hxx +@@ -20,8 +20,7 @@ + #ifndef INCLUDED_UNOTEST_GETTESTARGUMENT_HXX + #define INCLUDED_UNOTEST_GETTESTARGUMENT_HXX + +-#include +- ++#include + #include + + +diff --git a/include/unotest/toabsolutefileurl.hxx b/include/unotest/toabsolutefileurl.hxx +index 975e7f411002..5bdb7b05ef04 100644 +--- a/include/unotest/toabsolutefileurl.hxx ++++ b/include/unotest/toabsolutefileurl.hxx +@@ -20,7 +20,7 @@ + #ifndef INCLUDED_UNOTEST_TOABSOLUTEFILEURL_HXX + #define INCLUDED_UNOTEST_TOABSOLUTEFILEURL_HXX + +-#include ++#include + + #include + +diff --git a/include/vcl/fontcapabilities.hxx b/include/vcl/fontcapabilities.hxx +index 069afff14113..57342603fa8e 100644 +--- a/include/vcl/fontcapabilities.hxx ++++ b/include/vcl/fontcapabilities.hxx +@@ -13,6 +13,8 @@ + #include + #include + ++#include ++ + //See OS/2 table, i.e. http://www.microsoft.com/typography/otspec/os2.htm#ur + namespace vcl + { +diff --git a/include/vcl/salgtype.hxx b/include/vcl/salgtype.hxx +index de8a5555fee4..8a340099a11d 100644 +--- a/include/vcl/salgtype.hxx ++++ b/include/vcl/salgtype.hxx +@@ -20,6 +20,8 @@ + #ifndef INCLUDED_VCL_SALGTYPE_HXX + #define INCLUDED_VCL_SALGTYPE_HXX + ++#include ++ + typedef sal_uInt32 SalColor; + #define MAKE_SALCOLOR( r, g, b ) ((SalColor)(((sal_uInt32)((sal_uInt8)(b))))|(((sal_uInt32)((sal_uInt8)(g)))<<8)|(((sal_uInt32)((sal_uInt8)(r)))<<16)) + #define SALCOLOR_RED( n ) ((sal_uInt8)((n)>>16)) +diff --git a/include/xmloff/DashStyle.hxx b/include/xmloff/DashStyle.hxx +index eafe70e16399..8f57f2e9c3ad 100644 +--- a/include/xmloff/DashStyle.hxx ++++ b/include/xmloff/DashStyle.hxx +@@ -20,9 +20,8 @@ + #ifndef INCLUDED_XMLOFF_DASHSTYLE_HXX + #define INCLUDED_XMLOFF_DASHSTYLE_HXX + +-#include ++#include + #include +-#include + + class SvXMLImport; + class SvXMLExport; +diff --git a/include/xmloff/styleexp.hxx b/include/xmloff/styleexp.hxx +index 7d9d6eedb61f..ff427342028d 100644 +--- a/include/xmloff/styleexp.hxx ++++ b/include/xmloff/styleexp.hxx +@@ -21,6 +21,7 @@ + + #include + #include ++#include + #include + #include + +diff --git a/include/xmloff/xmlcnimp.hxx b/include/xmloff/xmlcnimp.hxx +index aefee1c7ecd4..338a48f753ac 100644 +--- a/include/xmloff/xmlcnimp.hxx ++++ b/include/xmloff/xmlcnimp.hxx +@@ -20,10 +20,11 @@ + #ifndef INCLUDED_XMLOFF_XMLCNIMP_HXX + #define INCLUDED_XMLOFF_XMLCNIMP_HXX + +-#include +-#include + #include + ++#include ++#include ++ + class SvXMLAttrCollection; + + class XMLOFF_DLLPUBLIC SvXMLAttrContainerData +-- +2.12.0 + diff --git a/SOURCES/0237-sd-implement-vcl-ITiledRenderable-getWindow.patch b/SOURCES/0237-sd-implement-vcl-ITiledRenderable-getWindow.patch new file mode 100644 index 0000000..240ffdc --- /dev/null +++ b/SOURCES/0237-sd-implement-vcl-ITiledRenderable-getWindow.patch @@ -0,0 +1,53 @@ +From 675db4db926a09024df57ae8f9be457662393757 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 22 Oct 2015 14:15:14 +0200 +Subject: [PATCH 237/398] sd: implement vcl::ITiledRenderable::getWindow() + +(cherry picked from commit 8522948ba2f30fb703d4725086d30d9aa2a0cf4c) + +Change-Id: I8bc7316d9304d9e764ee846fe3af34599bf6fc35 +--- + sd/source/ui/inc/unomodel.hxx | 4 +++- + sd/source/ui/unoidl/unomodel.cxx | 11 +++++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx +index 4d7314875f0b..a24f774e2fc9 100644 +--- a/sd/source/ui/inc/unomodel.hxx ++++ b/sd/source/ui/inc/unomodel.hxx +@@ -257,7 +257,9 @@ public: + /// @see vcl::ITiledRenderable::setGraphicSelection(). + virtual void setGraphicSelection(int nType, int nX, int nY) SAL_OVERRIDE; + /// @see lok::Document::resetSelection(). +- virtual void resetSelection() SAL_OVERRIDE; ++ virtual void resetSelection() override; ++ /// @see vcl::ITiledRenderable::getWindow(). ++ virtual vcl::Window* getWindow() override; + + // XComponent + +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 6ae01a28efac..1628a18df296 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2539,6 +2539,17 @@ void SdXImpressDocument::resetSelection() + pSdrView->UnmarkAll(); + } + ++vcl::Window* SdXImpressDocument::getWindow() ++{ ++ SolarMutexGuard aGuard; ++ ++ DrawViewShell* pViewShell = GetViewShell(); ++ if (!pViewShell) ++ return 0; ++ ++ return pViewShell->GetActiveWindow(); ++} ++ + uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable() + { + uno::Reference< i18n::XForbiddenCharacters > xForb(mxForbidenCharacters); +-- +2.12.0 + diff --git a/SOURCES/0238-sd-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch b/SOURCES/0238-sd-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch new file mode 100644 index 0000000..c84b7bf --- /dev/null +++ b/SOURCES/0238-sd-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch @@ -0,0 +1,51 @@ +From e428238e9c2017375e5f5e1a492385abac5937c1 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 26 Oct 2015 11:41:54 +0100 +Subject: [PATCH 238/398] sd: implement + vcl::ITiledRenderable::isMimeTypeSupported() + +Change-Id: I528ac9f9f687d2940c6477b1d33264f1e523051f +(cherry picked from commit b08546eb23aa8dfc2f139731f800031f147e32d7) +--- + sd/source/ui/inc/unomodel.hxx | 2 ++ + sd/source/ui/unoidl/unomodel.cxx | 11 +++++++++++ + 2 files changed, 13 insertions(+) + +diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx +index a24f774e2fc9..741cfd356e39 100644 +--- a/sd/source/ui/inc/unomodel.hxx ++++ b/sd/source/ui/inc/unomodel.hxx +@@ -260,6 +260,8 @@ public: + virtual void resetSelection() override; + /// @see vcl::ITiledRenderable::getWindow(). + virtual vcl::Window* getWindow() override; ++ /// @see vcl::ITiledRenderable::isMimeTypeSupported(). ++ virtual bool isMimeTypeSupported() override; + + // XComponent + +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 1628a18df296..31954b68f114 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2550,6 +2550,17 @@ vcl::Window* SdXImpressDocument::getWindow() + return pViewShell->GetActiveWindow(); + } + ++bool SdXImpressDocument::isMimeTypeSupported() ++{ ++ SolarMutexGuard aGuard; ++ DrawViewShell* pViewShell = GetViewShell(); ++ if (!pViewShell) ++ return false; ++ ++ TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewShell->GetActiveWindow())); ++ return EditEngine::HasValidData(aDataHelper.GetTransferable()); ++} ++ + uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable() + { + uno::Reference< i18n::XForbiddenCharacters > xForb(mxForbidenCharacters); +-- +2.12.0 + diff --git a/SOURCES/0239-vcl-getWindow-setClipboard-in-ITiledRenderable.patch b/SOURCES/0239-vcl-getWindow-setClipboard-in-ITiledRenderable.patch new file mode 100644 index 0000000..32a0ae3 --- /dev/null +++ b/SOURCES/0239-vcl-getWindow-setClipboard-in-ITiledRenderable.patch @@ -0,0 +1,169 @@ +From 857dfce43c26d197beaa330cd4f005ce2cfb5360 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 28 Oct 2015 09:44:37 +0100 +Subject: [PATCH 239/398] vcl: getWindow() -> setClipboard() in + ITiledRenderable + +It's cleaner to let the apps do this themselves than exposing their +underlying vcl::Window. + +Change-Id: Iff2442dd325fa65a0cf3ad4aa7f918542dab1e4c +(cherry picked from commit bfd79be417358822023691cf7b7b2946906100ca) +--- + desktop/source/lib/init.cxx | 9 +-------- + include/vcl/ITiledRenderable.hxx | 4 ++-- + sc/inc/docuno.hxx | 4 ++-- + sc/source/ui/unoobj/docuno.cxx | 6 +++--- + sd/source/ui/inc/unomodel.hxx | 4 ++-- + sd/source/ui/unoidl/unomodel.cxx | 6 +++--- + sw/inc/unotxdoc.hxx | 4 ++-- + sw/source/uibase/uno/unotxdoc.cxx | 4 ++-- + 8 files changed, 17 insertions(+), 24 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 75df1528fd51..80c3d0389504 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1008,14 +1008,7 @@ static bool doc_paste(LibreOfficeKitDocument* pThis, const char* pMimeType, cons + uno::Reference xTransferable(new LOKTransferable(pMimeType, pData, nSize)); + uno::Reference xClipboard(new LOKClipboard()); + xClipboard->setContents(xTransferable, uno::Reference()); +- vcl::Window* pWindow = pDoc->getWindow(); +- if (!pWindow) +- { +- gImpl->maLastExceptionMsg = "Document did not provide a window"; +- return false; +- } +- +- pWindow->SetClipboard(xClipboard); ++ pDoc->setClipboard(xClipboard); + if (!pDoc->isMimeTypeSupported()) + { + if (gImpl) +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 4fa23386bfbc..8ae719edf752 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -148,8 +148,8 @@ public: + return OUString(); + } + +- /// Returns the current vcl::Window of the component. +- virtual vcl::Window* getWindow() = 0; ++ /// Sets the clipboard of the component. ++ virtual void setClipboard(const css::uno::Reference& xClipboard) = 0; + + /// If the current contents of the clipboard is something we can paste. + virtual bool isMimeTypeSupported() = 0; +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index 1e3aae1d302b..a8595b00c36e 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -416,8 +416,8 @@ public: + /// @see lok::Document::resetSelection(). + virtual void resetSelection() override; + +- /// @see vcl::ITiledRenderable::getWindow(). +- virtual vcl::Window* getWindow() override; ++ /// @see vcl::ITiledRenderable::setClipboard(). ++ virtual void setClipboard(const css::uno::Reference& xClipboard) override; + + /// @see vcl::ITiledRenderable::isMimeTypeSupported(). + virtual bool isMimeTypeSupported() override; +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index af6bd11ba742..d58d6a900856 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -846,15 +846,15 @@ void ScModelObj::resetSelection() + pDocShell->GetDocument().GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, ""); + } + +-vcl::Window* ScModelObj::getWindow() ++void ScModelObj::setClipboard(const uno::Reference& xClipboard) + { + SolarMutexGuard aGuard; + + ScViewData* pViewData = ScDocShell::GetViewData(); + if (!pViewData) +- return 0; ++ return; + +- return pViewData->GetActiveWin(); ++ pViewData->GetActiveWin()->SetClipboard(xClipboard); + } + + bool ScModelObj::isMimeTypeSupported() +diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx +index 741cfd356e39..8178aab1f1fa 100644 +--- a/sd/source/ui/inc/unomodel.hxx ++++ b/sd/source/ui/inc/unomodel.hxx +@@ -258,8 +258,8 @@ public: + virtual void setGraphicSelection(int nType, int nX, int nY) SAL_OVERRIDE; + /// @see lok::Document::resetSelection(). + virtual void resetSelection() override; +- /// @see vcl::ITiledRenderable::getWindow(). +- virtual vcl::Window* getWindow() override; ++ /// @see vcl::ITiledRenderable::setClipboard(). ++ virtual void setClipboard(const css::uno::Reference& xClipboard) override; + /// @see vcl::ITiledRenderable::isMimeTypeSupported(). + virtual bool isMimeTypeSupported() override; + +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 31954b68f114..d2c6b5e37603 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2539,15 +2539,15 @@ void SdXImpressDocument::resetSelection() + pSdrView->UnmarkAll(); + } + +-vcl::Window* SdXImpressDocument::getWindow() ++void SdXImpressDocument::setClipboard(const uno::Reference& xClipboard) + { + SolarMutexGuard aGuard; + + DrawViewShell* pViewShell = GetViewShell(); + if (!pViewShell) +- return 0; ++ return; + +- return pViewShell->GetActiveWindow(); ++ pViewShell->GetActiveWindow()->SetClipboard(xClipboard); + } + + bool SdXImpressDocument::isMimeTypeSupported() +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index 180ceb891b89..85605d56c60f 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -434,8 +434,8 @@ public: + virtual void resetSelection() SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::getPartPageRectangles(). + virtual OUString getPartPageRectangles() override; +- /// @see vcl::ITiledRenderable::getWindow(). +- virtual vcl::Window* getWindow() override; ++ /// @see vcl::ITiledRenderable::setClipboard(). ++ virtual void setClipboard(const css::uno::Reference& xClipboard) override; + /// @see vcl::ITiledRenderable::isMimeTypeSupported(). + virtual bool isMimeTypeSupported() override; + +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index b50096bbbaa8..4de023d1275c 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3188,11 +3188,11 @@ OUString SwXTextDocument::getPartPageRectangles() + return pWrtShell->getPageRectangles(); + } + +-vcl::Window* SwXTextDocument::getWindow() ++void SwXTextDocument::setClipboard(const uno::Reference& xClipboard) + { + SolarMutexGuard aGuard; + +- return &pDocShell->GetView()->GetEditWin(); ++ pDocShell->GetView()->GetEditWin().SetClipboard(xClipboard); + } + + bool SwXTextDocument::isMimeTypeSupported() +-- +2.12.0 + diff --git a/SOURCES/0240-LOK-font-back-color-feedback.patch b/SOURCES/0240-LOK-font-back-color-feedback.patch new file mode 100644 index 0000000..e8de82c --- /dev/null +++ b/SOURCES/0240-LOK-font-back-color-feedback.patch @@ -0,0 +1,50 @@ +From c99c25c3d09c53667b3a9e90573ae25cd4f0d74b Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Thu, 29 Oct 2015 16:28:37 +0200 +Subject: [PATCH 240/398] LOK: font/back color feedback + +This is used to know the current font/back color + +Change-Id: Ic524fcb5c26e1c15ec9c50b2879465152ac8ee34 +(cherry picked from commit 8e3685228d833233fc9a912a5e97df0e14597928) +--- + desktop/source/lib/init.cxx | 4 +++- + sfx2/source/control/unoctitm.cxx | 7 +++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 80c3d0389504..9dacde8b0287 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -565,7 +565,9 @@ static void doc_iniUnoCommands () + OUString(".uno:DecrementIndent"), + OUString(".uno:CharFontName"), + OUString(".uno:FontHeight"), +- OUString(".uno:StyleApply") ++ OUString(".uno:StyleApply"), ++ OUString(".uno:FontColor"), ++ OUString(".uno:BackColor") + }; + + util::URL aCommandURL; +diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx +index bb5d6720029f..843e93d4feae 100644 +--- a/sfx2/source/control/unoctitm.cxx ++++ b/sfx2/source/control/unoctitm.cxx +@@ -1100,6 +1100,13 @@ void SfxDispatchController_Impl::InterceptLOKStateChangeEvent(const SfxObjectShe + aEvent.State >>= aTemplate; + aBuffer.append(aTemplate.StyleName); + } ++ else if (aEvent.FeatureURL.Path == "FontColor" || ++ aEvent.FeatureURL.Path == "BackColor") ++ { ++ long nColor; ++ aEvent.State >>= nColor; ++ aBuffer.append(nColor); ++ } + else + { + return; +-- +2.12.0 + diff --git a/SOURCES/0241-LOK-font-back-color-callback-use-sal_Int32-instead-o.patch b/SOURCES/0241-LOK-font-back-color-callback-use-sal_Int32-instead-o.patch new file mode 100644 index 0000000..e7dcb57 --- /dev/null +++ b/SOURCES/0241-LOK-font-back-color-callback-use-sal_Int32-instead-o.patch @@ -0,0 +1,28 @@ +From 4874f8d8125de27fbc98f9f39025e66509be90c2 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Thu, 29 Oct 2015 16:52:42 +0200 +Subject: [PATCH 241/398] LOK: font/back color callback - use sal_Int32 instead + of long + +Change-Id: I2e2ebc5a12794e9641a6195f07fa4b2d1a7369a9 +(cherry picked from commit ee73a6c5573391f5f8e2f100f8392c34d6c61344) +--- + sfx2/source/control/unoctitm.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx +index 843e93d4feae..42d128a20298 100644 +--- a/sfx2/source/control/unoctitm.cxx ++++ b/sfx2/source/control/unoctitm.cxx +@@ -1103,7 +1103,7 @@ void SfxDispatchController_Impl::InterceptLOKStateChangeEvent(const SfxObjectShe + else if (aEvent.FeatureURL.Path == "FontColor" || + aEvent.FeatureURL.Path == "BackColor") + { +- long nColor; ++ sal_Int32 nColor = -1; + aEvent.State >>= nColor; + aBuffer.append(nColor); + } +-- +2.12.0 + diff --git a/SOURCES/0242-lokdocview-ensure-private-structure-is-allocated-wit.patch b/SOURCES/0242-lokdocview-ensure-private-structure-is-allocated-wit.patch new file mode 100644 index 0000000..33fa427 --- /dev/null +++ b/SOURCES/0242-lokdocview-ensure-private-structure-is-allocated-wit.patch @@ -0,0 +1,519 @@ +From 1c92d1b2e1ac5b48a3c010c8fcaffc88f80e13da Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 30 Oct 2015 08:31:43 +0100 +Subject: [PATCH 242/398] lokdocview: ensure private structure is allocated + with operator new + +It's undesirable to malloc a struct that has a TileBuffer member, while +TileBuffer doesn't have a default ctor. + +Change-Id: I72dfacc0088f238ee101d84838bd7eea51ced82a +(cherry picked from commit bd0ec1e68dcbc344cbaa50e35608bab95925fcaf) +--- + libreofficekit/source/gtk/lokdocview.cxx | 152 +++++++++++++++++++++---------- + libreofficekit/source/gtk/tilebuffer.hxx | 4 +- + 2 files changed, 108 insertions(+), 48 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index bbb87115fa4f..29b028c7b5d0 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -39,7 +39,7 @@ + #define GRAPHIC_HANDLE_COUNT 8 + + /// Private struct used by this GObject type +-struct _LOKDocViewPrivate ++struct LOKDocViewPrivateImpl + { + const gchar* m_aLOPath; + const gchar* m_aDocPath; +@@ -115,6 +115,58 @@ struct _LOKDocViewPrivate + + /// View ID, returned by createView() or 0 by default. + int m_nViewId; ++ ++ LOKDocViewPrivateImpl() ++ : m_aLOPath(0), ++ m_aDocPath(0), ++ m_nLoadProgress(0), ++ m_bIsLoading(false), ++ m_bCanZoomIn(false), ++ m_bCanZoomOut(false), ++ m_pOffice(0), ++ m_pDocument(0), ++ lokThreadPool(0), ++ m_fZoom(0), ++ m_nDocumentWidthTwips(0), ++ m_nDocumentHeightTwips(0), ++ m_bEdit(FALSE), ++ m_aVisibleCursor({0, 0, 0, 0}), ++ m_bCursorOverlayVisible(false), ++ m_bCursorVisible(true), ++ m_nLastButtonPressTime(0), ++ m_nLastButtonReleaseTime(0), ++ m_nLastButtonPressed(0), ++ m_nKeyModifier(0), ++ m_aTextSelectionStart({0, 0, 0, 0}), ++ m_aTextSelectionEnd({0, 0, 0, 0}), ++ m_aGraphicSelection({0, 0, 0, 0}), ++ m_bInDragGraphicSelection(false), ++ m_pHandleStart(0), ++ m_aHandleStartRect({0, 0, 0, 0}), ++ m_bInDragStartHandle(0), ++ m_pHandleMiddle(0), ++ m_aHandleMiddleRect({0, 0, 0, 0}), ++ m_bInDragMiddleHandle(false), ++ m_pHandleEnd(0), ++ m_aHandleEndRect({0, 0, 0, 0}), ++ m_bInDragEndHandle(false), ++ m_pGraphicHandle(0), ++ m_nViewId(0) ++ { ++ memset(&m_aGraphicHandleRects, 0, sizeof(m_aGraphicHandleRects)); ++ memset(&m_bInDragGraphicHandles, 0, sizeof(m_bInDragGraphicHandles)); ++ } ++}; ++ ++/// Wrapper around LOKDocViewPrivateImpl, managed by malloc/memset/free. ++struct _LOKDocViewPrivate ++{ ++ LOKDocViewPrivateImpl* m_pImpl; ++ ++ LOKDocViewPrivateImpl* operator->() ++ { ++ return m_pImpl; ++ } + }; + + enum +@@ -167,6 +219,12 @@ G_DEFINE_TYPE_WITH_CODE (LOKDocView, lok_doc_view, GTK_TYPE_DRAWING_AREA, + #pragma GCC diagnostic pop + #endif + ++static LOKDocViewPrivate& getPrivate(LOKDocView* pDocView) ++{ ++ LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private(pDocView)); ++ return *priv; ++} ++ + /// Helper struct used to pass the data from soffice thread -> main thread. + struct CallbackData + { +@@ -249,7 +307,7 @@ postKeyEventInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); +@@ -263,7 +321,7 @@ static gboolean + signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + { + LOKDocView* pDocView = LOK_DOC_VIEW(pWidget); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + int nCharCode = 0; + int nKeyCode = 0; + GError* error = NULL; +@@ -372,7 +430,7 @@ static gboolean + handleTimeout (gpointer pData) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pData); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + if (priv->m_bEdit) + { +@@ -429,7 +487,7 @@ static gboolean queueDraw(gpointer pData) + static gboolean postDocumentLoad(gpointer pData) + { + LOKDocView* pLOKDocView = static_cast(pData); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private(pLOKDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pLOKDocView); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); +@@ -462,7 +520,7 @@ static gboolean + globalCallback (gpointer pData) + { + CallbackData* pCallback = static_cast(pData); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pCallback->m_pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pCallback->m_pDocView); + + switch (pCallback->m_nType) + { +@@ -506,7 +564,7 @@ globalCallbackWorker(int nType, const char* pPayload, void* pData) + static GdkRectangle + payloadToRectangle (LOKDocView* pDocView, const char* pPayload) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GdkRectangle aRet; + gchar** ppCoordinates = g_strsplit(pPayload, ", ", 4); + gchar** ppCoordinate = ppCoordinates; +@@ -558,7 +616,7 @@ payloadToRectangles(LOKDocView* pDocView, const char* pPayload) + static void + setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GdkRectangle aRectanglePixels; + GdkPoint aStart, aEnd; + +@@ -587,7 +645,7 @@ callback (gpointer pData) + { + CallbackData* pCallback = static_cast(pData); + LOKDocView* pDocView = LOK_DOC_VIEW (pCallback->m_pDocView); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + switch (pCallback->m_nType) + { +@@ -720,7 +778,7 @@ renderHandle(LOKDocView* pDocView, + cairo_surface_t* pHandle, + GdkRectangle& rRectangle) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GdkPoint aCursorBottom; + int nHandleWidth, nHandleHeight; + double fHandleScale; +@@ -753,7 +811,7 @@ renderGraphicHandle(LOKDocView* pDocView, + const GdkRectangle& rSelection, + cairo_surface_t* pHandle) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + int nHandleWidth, nHandleHeight; + GdkRectangle aSelection; + +@@ -819,7 +877,7 @@ renderGraphicHandle(LOKDocView* pDocView, + static gboolean + renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GdkRectangle aVisibleArea; + long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, priv->m_fZoom); + long nDocumentHeightPixels = twipToPixel(priv->m_nDocumentHeightTwips, priv->m_fZoom); +@@ -882,7 +940,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + static gboolean + renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + if (priv->m_bEdit && priv->m_bCursorVisible && priv->m_bCursorOverlayVisible && !isEmptyRectangle(priv->m_aVisibleCursor)) + { +@@ -960,7 +1018,7 @@ static gboolean + lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GError* error = NULL; + + g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", +@@ -1203,7 +1261,7 @@ static gboolean + lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GdkPoint aPoint; + GError* error = NULL; + +@@ -1300,7 +1358,7 @@ setGraphicSelectionInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); +@@ -1315,7 +1373,7 @@ postMouseEventInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); +@@ -1333,7 +1391,7 @@ openDocumentInThread (gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + if ( priv->m_pDocument ) + { +@@ -1360,7 +1418,7 @@ setPartInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + int nPart = pLOEvent->m_nPart; + +@@ -1373,7 +1431,7 @@ setPartmodeInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + int nPartMode = pLOEvent->m_nPartMode; + +@@ -1386,7 +1444,7 @@ setEditInThread(gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + gboolean bWasEdit = priv->m_bEdit; + gboolean bEdit = pLOEvent->m_bEdit; +@@ -1410,7 +1468,7 @@ postCommandInThread (gpointer data) + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + std::stringstream ss; +@@ -1424,7 +1482,7 @@ paintTileInThread (gpointer data) + { + GTask* task = G_TASK(data); + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + TileBuffer& buffer = priv->m_aTileBuffer; + int index = pLOEvent->m_nPaintTileX * buffer.m_nWidth + pLOEvent->m_nPaintTileY; +@@ -1508,8 +1566,8 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + + static void lok_doc_view_init (LOKDocView* pDocView) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); +- priv->m_bCursorVisible = true; ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ priv.m_pImpl = new LOKDocViewPrivateImpl(); + + gtk_widget_add_events(GTK_WIDGET(pDocView), + GDK_BUTTON_PRESS_MASK +@@ -1528,7 +1586,7 @@ static void lok_doc_view_init (LOKDocView* pDocView) + static void lok_doc_view_set_property (GObject* object, guint propId, const GValue *value, GParamSpec *pspec) + { + LOKDocView* pDocView = LOK_DOC_VIEW (object); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + switch (propId) + { +@@ -1564,7 +1622,7 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal + static void lok_doc_view_get_property (GObject* object, guint propId, GValue *value, GParamSpec *pspec) + { + LOKDocView* pDocView = LOK_DOC_VIEW (object); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + switch (propId) + { +@@ -1622,12 +1680,14 @@ static gboolean lok_doc_view_draw (GtkWidget* pWidget, cairo_t* pCairo) + static void lok_doc_view_finalize (GObject* object) + { + LOKDocView* pDocView = LOK_DOC_VIEW (object); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + if (priv->m_pDocument) + priv->m_pDocument->pClass->destroy (priv->m_pDocument); + if (priv->m_pOffice) + priv->m_pOffice->pClass->destroy (priv->m_pOffice); ++ delete priv.m_pImpl; ++ priv.m_pImpl = 0; + + G_OBJECT_CLASS (lok_doc_view_parent_class)->finalize (object); + } +@@ -1635,7 +1695,7 @@ static void lok_doc_view_finalize (GObject* object) + static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* /*cancellable*/, GError **error) + { + LOKDocView *pDocView = LOK_DOC_VIEW (initable); +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + if (priv->m_pOffice != NULL) + return TRUE; +@@ -1999,13 +2059,13 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOKDocView) + { +- LOKDocViewPrivate* pOldPriv = static_cast(lok_doc_view_get_instance_private(pOldLOKDocView)); ++ LOKDocViewPrivate& pOldPriv = getPrivate(pOldLOKDocView); + GtkWidget* pNewDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/0, /*error=*/0, + "lopath", pOldPriv->m_aLOPath, "lopointer", pOldPriv->m_pOffice, "docpointer", pOldPriv->m_pDocument, NULL)); + + // No documentLoad(), just a createView(). + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pNewDocView)); +- LOKDocViewPrivate* pNewPriv = static_cast(lok_doc_view_get_instance_private(LOK_DOC_VIEW(pNewDocView))); ++ LOKDocViewPrivate& pNewPriv = getPrivate(LOK_DOC_VIEW(pNewDocView)); + pNewPriv->m_nViewId = pDocument->pClass->createView(pDocument); + + postDocumentLoad(pNewDocView); +@@ -2033,7 +2093,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + gpointer userdata) + { + GTask* task = g_task_new(pDocView, cancellable, callback, userdata); +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GError* error = NULL; + + LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC); +@@ -2054,14 +2114,14 @@ lok_doc_view_open_document (LOKDocView* pDocView, + SAL_DLLPUBLIC_EXPORT LibreOfficeKitDocument* + lok_doc_view_get_document (LOKDocView* pDocView) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + return priv->m_pDocument; + } + + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + priv->m_fZoom = fZoom; + long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, fZoom); +@@ -2079,14 +2139,14 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_get_zoom (LOKDocView* pDocView) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + return priv->m_fZoom; + } + + SAL_DLLPUBLIC_EXPORT int + lok_doc_view_get_parts (LOKDocView* pDocView) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getParts( priv->m_pDocument ); + } +@@ -2094,7 +2154,7 @@ lok_doc_view_get_parts (LOKDocView* pDocView) + SAL_DLLPUBLIC_EXPORT int + lok_doc_view_get_part (LOKDocView* pDocView) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getPart( priv->m_pDocument ); + } +@@ -2102,7 +2162,7 @@ lok_doc_view_get_part (LOKDocView* pDocView) + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); + GError* error = NULL; +@@ -2122,7 +2182,7 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + SAL_DLLPUBLIC_EXPORT char* + lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getPartName( priv->m_pDocument, nPart ); + } +@@ -2131,7 +2191,7 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_partmode(LOKDocView* pDocView, + int nPartMode) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); + GError* error = NULL; +@@ -2150,7 +2210,7 @@ lok_doc_view_set_partmode(LOKDocView* pDocView, + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_reset_view(LOKDocView* pDocView) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + priv->m_aTileBuffer.resetAllTiles(); + priv->m_nLoadProgress = 0.0; + +@@ -2196,7 +2256,7 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_edit(LOKDocView* pDocView, + gboolean bEdit) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); + GError* error = NULL; +@@ -2215,7 +2275,7 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + SAL_DLLPUBLIC_EXPORT gboolean + lok_doc_view_get_edit (LOKDocView* pDocView) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + return priv->m_bEdit; + } + +@@ -2225,7 +2285,7 @@ lok_doc_view_post_command (LOKDocView* pDocView, + const gchar* pCommand, + const gchar* pArguments) + { +- LOKDocViewPrivate* priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); + LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); + GError* error = NULL; +@@ -2245,14 +2305,14 @@ lok_doc_view_post_command (LOKDocView* pDocView, + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + return pixelToTwip(fInput, priv->m_fZoom); + } + + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_twip_to_pixel (LOKDocView* pDocView, float fInput) + { +- LOKDocViewPrivate *priv = static_cast(lok_doc_view_get_instance_private (pDocView)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + return twipToPixel(fInput, priv->m_fZoom); + } + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 34b9001e8bc5..9361a622fb7c 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -82,8 +82,8 @@ private: + class TileBuffer + { + public: +- TileBuffer(LibreOfficeKitDocument *document, +- int columns) ++ TileBuffer(LibreOfficeKitDocument *document = 0, ++ int columns = 0) + : m_pLOKDocument(document) + , m_nWidth(columns) + { +-- +2.12.0 + diff --git a/SOURCES/0243-LOK-initial-Document-getCommandValues-for-RowColumnH.patch b/SOURCES/0243-LOK-initial-Document-getCommandValues-for-RowColumnH.patch new file mode 100644 index 0000000..b2d341d --- /dev/null +++ b/SOURCES/0243-LOK-initial-Document-getCommandValues-for-RowColumnH.patch @@ -0,0 +1,166 @@ +From 406b705cba1093c06770a2f09da6dd95a0c2bf3c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 30 Oct 2015 11:18:19 +0100 +Subject: [PATCH 243/398] LOK: initial Document::getCommandValues() for + RowColumnHeaders + +Only the row info and for the entire tiled rendering area as a start. + +Change-Id: Idbccd805b355e8d151ab7025ac1cf0c686cb237b +(cherry picked from commit a7ce5f83343f8f6ba8a59b05820b3a2066c0ce9a) +--- + desktop/source/lib/init.cxx | 18 +++++++++++++++++- + include/vcl/ITiledRenderable.hxx | 8 ++++++++ + sc/inc/docuno.hxx | 3 +++ + sc/source/ui/inc/tabview.hxx | 2 ++ + sc/source/ui/unoobj/docuno.cxx | 13 +++++++++++++ + sc/source/ui/view/tabview.cxx | 29 +++++++++++++++++++++++++++++ + 6 files changed, 72 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 9dacde8b0287..6785ae2328d4 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1134,7 +1134,23 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + { + return getStyles(pThis, pCommand); + } +- else { ++ else if (OString(pCommand) == ".uno:ViewRowColumnHeaders") ++ { ++ ITiledRenderable* pDoc = getTiledRenderable(pThis); ++ if (!pDoc) ++ { ++ gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; ++ return 0; ++ } ++ ++ OUString aHeaders = pDoc->getRowColumnHeaders(); ++ OString aString = OUStringToOString(aHeaders, RTL_TEXTENCODING_UTF8); ++ char* pMemory = static_cast(malloc(aString.getLength() + 1)); ++ strcpy(pMemory, aString.getStr()); ++ return pMemory; ++ } ++ else ++ { + gImpl->maLastExceptionMsg = "Unknown command, no values returned"; + return NULL; + } +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 8ae719edf752..48a13ffc1275 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -148,6 +148,14 @@ public: + return OUString(); + } + ++ /** ++ * Get position and content of row/column headers of Calc documents. ++ */ ++ virtual OUString getRowColumnHeaders() ++ { ++ return OUString(); ++ } ++ + /// Sets the clipboard of the component. + virtual void setClipboard(const css::uno::Reference& xClipboard) = 0; + +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index a8595b00c36e..b4711c54c883 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -421,6 +421,9 @@ public: + + /// @see vcl::ITiledRenderable::isMimeTypeSupported(). + virtual bool isMimeTypeSupported() override; ++ ++ /// @see vcl::ITiledRenderable::getRowColumnHeaders(). ++ virtual OUString getRowColumnHeaders() override; + }; + + class ScDrawPagesObj : public cppu::WeakImplHelper2< +diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx +index d7e2a2dbf12e..5b0852041108 100644 +--- a/sc/source/ui/inc/tabview.hxx ++++ b/sc/source/ui/inc/tabview.hxx +@@ -520,6 +520,8 @@ public: + void EnableAutoSpell( bool bEnable ); + void ResetAutoSpell(); + void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector* pRanges ); ++ /// @see ScModelObj::getRowColumnHeaders(). ++ OUString getRowColumnHeaders(); + }; + + #endif +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index d58d6a900856..f9a9e03f2839 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -870,6 +870,19 @@ bool ScModelObj::isMimeTypeSupported() + return EditEngine::HasValidData(aDataHelper.GetTransferable()); + } + ++OUString ScModelObj::getRowColumnHeaders() ++{ ++ ScViewData* pViewData = ScDocShell::GetViewData(); ++ if (!pViewData) ++ return OUString(); ++ ++ ScTabView* pTabView = pViewData->GetView(); ++ if (!pTabView) ++ return OUString(); ++ ++ return pTabView->getRowColumnHeaders(); ++} ++ + void ScModelObj::initializeForTiledRendering() + { + SolarMutexGuard aGuard; +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index b5d308be1aab..f177bbe704f1 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -50,6 +50,7 @@ + + #include + #include ++#include + + #include + +@@ -2302,4 +2303,32 @@ void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vectorGetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); ++ ++ boost::property_tree::ptree aRows; ++ for (SCROW nRow = 0; nRow < nEndRow; ++nRow) ++ { ++ boost::property_tree::ptree aRow; ++ sal_uInt16 nSize = pRowBar[SC_SPLIT_BOTTOM]->GetEntrySize(nRow); ++ aRow.put("size", OString::number(nSize).getStr()); ++ OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); ++ aRow.put("text", aText.toUtf8().getStr()); ++ aRows.push_back(std::make_pair("", aRow)); ++ } ++ ++ boost::property_tree::ptree aTree; ++ aTree.add_child("rows", aRows); ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ return OUString::fromUtf8(aStream.str().c_str()); ++} ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0244-gtktiledviewer-initial-row-headers-for-spreadsheet-d.patch b/SOURCES/0244-gtktiledviewer-initial-row-headers-for-spreadsheet-d.patch new file mode 100644 index 0000000..0489bd4 --- /dev/null +++ b/SOURCES/0244-gtktiledviewer-initial-row-headers-for-spreadsheet-d.patch @@ -0,0 +1,186 @@ +From 53bcb37a3c055ba6103a64ca1a29f284b2535b79 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 30 Oct 2015 12:34:38 +0100 +Subject: [PATCH 244/398] gtktiledviewer: initial row headers for spreadsheet + documents + +Change-Id: Iec9080d7017ddcf2b605243bc820f9664110c2e8 +(cherry picked from commit ecef9cb66c5f6009c7b062b489f93de85b70beeb) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 128 ++++++++++++++++++++- + 1 file changed, 127 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 72afd52131ad..cdde08db602d 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -32,6 +32,37 @@ static int help() + return 1; + } + ++/// Represents the row header widget for spreadsheets. ++class TiledRowBar ++{ ++public: ++ /// Stores size and content of a single row header. ++ struct Header ++ { ++ int m_nSize; ++ std::string m_aText; ++ Header(int nSize, const std::string& rText) ++ : m_nSize(nSize), ++ m_aText(rText) ++ { ++ } ++ }; ++ ++ static const int HEADER_WIDTH = 50; ++ ++ GtkWidget* m_pDrawingArea; ++ std::vector
m_aHeaders; ++ int m_nHeightPixel = 0; ++ ++ TiledRowBar(GtkWidget* pDocView); ++ static gboolean draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData); ++ gboolean drawImpl(GtkWidget* pWidget, cairo_t* pCairo); ++ static gboolean docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData); ++ gboolean docConfigureEventImpl(GtkWidget* pWidget, GdkEventConfigure* pEvent); ++ /// Draws rText at the center of rRectangle on pCairo. ++ void drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText); ++}; ++ + /// Represents all the state that is specific to one GtkWindow of this app. + class TiledWindow + { +@@ -56,6 +87,7 @@ public: + GtkWidget* m_pFindbarEntry; + GtkWidget* m_pFindbarLabel; + bool m_bFindAll; ++ std::shared_ptr m_pRowBar; + + TiledWindow() + : m_pDocView(0), +@@ -92,6 +124,92 @@ static TiledWindow& lcl_getTiledWindow(GtkWidget* pWidget) + return g_aWindows[pToplevel]; + } + ++TiledRowBar::TiledRowBar(GtkWidget* pDocView) ++ : m_pDrawingArea(gtk_drawing_area_new()), ++ m_nHeightPixel(0) ++{ ++ gtk_widget_set_size_request(m_pDrawingArea, HEADER_WIDTH, -1); ++ g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(TiledRowBar::draw), this); ++ g_signal_connect(pDocView, "configure-event", G_CALLBACK(TiledRowBar::docConfigureEvent), this); ++} ++ ++gboolean TiledRowBar::draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData) ++{ ++ return static_cast(pData)->drawImpl(pWidget, pCairo); ++} ++ ++void TiledRowBar::drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText) ++{ ++ cairo_text_extents_t extents; ++ cairo_text_extents(pCairo, rText.c_str(), &extents); ++ // Cairo reference point for text is the bottom left corner. ++ cairo_move_to(pCairo, rRectangle.x + rRectangle.width / 2 - extents.width / 2, rRectangle.y + rRectangle.height / 2 + extents.height / 2); ++ cairo_show_text(pCairo, rText.c_str()); ++} ++ ++gboolean TiledRowBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) ++{ ++ cairo_set_source_rgb(pCairo, 0, 0, 0); ++ ++ int nTotal = 0; ++ for (const Header& rHeader : m_aHeaders) ++ { ++ GdkRectangle aRectangle; ++ aRectangle.x = 0; ++ aRectangle.y = nTotal - 1; ++ aRectangle.width = HEADER_WIDTH - 1; ++ aRectangle.height = rHeader.m_nSize; ++ // Bottom line. ++ cairo_rectangle(pCairo, aRectangle.x, aRectangle.y + aRectangle.height, aRectangle.width, 1); ++ cairo_fill(pCairo); ++ // Left line. ++ cairo_rectangle(pCairo, aRectangle.width, aRectangle.y, 1, aRectangle.height); ++ cairo_fill(pCairo); ++ drawText(pCairo, aRectangle, rHeader.m_aText); ++ nTotal += rHeader.m_nSize; ++ if (nTotal > m_nHeightPixel) ++ break; ++ } ++ ++ return FALSE; ++} ++ ++gboolean TiledRowBar::docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData) ++{ ++ return static_cast(pData)->docConfigureEventImpl(pWidget, pEvent); ++} ++ ++gboolean TiledRowBar::docConfigureEventImpl(GtkWidget* pDocView, GdkEventConfigure* /*pEvent*/) ++{ ++ if (g_aWindows.find(gtk_widget_get_toplevel(pDocView)) == g_aWindows.end()) ++ return TRUE; ++ ++ TiledWindow& rWindow = lcl_getTiledWindow(pDocView); ++ GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); ++ m_nHeightPixel = gtk_adjustment_get_page_size(pVAdjustment); ++ ++ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)); ++ if (pDocument && pDocument->pClass->getDocumentType(pDocument) == LOK_DOCTYPE_SPREADSHEET) ++ { ++ m_aHeaders.clear(); ++ char* pValues = pDocument->pClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); ++ std::stringstream aStream(pValues); ++ free(pValues); ++ assert(!aStream.str().empty()); ++ boost::property_tree::ptree aTree; ++ boost::property_tree::read_json(aStream, aTree); ++ for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) ++ { ++ Header aHeader(std::atoi(rValue.second.get("size").c_str()), rValue.second.get("text")); ++ m_aHeaders.push_back(aHeader); ++ } ++ gtk_widget_show(m_pDrawingArea); ++ gtk_widget_queue_draw(m_pDrawingArea); ++ } ++ ++ return TRUE; ++} ++ + static void lcl_registerToolItem(TiledWindow& rWindow, GtkToolItem* pItem, const std::string& rName) + { + rWindow.m_aToolItemCommandNames[pItem] = rName; +@@ -797,11 +915,17 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + + gtk_box_pack_end(GTK_BOX(rWindow.m_pVBox), rWindow.m_pFindbar, FALSE, FALSE, 0); + ++ // Horizontal box for the row bar + doc view. ++ GtkWidget* pHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); ++ gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), pHBox); ++ rWindow.m_pRowBar.reset(new TiledRowBar(rWindow.m_pDocView)); ++ gtk_box_pack_start(GTK_BOX(pHBox), rWindow.m_pRowBar->m_pDrawingArea, FALSE, FALSE, 0); ++ + // Scrolled window for DocView + rWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); + gtk_widget_set_hexpand(rWindow.m_pScrolledWindow, TRUE); + gtk_widget_set_vexpand(rWindow.m_pScrolledWindow, TRUE); +- gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), rWindow.m_pScrolledWindow); ++ gtk_container_add(GTK_CONTAINER(pHBox), rWindow.m_pScrolledWindow); + + gtk_container_add(GTK_CONTAINER(rWindow.m_pScrolledWindow), rWindow.m_pDocView); + +@@ -818,6 +942,8 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_widget_show_all(pWindow); + // Hide the findbar by default. + gtk_widget_hide(rWindow.m_pFindbar); ++ // Same for the row bar. ++ gtk_widget_hide(rWindow.m_pRowBar->m_pDrawingArea); + + g_aWindows[pWindow] = rWindow; + return pWindow; +-- +2.12.0 + diff --git a/SOURCES/0245-loplugin-staticmethods.patch b/SOURCES/0245-loplugin-staticmethods.patch new file mode 100644 index 0000000..b0edf75 --- /dev/null +++ b/SOURCES/0245-loplugin-staticmethods.patch @@ -0,0 +1,27 @@ +From 3c7e2e232a55843b76f10c74bc419d1a12c452f5 Mon Sep 17 00:00:00 2001 +From: Noel Grandin +Date: Fri, 30 Oct 2015 14:24:26 +0200 +Subject: [PATCH 245/398] loplugin:staticmethods + +Change-Id: I4cdf2fa91dde1968cfb984faf0bdd3aad42eefd2 +(cherry picked from commit bee72ee6199950f9489ac4ed313db63586f2b742) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index cdde08db602d..9ee6ce8a39fb 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -60,7 +60,7 @@ public: + static gboolean docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData); + gboolean docConfigureEventImpl(GtkWidget* pWidget, GdkEventConfigure* pEvent); + /// Draws rText at the center of rRectangle on pCairo. +- void drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText); ++ static void drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText); + }; + + /// Represents all the state that is specific to one GtkWindow of this app. +-- +2.12.0 + diff --git a/SOURCES/0246-gtktiledviewer-initial-column-headers-for-spreadshee.patch b/SOURCES/0246-gtktiledviewer-initial-column-headers-for-spreadshee.patch new file mode 100644 index 0000000..c632af6 --- /dev/null +++ b/SOURCES/0246-gtktiledviewer-initial-column-headers-for-spreadshee.patch @@ -0,0 +1,253 @@ +From 7d7a5c94be66cbe7dc571a8bfb56f6e30b869303 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 30 Oct 2015 14:57:16 +0100 +Subject: [PATCH 246/398] gtktiledviewer: initial column headers for + spreadsheet documents + +Change-Id: I10e88b4ff4ab0cfb29e97fa608d8acd69ce0f062 +(cherry picked from commit 18bf71a2002b979dbf80d85c8863af39783bf87d) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 131 +++++++++++++-------- + 1 file changed, 83 insertions(+), 48 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 9ee6ce8a39fb..08058e8699c9 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -32,8 +32,8 @@ static int help() + return 1; + } + +-/// Represents the row header widget for spreadsheets. +-class TiledRowBar ++/// Represents the row or column header widget for spreadsheets. ++class TiledRowColumnBar + { + public: + /// Stores size and content of a single row header. +@@ -48,17 +48,21 @@ public: + } + }; + +- static const int HEADER_WIDTH = 50; ++ enum TiledBarType { ROW, COLUMN }; ++ ++ static const int ROW_HEADER_WIDTH = 50; ++ static const int COLUMN_HEADER_HEIGHT = 20; + + GtkWidget* m_pDrawingArea; + std::vector
m_aHeaders; +- int m_nHeightPixel = 0; ++ /// Height for row bar, width for column bar. ++ int m_nSizePixel; ++ TiledBarType m_eType; + +- TiledRowBar(GtkWidget* pDocView); ++ TiledRowColumnBar(TiledBarType eType); + static gboolean draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData); + gboolean drawImpl(GtkWidget* pWidget, cairo_t* pCairo); + static gboolean docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData); +- gboolean docConfigureEventImpl(GtkWidget* pWidget, GdkEventConfigure* pEvent); + /// Draws rText at the center of rRectangle on pCairo. + static void drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText); + }; +@@ -87,7 +91,8 @@ public: + GtkWidget* m_pFindbarEntry; + GtkWidget* m_pFindbarLabel; + bool m_bFindAll; +- std::shared_ptr m_pRowBar; ++ std::shared_ptr m_pRowBar; ++ std::shared_ptr m_pColumnBar; + + TiledWindow() + : m_pDocView(0), +@@ -124,21 +129,24 @@ static TiledWindow& lcl_getTiledWindow(GtkWidget* pWidget) + return g_aWindows[pToplevel]; + } + +-TiledRowBar::TiledRowBar(GtkWidget* pDocView) ++TiledRowColumnBar::TiledRowColumnBar(TiledBarType eType) + : m_pDrawingArea(gtk_drawing_area_new()), +- m_nHeightPixel(0) ++ m_nSizePixel(0), ++ m_eType(eType) + { +- gtk_widget_set_size_request(m_pDrawingArea, HEADER_WIDTH, -1); +- g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(TiledRowBar::draw), this); +- g_signal_connect(pDocView, "configure-event", G_CALLBACK(TiledRowBar::docConfigureEvent), this); ++ if (m_eType == ROW) ++ gtk_widget_set_size_request(m_pDrawingArea, ROW_HEADER_WIDTH, -1); ++ else ++ gtk_widget_set_size_request(m_pDrawingArea, -1, COLUMN_HEADER_HEIGHT); ++ g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(TiledRowColumnBar::draw), this); + } + +-gboolean TiledRowBar::draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData) ++gboolean TiledRowColumnBar::draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData) + { +- return static_cast(pData)->drawImpl(pWidget, pCairo); ++ return static_cast(pData)->drawImpl(pWidget, pCairo); + } + +-void TiledRowBar::drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText) ++void TiledRowColumnBar::drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText) + { + cairo_text_extents_t extents; + cairo_text_extents(pCairo, rText.c_str(), &extents); +@@ -147,7 +155,7 @@ void TiledRowBar::drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, cons + cairo_show_text(pCairo, rText.c_str()); + } + +-gboolean TiledRowBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) ++gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + { + cairo_set_source_rgb(pCairo, 0, 0, 0); + +@@ -155,56 +163,76 @@ gboolean TiledRowBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + for (const Header& rHeader : m_aHeaders) + { + GdkRectangle aRectangle; +- aRectangle.x = 0; +- aRectangle.y = nTotal - 1; +- aRectangle.width = HEADER_WIDTH - 1; +- aRectangle.height = rHeader.m_nSize; +- // Bottom line. +- cairo_rectangle(pCairo, aRectangle.x, aRectangle.y + aRectangle.height, aRectangle.width, 1); +- cairo_fill(pCairo); +- // Left line. +- cairo_rectangle(pCairo, aRectangle.width, aRectangle.y, 1, aRectangle.height); +- cairo_fill(pCairo); ++ if (m_eType == ROW) ++ { ++ aRectangle.x = 0; ++ aRectangle.y = nTotal - 1; ++ aRectangle.width = ROW_HEADER_WIDTH - 1; ++ aRectangle.height = rHeader.m_nSize; ++ // Bottom line. ++ cairo_rectangle(pCairo, aRectangle.x, aRectangle.y + aRectangle.height, aRectangle.width, 1); ++ cairo_fill(pCairo); ++ // Right line. ++ cairo_rectangle(pCairo, aRectangle.width, aRectangle.y, 1, aRectangle.height); ++ cairo_fill(pCairo); ++ } ++ else ++ { ++ aRectangle.x = nTotal -1; ++ aRectangle.y = 0; ++ aRectangle.width = rHeader.m_nSize; ++ aRectangle.height = COLUMN_HEADER_HEIGHT - 1; ++ // Right line. ++ cairo_rectangle(pCairo, aRectangle.x + aRectangle.width , aRectangle.y, 1, aRectangle.height); ++ cairo_fill(pCairo); ++ // Bottom line. ++ cairo_rectangle(pCairo, aRectangle.x, aRectangle.height, aRectangle.width, 1); ++ cairo_fill(pCairo); ++ } + drawText(pCairo, aRectangle, rHeader.m_aText); + nTotal += rHeader.m_nSize; +- if (nTotal > m_nHeightPixel) ++ if (nTotal > m_nSizePixel) + break; + } + + return FALSE; + } + +-gboolean TiledRowBar::docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData) +-{ +- return static_cast(pData)->docConfigureEventImpl(pWidget, pEvent); +-} +- +-gboolean TiledRowBar::docConfigureEventImpl(GtkWidget* pDocView, GdkEventConfigure* /*pEvent*/) ++gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfigure* /*pEvent*/, gpointer /*pData*/) + { +- if (g_aWindows.find(gtk_widget_get_toplevel(pDocView)) == g_aWindows.end()) +- return TRUE; +- + TiledWindow& rWindow = lcl_getTiledWindow(pDocView); + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); +- m_nHeightPixel = gtk_adjustment_get_page_size(pVAdjustment); ++ rWindow.m_pRowBar->m_nSizePixel = gtk_adjustment_get_page_size(pVAdjustment); ++ GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); ++ rWindow.m_pColumnBar->m_nSizePixel = gtk_adjustment_get_page_size(pHAdjustment); + + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)); + if (pDocument && pDocument->pClass->getDocumentType(pDocument) == LOK_DOCTYPE_SPREADSHEET) + { +- m_aHeaders.clear(); + char* pValues = pDocument->pClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); + std::stringstream aStream(pValues); + free(pValues); + assert(!aStream.str().empty()); + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); ++ ++ rWindow.m_pRowBar->m_aHeaders.clear(); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { + Header aHeader(std::atoi(rValue.second.get("size").c_str()), rValue.second.get("text")); +- m_aHeaders.push_back(aHeader); ++ rWindow.m_pRowBar->m_aHeaders.push_back(aHeader); ++ } ++ gtk_widget_show(rWindow.m_pRowBar->m_pDrawingArea); ++ gtk_widget_queue_draw(rWindow.m_pRowBar->m_pDrawingArea); ++ ++ rWindow.m_pColumnBar->m_aHeaders.clear(); ++ for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns")) ++ { ++ Header aHeader(std::atoi(rValue.second.get("size").c_str()), rValue.second.get("text")); ++ rWindow.m_pColumnBar->m_aHeaders.push_back(aHeader); + } +- gtk_widget_show(m_pDrawingArea); +- gtk_widget_queue_draw(m_pDrawingArea); ++ gtk_widget_show(rWindow.m_pColumnBar->m_pDrawingArea); ++ gtk_widget_queue_draw(rWindow.m_pColumnBar->m_pDrawingArea); + } + + return TRUE; +@@ -915,17 +943,22 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + + gtk_box_pack_end(GTK_BOX(rWindow.m_pVBox), rWindow.m_pFindbar, FALSE, FALSE, 0); + +- // Horizontal box for the row bar + doc view. +- GtkWidget* pHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); +- gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), pHBox); +- rWindow.m_pRowBar.reset(new TiledRowBar(rWindow.m_pDocView)); +- gtk_box_pack_start(GTK_BOX(pHBox), rWindow.m_pRowBar->m_pDrawingArea, FALSE, FALSE, 0); ++ // Grid for the row/column bar + doc view. ++ GtkWidget* pGrid = gtk_grid_new(); ++ gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), pGrid); ++ rWindow.m_pRowBar.reset(new TiledRowColumnBar(TiledRowColumnBar::ROW)); ++ // "A2" cell of the grid. ++ gtk_grid_attach(GTK_GRID(pGrid), rWindow.m_pRowBar->m_pDrawingArea, 0, 1, 1, 1); ++ rWindow.m_pColumnBar.reset(new TiledRowColumnBar(TiledRowColumnBar::COLUMN)); ++ // "B1" cell of the grid. ++ gtk_grid_attach(GTK_GRID(pGrid), rWindow.m_pColumnBar->m_pDrawingArea, 1, 0, 1, 1); + + // Scrolled window for DocView + rWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); + gtk_widget_set_hexpand(rWindow.m_pScrolledWindow, TRUE); + gtk_widget_set_vexpand(rWindow.m_pScrolledWindow, TRUE); +- gtk_container_add(GTK_CONTAINER(pHBox), rWindow.m_pScrolledWindow); ++ // "B2" cell of the grid ++ gtk_grid_attach(GTK_GRID(pGrid), rWindow.m_pScrolledWindow, 1, 1, 1, 1); + + gtk_container_add(GTK_CONTAINER(rWindow.m_pScrolledWindow), rWindow.m_pDocView); + +@@ -942,10 +975,12 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_widget_show_all(pWindow); + // Hide the findbar by default. + gtk_widget_hide(rWindow.m_pFindbar); +- // Same for the row bar. ++ // Same for the row/column bar. + gtk_widget_hide(rWindow.m_pRowBar->m_pDrawingArea); ++ gtk_widget_hide(rWindow.m_pColumnBar->m_pDrawingArea); + + g_aWindows[pWindow] = rWindow; ++ g_signal_connect(rWindow.m_pDocView, "configure-event", G_CALLBACK(TiledRowColumnBar::docConfigureEvent), 0); + return pWindow; + } + +-- +2.12.0 + diff --git a/SOURCES/0247-gtktiledviewer-add-missing-spreadsheet-corner-button.patch b/SOURCES/0247-gtktiledviewer-add-missing-spreadsheet-corner-button.patch new file mode 100644 index 0000000..2f1a539 --- /dev/null +++ b/SOURCES/0247-gtktiledviewer-add-missing-spreadsheet-corner-button.patch @@ -0,0 +1,129 @@ +From d2cc43af0d971232e843b20a7f2370baf5aecd17 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 30 Oct 2015 16:20:58 +0100 +Subject: [PATCH 247/398] gtktiledviewer: add missing spreadsheet corner button + +Change-Id: I3a7af693ccdce2012ddbaa6a3ac8321f29b6356c +(cherry picked from commit f5ab3e84dfd58722dc74c7369c1ad67237ca462e) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 52 +++++++++++++++++++++- + 1 file changed, 51 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 08058e8699c9..eec80ba0b727 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -67,6 +67,16 @@ public: + static void drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText); + }; + ++/// Represents the button at the top left corner for spreadsheets. ++class TiledCornerButton ++{ ++public: ++ GtkWidget* m_pDrawingArea; ++ TiledCornerButton(); ++ static gboolean draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData); ++ gboolean drawImpl(GtkWidget* pWidget, cairo_t* pCairo); ++}; ++ + /// Represents all the state that is specific to one GtkWindow of this app. + class TiledWindow + { +@@ -93,6 +103,7 @@ public: + bool m_bFindAll; + std::shared_ptr m_pRowBar; + std::shared_ptr m_pColumnBar; ++ std::shared_ptr m_pCornerButton; + + TiledWindow() + : m_pDocView(0), +@@ -169,6 +180,9 @@ gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + aRectangle.y = nTotal - 1; + aRectangle.width = ROW_HEADER_WIDTH - 1; + aRectangle.height = rHeader.m_nSize; ++ // Left line. ++ cairo_rectangle(pCairo, aRectangle.x, aRectangle.y, 1, aRectangle.height); ++ cairo_fill(pCairo); + // Bottom line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.y + aRectangle.height, aRectangle.width, 1); + cairo_fill(pCairo); +@@ -178,10 +192,13 @@ gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + } + else + { +- aRectangle.x = nTotal -1; ++ aRectangle.x = nTotal - 1; + aRectangle.y = 0; + aRectangle.width = rHeader.m_nSize; + aRectangle.height = COLUMN_HEADER_HEIGHT - 1; ++ // Top line. ++ cairo_rectangle(pCairo, aRectangle.x, aRectangle.y, aRectangle.width, 1); ++ cairo_fill(pCairo); + // Right line. + cairo_rectangle(pCairo, aRectangle.x + aRectangle.width , aRectangle.y, 1, aRectangle.height); + cairo_fill(pCairo); +@@ -216,6 +233,8 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + boost::property_tree::ptree aTree; + boost::property_tree::read_json(aStream, aTree); + ++ gtk_widget_show(rWindow.m_pCornerButton->m_pDrawingArea); ++ + rWindow.m_pRowBar->m_aHeaders.clear(); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { +@@ -238,6 +257,33 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + return TRUE; + } + ++TiledCornerButton::TiledCornerButton() ++ : m_pDrawingArea(gtk_drawing_area_new()) ++{ ++ gtk_widget_set_size_request(m_pDrawingArea, TiledRowColumnBar::ROW_HEADER_WIDTH, TiledRowColumnBar::COLUMN_HEADER_HEIGHT); ++ g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(TiledCornerButton::draw), this); ++} ++ ++gboolean TiledCornerButton::draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData) ++{ ++ return static_cast(pData)->drawImpl(pWidget, pCairo); ++} ++ ++gboolean TiledCornerButton::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) ++{ ++ cairo_set_source_rgb(pCairo, 0, 0, 0); ++ ++ GdkRectangle aRectangle; ++ aRectangle.x = 0; ++ aRectangle.y = 0; ++ aRectangle.width = TiledRowColumnBar::ROW_HEADER_WIDTH; ++ aRectangle.height = TiledRowColumnBar::COLUMN_HEADER_HEIGHT; ++ cairo_rectangle(pCairo, aRectangle.x, aRectangle.y, aRectangle.width, aRectangle.height); ++ cairo_stroke(pCairo); ++ ++ return FALSE; ++} ++ + static void lcl_registerToolItem(TiledWindow& rWindow, GtkToolItem* pItem, const std::string& rName) + { + rWindow.m_aToolItemCommandNames[pItem] = rName; +@@ -946,6 +992,9 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + // Grid for the row/column bar + doc view. + GtkWidget* pGrid = gtk_grid_new(); + gtk_container_add(GTK_CONTAINER(rWindow.m_pVBox), pGrid); ++ rWindow.m_pCornerButton.reset(new TiledCornerButton()); ++ // "A1" cell of the grid. ++ gtk_grid_attach(GTK_GRID(pGrid), rWindow.m_pCornerButton->m_pDrawingArea, 0, 0, 1, 1); + rWindow.m_pRowBar.reset(new TiledRowColumnBar(TiledRowColumnBar::ROW)); + // "A2" cell of the grid. + gtk_grid_attach(GTK_GRID(pGrid), rWindow.m_pRowBar->m_pDrawingArea, 0, 1, 1, 1); +@@ -976,6 +1025,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + // Hide the findbar by default. + gtk_widget_hide(rWindow.m_pFindbar); + // Same for the row/column bar. ++ gtk_widget_hide(rWindow.m_pCornerButton->m_pDrawingArea); + gtk_widget_hide(rWindow.m_pRowBar->m_pDrawingArea); + gtk_widget_hide(rWindow.m_pColumnBar->m_pDrawingArea); + +-- +2.12.0 + diff --git a/SOURCES/0248-loplugin-staticmethods.patch b/SOURCES/0248-loplugin-staticmethods.patch new file mode 100644 index 0000000..5733711 --- /dev/null +++ b/SOURCES/0248-loplugin-staticmethods.patch @@ -0,0 +1,39 @@ +From 0fb26aeb7fb8385ee19b1d79aeaa9dd51ed18071 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Fri, 30 Oct 2015 16:54:39 +0100 +Subject: [PATCH 248/398] loplugin:staticmethods + +Change-Id: I9ac908d0981734e4b2930a79f160ec0462127483 +(cherry picked from commit 86585175a607982f0549ddad19851f1ebf52148c) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index eec80ba0b727..1049c288a14b 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -74,7 +74,7 @@ public: + GtkWidget* m_pDrawingArea; + TiledCornerButton(); + static gboolean draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData); +- gboolean drawImpl(GtkWidget* pWidget, cairo_t* pCairo); ++ static gboolean drawImpl(GtkWidget* pWidget, cairo_t* pCairo); + }; + + /// Represents all the state that is specific to one GtkWindow of this app. +@@ -264,9 +264,9 @@ TiledCornerButton::TiledCornerButton() + g_signal_connect(m_pDrawingArea, "draw", G_CALLBACK(TiledCornerButton::draw), this); + } + +-gboolean TiledCornerButton::draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData) ++gboolean TiledCornerButton::draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer) + { +- return static_cast(pData)->drawImpl(pWidget, pCairo); ++ return drawImpl(pWidget, pCairo); + } + + gboolean TiledCornerButton::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) +-- +2.12.0 + diff --git a/SOURCES/0249-sc-lok-Always-provide-a-reasonable-document-size.patch b/SOURCES/0249-sc-lok-Always-provide-a-reasonable-document-size.patch new file mode 100644 index 0000000..30c8f9b --- /dev/null +++ b/SOURCES/0249-sc-lok-Always-provide-a-reasonable-document-size.patch @@ -0,0 +1,44 @@ +From abae8af12a4ecb926261a4cee6f92561478ac606 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Sat, 31 Oct 2015 00:24:17 +0100 +Subject: [PATCH 249/398] sc lok: Always provide a reasonable document size. + +With an empty document, GetPrintArea() returned false, causing nothing visible +on the screen. + +Also increase the values when I'm touching this. + +Change-Id: Iee7544a428d5d4d5d5931230a51e605302557f41 +(cherry picked from commit 5409dc0847a4ec17f5791f577249d47913f12b48) +--- + sc/source/core/data/documen2.cxx | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx +index 8d3e4e3d3b8f..2a305c032f2b 100644 +--- a/sc/source/core/data/documen2.cxx ++++ b/sc/source/core/data/documen2.cxx +@@ -708,15 +708,14 @@ bool ScDocument::GetDataStart( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow ) + + bool ScDocument::GetTiledRenderingArea(SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow) const + { +- if (!GetPrintArea(nTab, rEndCol, rEndRow, false)) +- return false; ++ bool bHasPrintArea = GetPrintArea(nTab, rEndCol, rEndRow, false); + + // we need some reasonable minimal document size +- if (rEndCol < 12) +- rEndCol = 12; ++ if (!bHasPrintArea || rEndCol < 20) ++ rEndCol = 20; + +- if (rEndRow < 36) +- rEndRow = 36; ++ if (!bHasPrintArea || rEndRow < 50) ++ rEndRow = 50; + + return true; + } +-- +2.12.0 + diff --git a/SOURCES/0250-lokdocview-Fix-memory-leaks.patch b/SOURCES/0250-lokdocview-Fix-memory-leaks.patch new file mode 100644 index 0000000..c85116c --- /dev/null +++ b/SOURCES/0250-lokdocview-Fix-memory-leaks.patch @@ -0,0 +1,165 @@ +From 565d5396ec1285508ca20544ab01569819b4b540 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 25 Oct 2015 19:22:46 +0530 +Subject: [PATCH 250/398] lokdocview: Fix memory leaks + +Change-Id: I5107e4fa1828145a709e1edffe02831f4faae3c8 +Reviewed-on: https://gerrit.libreoffice.org/19676 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit cfbc36e2eade42e471056d3c32fc962cd3149c17) +--- + libreofficekit/source/gtk/lokdocview.cxx | 33 ++++++++++++++++---------------- + libreofficekit/source/gtk/tilebuffer.cxx | 5 +++++ + libreofficekit/source/gtk/tilebuffer.hxx | 8 ++++++-- + 3 files changed, 28 insertions(+), 18 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 29b028c7b5d0..2ec27305af4e 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -50,7 +50,7 @@ struct LOKDocViewPrivateImpl + LibreOfficeKit* m_pOffice; + LibreOfficeKitDocument* m_pDocument; + +- TileBuffer m_aTileBuffer; ++ std::unique_ptr m_pTileBuffer; + GThreadPool* lokThreadPool; + + gfloat m_fZoom; +@@ -503,9 +503,8 @@ static gboolean postDocumentLoad(gpointer pData) + // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- +- priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, +- nColumns); ++ priv->m_pTileBuffer = std::unique_ptr(new TileBuffer(priv->m_pDocument, ++ nColumns)); + gtk_widget_set_size_request(GTK_WIDGET(pLOKDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +@@ -634,7 +633,7 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + for (int j = aStart.y; j < aEnd.y; j++) + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +- priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task, priv->lokThreadPool); ++ priv->m_pTileBuffer->setInvalid(i, j, priv->m_fZoom, task, priv->lokThreadPool); + g_object_unref(task); + } + } +@@ -657,7 +656,7 @@ callback (gpointer pData) + setTilesInvalid(pDocView, aRectangle); + } + else +- priv->m_aTileBuffer.resetAllTiles(); ++ priv->m_pTileBuffer->resetAllTiles(); + + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } +@@ -923,7 +922,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + if (bPaint) + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +- Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task, priv->lokThreadPool); ++ Tile& currentTile = priv->m_pTileBuffer->getTile(nRow, nColumn, priv->m_fZoom, task, priv->lokThreadPool); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, + twipToPixel(aTileRectangleTwips.x, priv->m_fZoom), +@@ -1484,10 +1483,10 @@ paintTileInThread (gpointer data) + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); + LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); +- TileBuffer& buffer = priv->m_aTileBuffer; +- int index = pLOEvent->m_nPaintTileX * buffer.m_nWidth + pLOEvent->m_nPaintTileY; +- if (buffer.m_mTiles.find(index) != buffer.m_mTiles.end() && +- buffer.m_mTiles[index].valid) ++ std::unique_ptr& buffer = priv->m_pTileBuffer; ++ int index = pLOEvent->m_nPaintTileX * buffer->m_nWidth + pLOEvent->m_nPaintTileY; ++ if (buffer->m_mTiles.find(index) != buffer->m_mTiles.end() && ++ buffer->m_mTiles[index].valid) + return; + + GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); +@@ -1518,9 +1517,11 @@ paintTileInThread (gpointer data) + pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom)); + + //create a mapping for it +- buffer.m_mTiles[index].setPixbuf(pPixBuf); +- buffer.m_mTiles[index].valid = true; ++ buffer->m_mTiles[index].setPixbuf(pPixBuf); ++ buffer->m_mTiles[index].valid = true; + gdk_threads_add_idle(queueDraw, GTK_WIDGET(pDocView)); ++ ++ g_object_unref(pPixBuf); + } + + +@@ -2129,8 +2130,8 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + // Total number of columns in this document. + guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); + +- priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, +- nColumns); ++ priv->m_pTileBuffer = std::unique_ptr(new TileBuffer(priv->m_pDocument, ++ nColumns)); + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); +@@ -2211,7 +2212,7 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_reset_view(LOKDocView* pDocView) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- priv->m_aTileBuffer.resetAllTiles(); ++ priv->m_pTileBuffer->resetAllTiles(); + priv->m_nLoadProgress = 0.0; + + memset(&priv->m_aVisibleCursor, 0, sizeof(priv->m_aVisibleCursor)); +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 2f4e6cf123c1..811fcc61ef46 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -41,6 +41,11 @@ void Tile::release() + + void Tile::setPixbuf(GdkPixbuf *buffer) + { ++ if (m_pBuffer == buffer) ++ return; ++ g_clear_object(&m_pBuffer); ++ if (buffer != NULL) ++ g_object_ref(buffer); + m_pBuffer = buffer; + } + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 9361a622fb7c..bef1444f9c9c 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -52,7 +52,10 @@ class Tile + { + public: + Tile() : valid(false), m_pBuffer(0) {} +- ~Tile() { } ++ ~Tile() ++ { ++ g_clear_object(&m_pBuffer); ++ } + + /** + Tells if this tile is valid or not. Initialised to 0 (invalid) during +@@ -85,10 +88,11 @@ class TileBuffer + TileBuffer(LibreOfficeKitDocument *document = 0, + int columns = 0) + : m_pLOKDocument(document) +- , m_nWidth(columns) ++ , m_nWidth(columns) + { + GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); + m_DummyTile.setPixbuf(pPixBuf); ++ g_object_unref(pPixBuf); + } + + ~TileBuffer() {} +-- +2.12.0 + diff --git a/SOURCES/0251-android-don-t-use-alpha-VDev-when-painting-tiles-on-.patch b/SOURCES/0251-android-don-t-use-alpha-VDev-when-painting-tiles-on-.patch new file mode 100644 index 0000000..ed10264 --- /dev/null +++ b/SOURCES/0251-android-don-t-use-alpha-VDev-when-painting-tiles-on-.patch @@ -0,0 +1,69 @@ +From 8e257245396ec0f9edde494904a1c7d9835535bd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Toma=C5=BE=20Vajngerl?= +Date: Sat, 31 Oct 2015 13:59:46 +0100 +Subject: [PATCH 251/398] android: don't use alpha VDev when painting tiles on + Android + +Improves tile rendering speed. + +Change-Id: I6a4b87fbc1d9ed284f5c4a781d769eeacd9bc2ca +(cherry picked from commit e0d68da3ff3ae81e35f4e7393fb998a41886831d) +--- + desktop/source/lib/init.cxx | 34 ++++++++++++++++++++++++---------- + 1 file changed, 24 insertions(+), 10 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 6785ae2328d4..98747ea62e3a 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -773,7 +773,30 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + + #if defined(UNX) && !defined(MACOSX) && !defined(ENABLE_HEADLESS) + +-#ifndef IOS ++#if defined(IOS) ++ SystemGraphicsData aData; ++ aData.rCGContext = reinterpret_cast(pBuffer); ++ // the Size argument is irrelevant, I hope ++ ScopedVclPtrInstance pDevice(&aData, Size(1, 1), (sal_uInt16)0); ++ ++ pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, ++ nTilePosX, nTilePosY, nTileWidth, nTileHeight); ++#elif defined(ANDROID) ++ InitSvpForLibreOfficeKit(); ++ ++ ScopedVclPtrInstance< VirtualDevice > pDevice(nullptr, Size(1, 1), (sal_uInt16)32) ; ++ ++ boost::shared_array aBuffer(pBuffer, NoDelete< sal_uInt8 >()); ++ ++ boost::shared_array aAlphaBuffer; ++ ++ pDevice->SetOutputSizePixelScaleOffsetAndBuffer( ++ Size(nCanvasWidth, nCanvasHeight), Fraction(1.0), Point(), ++ aBuffer, aAlphaBuffer, true); ++ ++ pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, ++ nTilePosX, nTilePosY, nTileWidth, nTileHeight); ++#else + InitSvpForLibreOfficeKit(); + + ScopedVclPtrInstance< VirtualDevice > pDevice(nullptr, Size(1, 1), (sal_uInt16)32) ; +@@ -806,15 +829,6 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + pBuffer[nOffset * 4 +3] = 0xff - aAlpha[nOffset]; + } + } +- +-#else +- SystemGraphicsData aData; +- aData.rCGContext = reinterpret_cast(pBuffer); +- // the Size argument is irrelevant, I hope +- ScopedVclPtrInstance pDevice(&aData, Size(1, 1), (sal_uInt16)0); +- +- pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, +- nTilePosX, nTilePosY, nTileWidth, nTileHeight); + #endif + + static bool bDebug = getenv("LOK_DEBUG") != 0; +-- +2.12.0 + diff --git a/SOURCES/0252-add-LOKit-interface-missing-description.patch b/SOURCES/0252-add-LOKit-interface-missing-description.patch new file mode 100644 index 0000000..719d904 --- /dev/null +++ b/SOURCES/0252-add-LOKit-interface-missing-description.patch @@ -0,0 +1,37 @@ +From 21af7ed50479037d9574d5a8061b4ca98065c702 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Toma=C5=BE=20Vajngerl?= +Date: Sun, 1 Nov 2015 22:37:12 +0100 +Subject: [PATCH 252/398] add LOKit interface missing description + +Change-Id: Ia9e33704cfffd2094606e6fd166796bd8cd5d4fe +(cherry picked from commit 3d34594138c42ec4b253a25c403ef9346265a28f) +--- + include/LibreOfficeKit/LibreOfficeKit.hxx | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 0e83a63c3fe5..6673cd731eb7 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -129,8 +129,7 @@ public: + * @param nTileWidth logical width of the rendered rectangle, in TWIPs. + * @param nTileHeight logical height of the rendered rectangle, in TWIPs. + */ +- inline void paintTile( +- unsigned char* pBuffer, ++ inline void paintTile(unsigned char* pBuffer, + const int nCanvasWidth, + const int nCanvasHeight, + const int nTilePosX, +@@ -192,6 +191,8 @@ public: + * @param nX horizontal position in document coordinates + * @param nY vertical position in document coordinates + * @param nCount number of clicks: 1 for single click, 2 for double click ++ * @param nButtons: which mouse buttons: 1 for left, 2 for middle, 4 right ++ * @param nModifier: which keyboard modifier: (see include/rsc/rsc-vcl-shared-types.hxx for possible values) + */ + inline void postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier) + { +-- +2.12.0 + diff --git a/SOURCES/0253-gtktiledviewer-add-a-few-more-trivial-buttons-and-br.patch b/SOURCES/0253-gtktiledviewer-add-a-few-more-trivial-buttons-and-br.patch new file mode 100644 index 0000000..d2ed897 --- /dev/null +++ b/SOURCES/0253-gtktiledviewer-add-a-few-more-trivial-buttons-and-br.patch @@ -0,0 +1,266 @@ +From 9c22806888e899bd9ab7166bad8e0d78a35c1de4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 2 Nov 2015 09:13:28 +0100 +Subject: [PATCH 253/398] gtktiledviewer: add a few more trivial buttons and + break the toolbar into two + +Change-Id: Iea8f32fb8c388b49dad8119f816502f593ebadeb +(cherry picked from commit 96f2e0730bbfd1cdc0bae131cd35b63f97f5268a) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 168 +++++++++++++++------ + 1 file changed, 120 insertions(+), 48 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 1049c288a14b..822a6cb3c4bd 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -88,6 +88,12 @@ public: + GtkToolItem* m_pItalic; + GtkToolItem* m_pUnderline; + GtkToolItem* m_pStrikethrough; ++ GtkToolItem* m_pSuperscript; ++ GtkToolItem* m_pSubscript; ++ GtkToolItem* m_pLeftpara; ++ GtkToolItem* m_pCenterpara; ++ GtkToolItem* m_pRightpara; ++ GtkToolItem* m_pJustifypara; + GtkWidget* m_pScrolledWindow; + std::map m_aToolItemCommandNames; + std::map m_aCommandNameToolItems; +@@ -113,6 +119,12 @@ public: + m_pItalic(0), + m_pUnderline(0), + m_pStrikethrough(0), ++ m_pSuperscript(0), ++ m_pSubscript(0), ++ m_pLeftpara(0), ++ m_pCenterpara(0), ++ m_pRightpara(0), ++ m_pJustifypara(0), + m_pScrolledWindow(0), + m_bToolItemBroadcast(true), + m_pVBox(0), +@@ -845,112 +857,172 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + rWindow.m_pVBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_container_add(GTK_CONTAINER(pWindow), rWindow.m_pVBox); + +- // Toolbar +- GtkWidget* pToolbar = gtk_toolbar_new(); +- gtk_toolbar_set_style(GTK_TOOLBAR(pToolbar), GTK_TOOLBAR_ICONS); ++ // Upper toolbar. ++ GtkWidget* pUpperToolbar = gtk_toolbar_new(); ++ gtk_toolbar_set_style(GTK_TOOLBAR(pUpperToolbar), GTK_TOOLBAR_ICONS); + ++ // Save. ++ GtkToolItem* pSave = gtk_tool_button_new(NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pSave), "document-save-symbolic"); ++ gtk_tool_item_set_tooltip_text(pSave, "Save"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pSave, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), gtk_separator_tool_item_new(), -1); ++ g_signal_connect(G_OBJECT(pSave), "clicked", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, pSave, ".uno:Save"); ++ ++ // Copy and paste. ++ GtkToolItem* pCopyButton = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pCopyButton), "edit-copy-symbolic"); ++ gtk_tool_item_set_tooltip_text(pCopyButton, "Copy"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pCopyButton, -1); ++ g_signal_connect(G_OBJECT(pCopyButton), "clicked", G_CALLBACK(doCopy), NULL); ++ GtkToolItem* pPasteButton = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pPasteButton), "edit-paste-symbolic"); ++ gtk_tool_item_set_tooltip_text(pPasteButton, "Paste"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pPasteButton, -1); ++ g_signal_connect(G_OBJECT(pPasteButton), "clicked", G_CALLBACK(doPaste), NULL); ++ gtk_toolbar_insert( GTK_TOOLBAR(pUpperToolbar), gtk_separator_tool_item_new(), -1); ++ ++ // Undo and redo. ++ GtkToolItem* pUndo = gtk_tool_button_new(NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pUndo), "edit-undo-symbolic"); ++ gtk_tool_item_set_tooltip_text(pUndo, "Undo"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pUndo, -1); ++ g_signal_connect(G_OBJECT(pUndo), "clicked", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, pUndo, ".uno:Undo"); ++ GtkToolItem* pRedo = gtk_tool_button_new(NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pRedo), "edit-redo-symbolic"); ++ gtk_tool_item_set_tooltip_text(pRedo, "Redo"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pRedo, -1); ++ g_signal_connect(G_OBJECT(pRedo), "clicked", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, pRedo, ".uno:Redo"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), gtk_separator_tool_item_new(), -1); ++ ++ // Find. ++ GtkToolItem* pFindButton = gtk_tool_button_new( NULL, NULL); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindButton), "edit-find-symbolic"); ++ gtk_tool_item_set_tooltip_text(pFindButton, "Find"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pFindButton, -1); ++ g_signal_connect(G_OBJECT(pFindButton), "clicked", G_CALLBACK(toggleFindbar), NULL); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), gtk_separator_tool_item_new(), -1); ++ ++ // Misc upper toolbar. + GtkToolItem* pZoomIn = gtk_tool_button_new(NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomIn), "zoom-in-symbolic"); + gtk_tool_item_set_tooltip_text(pZoomIn, "Zoom In"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pZoomIn, 0); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pZoomIn, -1); + g_signal_connect(G_OBJECT(pZoomIn), "clicked", G_CALLBACK(changeZoom), NULL); + + GtkToolItem* pZoom1 = gtk_tool_button_new(NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pZoom1), "zoom-original-symbolic"); + gtk_tool_item_set_tooltip_text(pZoom1, "Normal Size"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pZoom1, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pZoom1, -1); + g_signal_connect(G_OBJECT(pZoom1), "clicked", G_CALLBACK(changeZoom), NULL); + + GtkToolItem* pZoomOut = gtk_tool_button_new(NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomOut), "zoom-out-symbolic"); + gtk_tool_item_set_tooltip_text(pZoomOut, "Zoom Out"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pZoomOut, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pZoomOut, -1); + g_signal_connect(G_OBJECT(pZoomOut), "clicked", G_CALLBACK(changeZoom), NULL); + +- GtkToolItem* pSeparator1 = gtk_separator_tool_item_new(); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pSeparator1, -1); +- + GtkToolItem* pPartSelectorToolItem = gtk_tool_item_new(); + GtkWidget* pComboBox = gtk_combo_box_text_new(); + gtk_container_add(GTK_CONTAINER(pPartSelectorToolItem), pComboBox); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pPartSelectorToolItem, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pPartSelectorToolItem, -1); + + rWindow.m_pPartSelector = GTK_COMBO_BOX_TEXT(pComboBox); + +- GtkToolItem* pSeparator2 = gtk_separator_tool_item_new(); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pSeparator2, -1); +- + GtkToolItem* pPartModeSelectorToolItem = gtk_tool_item_new(); + rWindow.m_pPartModeComboBox = gtk_combo_box_text_new(); + gtk_container_add(GTK_CONTAINER(pPartModeSelectorToolItem), rWindow.m_pPartModeComboBox); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pPartModeSelectorToolItem, -1); +- +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); +- +- // Cut, copy & paste. +- GtkToolItem* pCopyButton = gtk_tool_button_new( NULL, NULL); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pCopyButton), "edit-copy-symbolic"); +- gtk_tool_item_set_tooltip_text(pCopyButton, "Copy"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pCopyButton, -1); +- g_signal_connect(G_OBJECT(pCopyButton), "clicked", G_CALLBACK(doCopy), NULL); +- +- GtkToolItem* pPasteButton = gtk_tool_button_new( NULL, NULL); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pPasteButton), "edit-paste-symbolic"); +- gtk_tool_item_set_tooltip_text(pPasteButton, "Paste"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pPasteButton, -1); +- g_signal_connect(G_OBJECT(pPasteButton), "clicked", G_CALLBACK(doPaste), NULL); +- gtk_toolbar_insert( GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pPartModeSelectorToolItem, -1); + + GtkToolItem* pEnableEditing = gtk_toggle_tool_button_new(); + rWindow.m_pEnableEditing = pEnableEditing; + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pEnableEditing), "insert-text-symbolic"); + gtk_tool_item_set_tooltip_text(pEnableEditing, "Edit"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pEnableEditing, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pEnableEditing, -1); + g_signal_connect(G_OBJECT(pEnableEditing), "toggled", G_CALLBACK(toggleEditing), NULL); + +- GtkToolItem* pFindButton = gtk_tool_button_new( NULL, NULL); +- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindButton), "edit-find-symbolic"); +- gtk_tool_item_set_tooltip_text(pFindButton, "Find"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pFindButton, -1); +- g_signal_connect(G_OBJECT(pFindButton), "clicked", G_CALLBACK(toggleFindbar), NULL); +- + GtkToolItem* pNewViewButton = gtk_tool_button_new( NULL, NULL); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pNewViewButton), "view-continuous-symbolic"); + gtk_tool_item_set_tooltip_text(pNewViewButton, "New View"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), pNewViewButton, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pNewViewButton, -1); + g_signal_connect(G_OBJECT(pNewViewButton), "clicked", G_CALLBACK(createView), NULL); ++ gtk_box_pack_start(GTK_BOX(rWindow.m_pVBox), pUpperToolbar, FALSE, FALSE, 0 ); // Adds to top. + +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), gtk_separator_tool_item_new(), -1); ++ // Lower toolbar. ++ GtkWidget* pLowerToolbar = gtk_toolbar_new(); ++ gtk_toolbar_set_style(GTK_TOOLBAR(pLowerToolbar), GTK_TOOLBAR_ICONS); + ++ // Bold, italic, underline and strikethrough. + rWindow.m_pBold = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pBold), "format-text-bold-symbolic"); + gtk_tool_item_set_tooltip_text(rWindow.m_pBold, "Bold"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pBold, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pBold, -1); + g_signal_connect(G_OBJECT(rWindow.m_pBold), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(rWindow, rWindow.m_pBold, ".uno:Bold"); +- + rWindow.m_pItalic = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (rWindow.m_pItalic), "format-text-italic-symbolic"); + gtk_tool_item_set_tooltip_text(rWindow.m_pItalic, "Italic"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pItalic, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pItalic, -1); + g_signal_connect(G_OBJECT(rWindow.m_pItalic), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(rWindow, rWindow.m_pItalic, ".uno:Italic"); +- + rWindow.m_pUnderline = gtk_toggle_tool_button_new(); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (rWindow.m_pUnderline), "format-text-underline-symbolic"); + gtk_tool_item_set_tooltip_text(rWindow.m_pUnderline, "Underline"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pUnderline, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pUnderline, -1); + g_signal_connect(G_OBJECT(rWindow.m_pUnderline), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(rWindow, rWindow.m_pUnderline, ".uno:Underline"); +- + rWindow.m_pStrikethrough = gtk_toggle_tool_button_new (); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pStrikethrough), "format-text-strikethrough-symbolic"); + gtk_tool_item_set_tooltip_text(rWindow.m_pStrikethrough, "Strikethrough"); +- gtk_toolbar_insert(GTK_TOOLBAR(pToolbar), rWindow.m_pStrikethrough, -1); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pStrikethrough, -1); + g_signal_connect(G_OBJECT(rWindow.m_pStrikethrough), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(rWindow, rWindow.m_pStrikethrough, ".uno:Strikeout"); +- +- gtk_box_pack_start(GTK_BOX(rWindow.m_pVBox), pToolbar, FALSE, FALSE, 0 ); // Adds to top. ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), gtk_separator_tool_item_new(), -1); ++ ++ // Superscript and subscript. ++ rWindow.m_pSuperscript = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pSuperscript), "go-up-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pSuperscript, "Superscript"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pSuperscript, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pSuperscript), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pSuperscript, ".uno:SuperScript"); ++ rWindow.m_pSubscript = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pSubscript), "go-down-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pSubscript, "Subscript"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pSubscript, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pSubscript), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pSubscript, ".uno:SubScript"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), gtk_separator_tool_item_new(), -1); ++ ++ // Align left, center horizontally, align right and justified. ++ rWindow.m_pLeftpara = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pLeftpara), "format-justify-left-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pLeftpara, "Align Left"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pLeftpara, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pLeftpara), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pLeftpara, ".uno:LeftPara"); ++ rWindow.m_pCenterpara = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pCenterpara), "format-justify-center-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pCenterpara, "Center Horizontally"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pCenterpara, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pCenterpara), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pCenterpara, ".uno:CenterPara"); ++ rWindow.m_pRightpara = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pRightpara), "format-justify-right-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pRightpara, "Align Right"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pRightpara, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pRightpara), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pRightpara, ".uno:RightPara"); ++ rWindow.m_pJustifypara = gtk_toggle_tool_button_new(); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(rWindow.m_pJustifypara), "format-justify-fill-symbolic"); ++ gtk_tool_item_set_tooltip_text(rWindow.m_pJustifypara, "Justified"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pJustifypara, -1); ++ g_signal_connect(G_OBJECT(rWindow.m_pJustifypara), "toggled", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, rWindow.m_pJustifypara, ".uno:JustifyPara"); ++ gtk_box_pack_start(GTK_BOX(rWindow.m_pVBox), pLowerToolbar, FALSE, FALSE, 0 ); // Adds to top. + + // Findbar + rWindow.m_pFindbar = gtk_toolbar_new(); +-- +2.12.0 + diff --git a/SOURCES/0254-ScTabView-getRowColumnHeaders-include-info-about-col.patch b/SOURCES/0254-ScTabView-getRowColumnHeaders-include-info-about-col.patch new file mode 100644 index 0000000..b03d96f --- /dev/null +++ b/SOURCES/0254-ScTabView-getRowColumnHeaders-include-info-about-col.patch @@ -0,0 +1,40 @@ +From 48b6afeef26d498f4338170e53306257ef9914d4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 30 Oct 2015 13:57:28 +0100 +Subject: [PATCH 254/398] ScTabView::getRowColumnHeaders: include info about + columns, too + +Change-Id: Id7db9fa9b451dcf2423142b38c2c12b369e16fae +(cherry picked from commit ac47e5758e56ac30d98c1d6386dfad24ac59b1f6) +--- + sc/source/ui/view/tabview.cxx | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index f177bbe704f1..4dccc9b4032a 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2324,8 +2324,20 @@ OUString ScTabView::getRowColumnHeaders() + aRows.push_back(std::make_pair("", aRow)); + } + ++ boost::property_tree::ptree aCols; ++ for (SCCOL nCol = 0; nCol < nEndCol; ++nCol) ++ { ++ boost::property_tree::ptree aCol; ++ sal_uInt16 nSize = pColBar[SC_SPLIT_LEFT]->GetEntrySize(nCol); ++ aCol.put("size", OString::number(nSize).getStr()); ++ OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); ++ aCol.put("text", aText.toUtf8().getStr()); ++ aCols.push_back(std::make_pair("", aCol)); ++ } ++ + boost::property_tree::ptree aTree; + aTree.add_child("rows", aRows); ++ aTree.add_child("columns", aCols); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + return OUString::fromUtf8(aStream.str().c_str()); +-- +2.12.0 + diff --git a/SOURCES/0255-ScTabView-getRowColumnHeaders-emit-info-about-last-f.patch b/SOURCES/0255-ScTabView-getRowColumnHeaders-emit-info-about-last-f.patch new file mode 100644 index 0000000..78132eb --- /dev/null +++ b/SOURCES/0255-ScTabView-getRowColumnHeaders-emit-info-about-last-f.patch @@ -0,0 +1,37 @@ +From d9521709e35a62c5e56d099d49bad5316bc394c4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 30 Oct 2015 16:00:03 +0100 +Subject: [PATCH 255/398] ScTabView::getRowColumnHeaders: emit info about last + formatted row/col + +Change-Id: I6b4f6eacde84433fa3865e62c692a3f97895b887 +(cherry picked from commit 3bdce53c557a1279e7e40d215e34405626bbc628) +--- + sc/source/ui/view/tabview.cxx | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index 4dccc9b4032a..a3718f62cd7e 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2314,7 +2314,7 @@ OUString ScTabView::getRowColumnHeaders() + pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); + + boost::property_tree::ptree aRows; +- for (SCROW nRow = 0; nRow < nEndRow; ++nRow) ++ for (SCROW nRow = 0; nRow <= nEndRow; ++nRow) + { + boost::property_tree::ptree aRow; + sal_uInt16 nSize = pRowBar[SC_SPLIT_BOTTOM]->GetEntrySize(nRow); +@@ -2325,7 +2325,7 @@ OUString ScTabView::getRowColumnHeaders() + } + + boost::property_tree::ptree aCols; +- for (SCCOL nCol = 0; nCol < nEndCol; ++nCol) ++ for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol) + { + boost::property_tree::ptree aCol; + sal_uInt16 nSize = pColBar[SC_SPLIT_LEFT]->GetEntrySize(nCol); +-- +2.12.0 + diff --git a/SOURCES/0256-sc-lok-emit-RowColumnHeader-info-in-twips.patch b/SOURCES/0256-sc-lok-emit-RowColumnHeader-info-in-twips.patch new file mode 100644 index 0000000..4e82cb9 --- /dev/null +++ b/SOURCES/0256-sc-lok-emit-RowColumnHeader-info-in-twips.patch @@ -0,0 +1,99 @@ +From 2cd289ebee6e572804338d87e26d935443c4817b Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 2 Nov 2015 10:56:43 +0100 +Subject: [PATCH 256/398] sc lok: emit RowColumnHeader info in twips + +As that's the unit we use everywhere else in the LOK API. Also, make the +ScGlobal::nScreenPPTX/Y calculation more precise, otherwise rounding +errors occur during the pixel -> twip conversion. + +Example with the old precision: col height is 103 px, nScreenPPTY is +0.067, twips is 1537.3134328358208, convering it back is 102.487562189 +px. + +Example with the new precision: col height is 103 px, nScreenPPTY is +0.0667, twips is 1544.2278860569716, convering it back is 102.948525737 +px. + +Change-Id: I19f5285508ef0c751614d07969b3a7a037e7d1ec +(cherry picked from commit 708d1c5ab242b545ced598879233fc662d7e6cc0) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 6 ++++-- + sc/source/core/data/global.cxx | 6 +++--- + sc/source/ui/view/tabview.cxx | 7 +++++-- + 3 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 822a6cb3c4bd..4e9b9b80ea03 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -250,7 +250,8 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + rWindow.m_pRowBar->m_aHeaders.clear(); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { +- Header aHeader(std::atoi(rValue.second.get("size").c_str()), rValue.second.get("text")); ++ int nSize = std::round(lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str()))); ++ Header aHeader(nSize, rValue.second.get("text")); + rWindow.m_pRowBar->m_aHeaders.push_back(aHeader); + } + gtk_widget_show(rWindow.m_pRowBar->m_pDrawingArea); +@@ -259,7 +260,8 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + rWindow.m_pColumnBar->m_aHeaders.clear(); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns")) + { +- Header aHeader(std::atoi(rValue.second.get("size").c_str()), rValue.second.get("text")); ++ int nSize = std::round(lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str()))); ++ Header aHeader(nSize, rValue.second.get("text")); + rWindow.m_pColumnBar->m_aHeaders.push_back(aHeader); + } + gtk_widget_show(rWindow.m_pColumnBar->m_pDrawingArea); +diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx +index 12b7cbbe6b56..8303770a7850 100644 +--- a/sc/source/core/data/global.cxx ++++ b/sc/source/core/data/global.cxx +@@ -544,9 +544,9 @@ void ScGlobal::UpdatePPT( OutputDevice* pDev ) + + if ( !pDev ) + pDev = Application::GetDefaultDevice(); +- Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP ); +- nScreenPPTX = aPix1000.X() / 1000.0; +- nScreenPPTY = aPix1000.Y() / 1000.0; ++ Point aPix1000 = pDev->LogicToPixel( Point(10000,10000), MAP_TWIP ); ++ nScreenPPTX = aPix1000.X() / 10000.0; ++ nScreenPPTY = aPix1000.Y() / 10000.0; + nPPTZoom = nCurrentZoom; + } + } +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index a3718f62cd7e..f2f6179eaaf9 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2313,12 +2313,15 @@ OUString ScTabView::getRowColumnHeaders() + SCROW nEndRow = 0; + pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); + ++ double nPPTX = aViewData.GetPPTX(); ++ double nPPTY = aViewData.GetPPTY(); ++ + boost::property_tree::ptree aRows; + for (SCROW nRow = 0; nRow <= nEndRow; ++nRow) + { + boost::property_tree::ptree aRow; + sal_uInt16 nSize = pRowBar[SC_SPLIT_BOTTOM]->GetEntrySize(nRow); +- aRow.put("size", OString::number(nSize).getStr()); ++ aRow.put("size", OString::number(nSize / nPPTY).getStr()); + OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); + aRow.put("text", aText.toUtf8().getStr()); + aRows.push_back(std::make_pair("", aRow)); +@@ -2329,7 +2332,7 @@ OUString ScTabView::getRowColumnHeaders() + { + boost::property_tree::ptree aCol; + sal_uInt16 nSize = pColBar[SC_SPLIT_LEFT]->GetEntrySize(nCol); +- aCol.put("size", OString::number(nSize).getStr()); ++ aCol.put("size", OString::number(nSize / nPPTX).getStr()); + OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); + aCol.put("text", aText.toUtf8().getStr()); + aCols.push_back(std::make_pair("", aCol)); +-- +2.12.0 + diff --git a/SOURCES/0257-gtktiledviewer-show-zoom-in-the-status-bar.patch b/SOURCES/0257-gtktiledviewer-show-zoom-in-the-status-bar.patch new file mode 100644 index 0000000..b6927e4 --- /dev/null +++ b/SOURCES/0257-gtktiledviewer-show-zoom-in-the-status-bar.patch @@ -0,0 +1,106 @@ +From 64db75597615c8f528e91203e7a50768a891aab0 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 2 Nov 2015 14:59:07 +0100 +Subject: [PATCH 257/398] gtktiledviewer: show zoom in the status bar + +Change-Id: I4ab00a269b0a8435a278f93e1d92d102a80c8506 +(cherry picked from commit 901fa421e1d446408116d1fe2eb6f070b5946dc9) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 34 +++++++++++++++++----- + 1 file changed, 27 insertions(+), 7 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 4e9b9b80ea03..c6821065d147 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -83,6 +83,9 @@ class TiledWindow + public: + GtkWidget* m_pDocView; + GtkWidget* m_pStatusBar; ++ GtkWidget* m_pProgressBar; ++ GtkWidget* m_pStatusbarLabel; ++ GtkWidget* m_pZoomLabel; + GtkToolItem* m_pEnableEditing; + GtkToolItem* m_pBold; + GtkToolItem* m_pItalic; +@@ -114,6 +117,9 @@ public: + TiledWindow() + : m_pDocView(0), + m_pStatusBar(0), ++ m_pProgressBar(0), ++ m_pStatusbarLabel(0), ++ m_pZoomLabel(0), + m_pEnableEditing(0), + m_pBold(0), + m_pItalic(0), +@@ -373,6 +379,8 @@ static void changeZoom( GtkWidget* pButton, gpointer /* pItem */ ) + lok_doc_view_set_zoom( LOK_DOC_VIEW(pDocView), fZoom ); + } + } ++ std::string aZoom = std::to_string(int(fZoom * 100)) + std::string("%"); ++ gtk_label_set_text(GTK_LABEL(rWindow.m_pZoomLabel), aZoom.c_str()); + } + + /// User clicked on the button -> inform LOKDocView. +@@ -425,8 +433,9 @@ static void createView(GtkWidget* pButton, gpointer /*pItem*/) + GtkWidget* pDocView = lok_doc_view_new_from_widget(LOK_DOC_VIEW(rWindow.m_pDocView)); + + TiledWindow& rNewWindow = setupWidgetAndCreateWindow(pDocView); +- // Hide status bar that contains the unused progress bar. +- gtk_widget_hide(rNewWindow.m_pStatusBar); ++ // Hide the unused progress bar. ++ gtk_widget_show_all(rNewWindow.m_pStatusBar); ++ gtk_widget_hide(rNewWindow.m_pProgressBar); + } + + /// Creates a new model, i.e. LOK init and document load, one view implicitly. +@@ -845,7 +854,8 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo + focusChain = g_list_append( focusChain, pDocView ); + gtk_container_set_focus_chain ( GTK_CONTAINER (rWindow.m_pVBox), focusChain ); + +- gtk_widget_hide(rWindow.m_pStatusBar); ++ gtk_widget_show_all(rWindow.m_pStatusBar); ++ gtk_widget_hide(rWindow.m_pProgressBar); + } + + /// Creates the GtkWindow that has main widget as children and registers it in the window map. +@@ -1085,15 +1095,22 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + + gtk_container_add(GTK_CONTAINER(rWindow.m_pScrolledWindow), rWindow.m_pDocView); + +- GtkWidget* pProgressBar = gtk_progress_bar_new (); +- g_signal_connect(rWindow.m_pDocView, "load-changed", G_CALLBACK(loadChanged), pProgressBar); ++ rWindow.m_pProgressBar = gtk_progress_bar_new (); ++ g_signal_connect(rWindow.m_pDocView, "load-changed", G_CALLBACK(loadChanged), rWindow.m_pProgressBar); + + GtkWidget* pStatusBar = gtk_statusbar_new(); + rWindow.m_pStatusBar = pStatusBar; + gtk_container_forall(GTK_CONTAINER(pStatusBar), removeChildrenFromStatusbar, pStatusBar); + gtk_container_add (GTK_CONTAINER(rWindow.m_pVBox), pStatusBar); +- gtk_container_add (GTK_CONTAINER(pStatusBar), pProgressBar); +- gtk_widget_set_hexpand(pProgressBar, true); ++ gtk_container_add (GTK_CONTAINER(pStatusBar), rWindow.m_pProgressBar); ++ gtk_widget_set_hexpand(rWindow.m_pProgressBar, true); ++ ++ rWindow.m_pStatusbarLabel = gtk_label_new(""); ++ gtk_widget_set_hexpand(rWindow.m_pStatusbarLabel, TRUE); ++ gtk_container_add(GTK_CONTAINER(pStatusBar), rWindow.m_pStatusbarLabel); ++ ++ rWindow.m_pZoomLabel = gtk_label_new("100%"); ++ gtk_container_add(GTK_CONTAINER(pStatusBar), rWindow.m_pZoomLabel); + + gtk_widget_show_all(pWindow); + // Hide the findbar by default. +@@ -1102,6 +1119,9 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_widget_hide(rWindow.m_pCornerButton->m_pDrawingArea); + gtk_widget_hide(rWindow.m_pRowBar->m_pDrawingArea); + gtk_widget_hide(rWindow.m_pColumnBar->m_pDrawingArea); ++ // Hide the non-progressbar children of the status bar by default. ++ gtk_widget_hide(rWindow.m_pStatusbarLabel); ++ gtk_widget_hide(rWindow.m_pZoomLabel); + + g_aWindows[pWindow] = rWindow; + g_signal_connect(rWindow.m_pDocView, "configure-event", G_CALLBACK(TiledRowColumnBar::docConfigureEvent), 0); +-- +2.12.0 + diff --git a/SOURCES/0258-sc-lok-fix-rounding-errors-with-non-100-zoom.patch b/SOURCES/0258-sc-lok-fix-rounding-errors-with-non-100-zoom.patch new file mode 100644 index 0000000..f261bf1 --- /dev/null +++ b/SOURCES/0258-sc-lok-fix-rounding-errors-with-non-100-zoom.patch @@ -0,0 +1,82 @@ +From 9d9749fb86461eefdb2bab01de003409b236dde0 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 2 Nov 2015 15:18:09 +0100 +Subject: [PATCH 258/398] sc lok: fix rounding errors with non-100% zoom + +There were two problems here: + +1) ScTabView::getRowColumnHeaders() did not expose twip values directly, +but used ScRow/ColBar::GetEntrySize(), which does a twip -> pixel +conversion, and then converted it back to twip. Avoid this unnecessary +roundtrip. + +2) ScViewData::ToPixel() trunaces the resulting float to an integer, so +if the result is e.g. 67.7 pixels, then Calc handled that as 67, but +gtktiledviewer rounded that up to 68, resulting in non-matching headers +for the rendered tiles. + +Change-Id: Ie6ed1ea923a423d1526eeb235b7b87106fd2f20b +(cherry picked from commit 861b28b88909ec39fc83fccc0ab23d288128aa0e) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 4 ++-- + sc/source/ui/view/tabview.cxx | 11 ++++------- + 2 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index c6821065d147..7e6379124678 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -256,7 +256,7 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + rWindow.m_pRowBar->m_aHeaders.clear(); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { +- int nSize = std::round(lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str()))); ++ int nSize = lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str())); + Header aHeader(nSize, rValue.second.get("text")); + rWindow.m_pRowBar->m_aHeaders.push_back(aHeader); + } +@@ -266,7 +266,7 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + rWindow.m_pColumnBar->m_aHeaders.clear(); + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns")) + { +- int nSize = std::round(lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str()))); ++ int nSize = lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str())); + Header aHeader(nSize, rValue.second.get("text")); + rWindow.m_pColumnBar->m_aHeaders.push_back(aHeader); + } +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index f2f6179eaaf9..2d886bca6003 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2313,15 +2313,12 @@ OUString ScTabView::getRowColumnHeaders() + SCROW nEndRow = 0; + pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); + +- double nPPTX = aViewData.GetPPTX(); +- double nPPTY = aViewData.GetPPTY(); +- + boost::property_tree::ptree aRows; + for (SCROW nRow = 0; nRow <= nEndRow; ++nRow) + { + boost::property_tree::ptree aRow; +- sal_uInt16 nSize = pRowBar[SC_SPLIT_BOTTOM]->GetEntrySize(nRow); +- aRow.put("size", OString::number(nSize / nPPTY).getStr()); ++ sal_uInt16 nSize = pDoc->GetOriginalHeight(nRow, aViewData.GetTabNo()); ++ aRow.put("size", OString::number(nSize).getStr()); + OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); + aRow.put("text", aText.toUtf8().getStr()); + aRows.push_back(std::make_pair("", aRow)); +@@ -2331,8 +2328,8 @@ OUString ScTabView::getRowColumnHeaders() + for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol) + { + boost::property_tree::ptree aCol; +- sal_uInt16 nSize = pColBar[SC_SPLIT_LEFT]->GetEntrySize(nCol); +- aCol.put("size", OString::number(nSize / nPPTX).getStr()); ++ sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo()); ++ aCol.put("size", OString::number(nSize).getStr()); + OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); + aCol.put("text", aText.toUtf8().getStr()); + aCols.push_back(std::make_pair("", aCol)); +-- +2.12.0 + diff --git a/SOURCES/0259-LOK-make-use-of-MOUSEMOVE-in-calc.patch b/SOURCES/0259-LOK-make-use-of-MOUSEMOVE-in-calc.patch new file mode 100644 index 0000000..870cc46 --- /dev/null +++ b/SOURCES/0259-LOK-make-use-of-MOUSEMOVE-in-calc.patch @@ -0,0 +1,28 @@ +From 2f89f229707b1de749c0c61b112339b3020a305c Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Mon, 2 Nov 2015 16:52:48 +0200 +Subject: [PATCH 259/398] LOK: make use of MOUSEMOVE in calc + +Change-Id: Ideb7bdabd86e95cf10c7f19f0900110b816970c2 +(cherry picked from commit bcd8da6849780b9680963ef3313d14209a46e5fa) +--- + sc/source/ui/unoobj/docuno.cxx | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index f9a9e03f2839..267798d4e949 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -624,6 +624,9 @@ void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButt + pGridWindow->EndTracking(TrackingEventFlags::DontCallHdl); + + break; ++ case LOK_MOUSEEVENT_MOUSEMOVE: ++ pGridWindow->MouseMove(aEvent); ++ break; + default: + assert(false); + break; +-- +2.12.0 + diff --git a/SOURCES/0260-gtktiledviewer-adjust-spreadsheet-row-column-headers.patch b/SOURCES/0260-gtktiledviewer-adjust-spreadsheet-row-column-headers.patch new file mode 100644 index 0000000..ffc19f5 --- /dev/null +++ b/SOURCES/0260-gtktiledviewer-adjust-spreadsheet-row-column-headers.patch @@ -0,0 +1,118 @@ +From 380e289f5d0a7af5df0d0ed7b4a8d940e01a35b1 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 2 Nov 2015 17:03:08 +0100 +Subject: [PATCH 260/398] gtktiledviewer: adjust spreadsheet row/column headers + on scrolling + +Change-Id: I7ed9e19df071b6baf1e941faee24c332c7b5e804 +(cherry picked from commit 7c4733661b0a80098e84413fbc91b84b4c14cfc1) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 43 ++++++++++++++++++++-- + 1 file changed, 39 insertions(+), 4 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 7e6379124678..795fb4ed7ff7 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -57,12 +57,16 @@ public: + std::vector
m_aHeaders; + /// Height for row bar, width for column bar. + int m_nSizePixel; ++ /// Left/top position for the column/row bar -- initially 0, then may grow due to scrolling. ++ int m_nPositionPixel; + TiledBarType m_eType; + + TiledRowColumnBar(TiledBarType eType); + static gboolean draw(GtkWidget* pWidget, cairo_t* pCairo, gpointer pData); + gboolean drawImpl(GtkWidget* pWidget, cairo_t* pCairo); + static gboolean docConfigureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData); ++ /// Adjustments of the doc widget changed -- horizontal or vertical scroll. ++ static void docAdjustmentChanged(GtkAdjustment* pAdjustment, gpointer pData); + /// Draws rText at the center of rRectangle on pCairo. + static void drawText(cairo_t* pCairo, const GdkRectangle& rRectangle, const std::string& rText); + }; +@@ -233,17 +237,26 @@ gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + return FALSE; + } + ++void TiledRowColumnBar::docAdjustmentChanged(GtkAdjustment* /*pAdjustment*/, gpointer pData) ++{ ++ GtkWidget* pDocView = static_cast(pData); ++ docConfigureEvent(pDocView, 0, 0); ++} ++ + gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfigure* /*pEvent*/, gpointer /*pData*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pDocView); + GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); + rWindow.m_pRowBar->m_nSizePixel = gtk_adjustment_get_page_size(pVAdjustment); ++ rWindow.m_pRowBar->m_nPositionPixel = gtk_adjustment_get_value(pVAdjustment); + GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); + rWindow.m_pColumnBar->m_nSizePixel = gtk_adjustment_get_page_size(pHAdjustment); ++ rWindow.m_pColumnBar->m_nPositionPixel = gtk_adjustment_get_value(pHAdjustment); + + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)); + if (pDocument && pDocument->pClass->getDocumentType(pDocument) == LOK_DOCTYPE_SPREADSHEET) + { ++ g_info("lok::Document::getCommandValues(.uno:ViewRowColumnHeaders)"); + char* pValues = pDocument->pClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); + std::stringstream aStream(pValues); + free(pValues); +@@ -254,21 +267,39 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + gtk_widget_show(rWindow.m_pCornerButton->m_pDrawingArea); + + rWindow.m_pRowBar->m_aHeaders.clear(); ++ int nTotal = 0; + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { + int nSize = lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str())); +- Header aHeader(nSize, rValue.second.get("text")); +- rWindow.m_pRowBar->m_aHeaders.push_back(aHeader); ++ int nScrolledSize = nSize; ++ if (nTotal + nSize >= rWindow.m_pRowBar->m_nPositionPixel) ++ { ++ if (nTotal < rWindow.m_pRowBar->m_nPositionPixel) ++ // First visible row: reduce height because the row is only partially visible. ++ nScrolledSize = nTotal + nSize - rWindow.m_pRowBar->m_nPositionPixel; ++ Header aHeader(nScrolledSize, rValue.second.get("text")); ++ rWindow.m_pRowBar->m_aHeaders.push_back(aHeader); ++ } ++ nTotal += nSize; + } + gtk_widget_show(rWindow.m_pRowBar->m_pDrawingArea); + gtk_widget_queue_draw(rWindow.m_pRowBar->m_pDrawingArea); + + rWindow.m_pColumnBar->m_aHeaders.clear(); ++ nTotal = 0; + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns")) + { + int nSize = lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str())); +- Header aHeader(nSize, rValue.second.get("text")); +- rWindow.m_pColumnBar->m_aHeaders.push_back(aHeader); ++ int nScrolledSize = nSize; ++ if (nTotal + nSize >= rWindow.m_pColumnBar->m_nPositionPixel) ++ { ++ if (nTotal < rWindow.m_pColumnBar->m_nPositionPixel) ++ // First visible column: reduce width because the column is only partially visible. ++ nScrolledSize = nTotal + nSize - rWindow.m_pColumnBar->m_nPositionPixel; ++ Header aHeader(nScrolledSize, rValue.second.get("text")); ++ rWindow.m_pColumnBar->m_aHeaders.push_back(aHeader); ++ } ++ nTotal += nSize; + } + gtk_widget_show(rWindow.m_pColumnBar->m_pDrawingArea); + gtk_widget_queue_draw(rWindow.m_pColumnBar->m_pDrawingArea); +@@ -1094,6 +1125,10 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_grid_attach(GTK_GRID(pGrid), rWindow.m_pScrolledWindow, 1, 1, 1, 1); + + gtk_container_add(GTK_CONTAINER(rWindow.m_pScrolledWindow), rWindow.m_pDocView); ++ GtkAdjustment* pHAdjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); ++ g_signal_connect(pHAdjustment, "value-changed", G_CALLBACK(TiledRowColumnBar::docAdjustmentChanged), rWindow.m_pDocView); ++ GtkAdjustment* pVAdjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(rWindow.m_pScrolledWindow)); ++ g_signal_connect(pVAdjustment, "value-changed", G_CALLBACK(TiledRowColumnBar::docAdjustmentChanged), rWindow.m_pDocView); + + rWindow.m_pProgressBar = gtk_progress_bar_new (); + g_signal_connect(rWindow.m_pDocView, "load-changed", G_CALLBACK(loadChanged), rWindow.m_pProgressBar); +-- +2.12.0 + diff --git a/SOURCES/0261-lokdocview-Separate-painting-and-saving-of-tiles.patch b/SOURCES/0261-lokdocview-Separate-painting-and-saving-of-tiles.patch new file mode 100644 index 0000000..dd27ea8 --- /dev/null +++ b/SOURCES/0261-lokdocview-Separate-painting-and-saving-of-tiles.patch @@ -0,0 +1,132 @@ +From a47531dc2f5b90eedb4afb4dd2b3b52fb5a59365 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 1 Nov 2015 13:22:25 +0530 +Subject: [PATCH 261/398] lokdocview: Separate "painting" and "saving" of tiles + +Lets separate the task of painting the tile, and saving the tile +in tile buffer using GAsyncReadyCallback. This will provide us +with better control over tiles -- cancelling the painting operation, +and filtering tiles that should not be saved in the tile buffer. + +Change-Id: I6aae928d8cc0c906034570ed0e9a054763d493a3 +Reviewed-on: https://gerrit.libreoffice.org/19725 +Reviewed-by: Miklos Vajna +Tested-by: Miklos Vajna +(cherry picked from commit de0c7e1783edc6a36037f2657f823dc9812c0804) +--- + libreofficekit/source/gtk/lokdocview.cxx | 56 ++++++++++++++++++++++++++++---- + libreofficekit/source/gtk/tilebuffer.cxx | 10 ------ + 2 files changed, 49 insertions(+), 17 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 2ec27305af4e..867c0d165448 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -873,6 +873,47 @@ renderGraphicHandle(LOKDocView* pDocView, + } + } + ++/// Finishes the paint tile operation and returns the result, if any ++static gpointer ++paintTileFinish(LOKDocView* pDocView, GAsyncResult* res, GError **error) ++{ ++ GTask* task = G_TASK(res); ++ ++ g_return_val_if_fail(LOK_IS_DOC_VIEW(pDocView), NULL); ++ g_return_val_if_fail(g_task_is_valid(res, pDocView), NULL); ++ g_return_val_if_fail(error == NULL || *error == NULL, NULL); ++ ++ return g_task_propagate_pointer(task, error); ++} ++ ++/// Callback called in the main UI thread when paintTileInThread in LOK thread has finished ++static void ++paintTileCallback(GObject* sourceObject, GAsyncResult* res, gpointer userData) ++{ ++ LOKDocView* pDocView = LOK_DOC_VIEW(sourceObject); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ LOEvent* pLOEvent = static_cast(userData); ++ std::unique_ptr& buffer = priv->m_pTileBuffer; ++ int index = pLOEvent->m_nPaintTileX * buffer->m_nWidth + pLOEvent->m_nPaintTileY; ++ GError* error; ++ ++ error = NULL; ++ GdkPixbuf* pPixBuf = static_cast(paintTileFinish(pDocView, res, &error)); ++ if (error != NULL) ++ { ++ g_warning("Unable to get painted GdkPixbuf: %s", error->message); ++ g_error_free(error); ++ return; ++ } ++ ++ buffer->m_mTiles[index].setPixbuf(pPixBuf); ++ buffer->m_mTiles[index].valid = true; ++ gdk_threads_add_idle(queueDraw, GTK_WIDGET(pDocView)); ++ ++ g_object_unref(pPixBuf); ++} ++ ++ + static gboolean + renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + { +@@ -921,7 +962,13 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + + if (bPaint) + { +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE); ++ pLOEvent->m_nPaintTileX = nRow; ++ pLOEvent->m_nPaintTileY = nColumn; ++ pLOEvent->m_fPaintTileZoom = priv->m_fZoom; ++ GTask* task = g_task_new(pDocView, NULL, paintTileCallback, pLOEvent); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); ++ + Tile& currentTile = priv->m_pTileBuffer->getTile(nRow, nColumn, priv->m_fZoom, task, priv->lokThreadPool); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, +@@ -1516,12 +1563,7 @@ paintTileInThread (gpointer data) + pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom), + pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom)); + +- //create a mapping for it +- buffer->m_mTiles[index].setPixbuf(pPixBuf); +- buffer->m_mTiles[index].valid = true; +- gdk_threads_add_idle(queueDraw, GTK_WIDGET(pDocView)); +- +- g_object_unref(pPixBuf); ++ g_task_return_pointer(task, pPixBuf, g_object_unref); + } + + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 811fcc61ef46..6c9847674e53 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -93,11 +93,6 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + + if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid) + { +- LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE); +- pLOEvent->m_nPaintTileX = x; +- pLOEvent->m_nPaintTileY = y; +- pLOEvent->m_fPaintTileZoom = fZoom; +- g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); + if (error != NULL) + { +@@ -108,11 +103,6 @@ Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, + } + else if(m_mTiles.find(index) == m_mTiles.end()) + { +- LOEvent* pLOEvent = new LOEvent(LOK_PAINT_TILE); +- pLOEvent->m_nPaintTileX = x; +- pLOEvent->m_nPaintTileY = y; +- pLOEvent->m_fPaintTileZoom = fZoom; +- g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); + if (error != NULL) + { +-- +2.12.0 + diff --git a/SOURCES/0262-libreofficekit-Werror-unused-parameter.patch b/SOURCES/0262-libreofficekit-Werror-unused-parameter.patch new file mode 100644 index 0000000..1f7cb9d --- /dev/null +++ b/SOURCES/0262-libreofficekit-Werror-unused-parameter.patch @@ -0,0 +1,63 @@ +From a56ef7d60e8ee96204700a0b6c1474ed2d1560ad Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 3 Nov 2015 11:19:03 +0100 +Subject: [PATCH 262/398] libreofficekit: -Werror=unused-parameter + +Change-Id: I89c4d9752ef650d516bed8fcdc5873de8ae87e18 +(cherry picked from commit 602c1b4e2922c6a0ce425f398983ef64e595b606) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + libreofficekit/source/gtk/tilebuffer.cxx | 2 +- + libreofficekit/source/gtk/tilebuffer.hxx | 3 +-- + 3 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 867c0d165448..d570bbd1393b 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -969,7 +969,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + GTask* task = g_task_new(pDocView, NULL, paintTileCallback, pLOEvent); + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +- Tile& currentTile = priv->m_pTileBuffer->getTile(nRow, nColumn, priv->m_fZoom, task, priv->lokThreadPool); ++ Tile& currentTile = priv->m_pTileBuffer->getTile(nRow, nColumn, task, priv->lokThreadPool); + GdkPixbuf* pPixBuf = currentTile.getBuffer(); + gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, + twipToPixel(aTileRectangleTwips.x, priv->m_fZoom), +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 6c9847674e53..1158209b2273 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -85,7 +85,7 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, + } + } + +-Tile& TileBuffer::getTile(int x, int y, float fZoom, GTask* task, ++Tile& TileBuffer::getTile(int x, int y, GTask* task, + GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index bef1444f9c9c..5e1ea1a27049 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -107,7 +107,6 @@ class TileBuffer + + @param x the tile along the x-axis of the buffer + @param y the tile along the y-axis of the buffer +- @param aZoom current zoom factor of the document + @param task GTask object containing the necessary data + @param pool GThreadPool managed by the widget instance used for all the + LOK calls made by widget. It is needed here because getTile invokes one +@@ -115,7 +114,7 @@ class TileBuffer + + @return the tile at the mentioned position (x, y) + */ +- Tile& getTile(int x, int y, float aZoom, GTask* task, GThreadPool* pool); ++ Tile& getTile(int x, int y, GTask* task, GThreadPool* pool); + /// Destroys all the tiles in the tile buffer; also frees the memory allocated + /// for all the Tile objects. + void resetAllTiles(); +-- +2.12.0 + diff --git a/SOURCES/0263-lok-Fix-typo-search-result_count-search-result-count.patch b/SOURCES/0263-lok-Fix-typo-search-result_count-search-result-count.patch new file mode 100644 index 0000000..4acbfdf --- /dev/null +++ b/SOURCES/0263-lok-Fix-typo-search-result_count-search-result-count.patch @@ -0,0 +1,28 @@ +From df79516e23a605a493d9e90de9ab7a6ccefefec4 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 3 Nov 2015 12:58:48 +0100 +Subject: [PATCH 263/398] lok: Fix typo search-result_count -> + search-result-count. + +Change-Id: Iccd5b39f6bdf1c7a43131fc50186ea5a2838d77e +(cherry picked from commit c0f37892a24b202c0a28836ed1046c90c7631e03) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d570bbd1393b..49d5ecc54f65 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2083,7 +2083,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * @aCommand: number of matches. + */ + doc_view_signals[SEARCH_RESULT_COUNT] = +- g_signal_new("search-result_count", ++ g_signal_new("search-result-count", + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +-- +2.12.0 + diff --git a/SOURCES/0264-lok-Introduce-LOK_CALLBACK_UNO_COMMAND_RESULT-callba.patch b/SOURCES/0264-lok-Introduce-LOK_CALLBACK_UNO_COMMAND_RESULT-callba.patch new file mode 100644 index 0000000..5207104 --- /dev/null +++ b/SOURCES/0264-lok-Introduce-LOK_CALLBACK_UNO_COMMAND_RESULT-callba.patch @@ -0,0 +1,466 @@ +From 1c5b0b2f4a2e883f5da3a4afb3cadaf695d58fac Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 3 Nov 2015 13:20:06 +0100 +Subject: [PATCH 264/398] lok: Introduce LOK_CALLBACK_UNO_COMMAND_RESULT + callback. + +Posting of the .uno:Something commands is asynchronous. To be able to find +out when eg. .uno:Save finished, this commit introduces a callback that fires +when that happens. + +To be able to receive such a notification, the appropriate postUnoCommand() +must be called with 'true' as the parameter for bNotifyWhenFinished (defaults +to 'false'). + +Change-Id: I254939ebc8ea5f309ae39686dcaaeddd5148b0c9 +(cherry picked from commit 8c987fababbddb6e4f81b0cd717b59b9a9ff9be0) +--- + comphelper/source/misc/dispatchcommand.cxx | 9 ++- + desktop/inc/lib/init.hxx | 2 + + desktop/source/lib/init.cxx | 74 ++++++++++++++++++++-- + include/LibreOfficeKit/LibreOfficeKit.h | 8 ++- + include/LibreOfficeKit/LibreOfficeKit.hxx | 4 +- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 17 ++++- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 4 +- + include/comphelper/dispatchcommand.hxx | 5 +- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 15 ++++- + libreofficekit/source/gtk/lokdocview.cxx | 34 +++++++++- + libreofficekit/source/gtk/tilebuffer.hxx | 2 + + 11 files changed, 157 insertions(+), 17 deletions(-) + +diff --git a/comphelper/source/misc/dispatchcommand.cxx b/comphelper/source/misc/dispatchcommand.cxx +index 5de05542dbb4..a5a6dde0885d 100644 +--- a/comphelper/source/misc/dispatchcommand.cxx ++++ b/comphelper/source/misc/dispatchcommand.cxx +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -30,7 +31,7 @@ using namespace css; + + namespace comphelper { + +-bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence& rArguments) ++bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence& rArguments, uno::Reference aListener) + { + // Target where we will execute the .uno: command + uno::Reference xContext = ::comphelper::getProcessComponentContext(); +@@ -54,7 +55,11 @@ bool dispatchCommand(const OUString& rCommand, const css::uno::Sequencedispatch(aCommandURL, rArguments); ++ uno::Reference xNotifyingDisp(xDisp, uno::UNO_QUERY); ++ if (xNotifyingDisp.is()) ++ xNotifyingDisp->dispatchWithNotification(aCommandURL, rArguments, aListener); ++ else ++ xNotifyingDisp->dispatch(aCommandURL, rArguments); + + return true; + } +diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx +index d3a42fb10bde..4f878d26c007 100644 +--- a/desktop/inc/lib/init.hxx ++++ b/desktop/inc/lib/init.hxx +@@ -20,6 +20,8 @@ namespace desktop { + { + uno::Reference mxComponent; + std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; ++ LibreOfficeKitCallback mpCallback; ++ void *mpCallbackData; + + explicit LibLODocument_Impl(const uno::Reference &xComponent); + ~LibLODocument_Impl(); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 98747ea62e3a..9ba26c414d8c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -35,6 +35,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -240,7 +242,8 @@ static void doc_postMouseEvent (LibreOfficeKitDocument* pThis, + int nModifier); + static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, + const char* pCommand, +- const char* pArguments); ++ const char* pArguments, ++ bool bNotifyWhenFinished); + static void doc_setTextSelection (LibreOfficeKitDocument* pThis, + int nType, + int nX, +@@ -883,9 +886,14 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis) + } + + static void doc_registerCallback(LibreOfficeKitDocument* pThis, +- LibreOfficeKitCallback pCallback, +- void* pData) ++ LibreOfficeKitCallback pCallback, ++ void* pData) + { ++ LibLODocument_Impl* pDocument = static_cast(pThis); ++ ++ pDocument->mpCallback = pCallback; ++ pDocument->mpCallbackData = pData; ++ + if (comphelper::LibreOfficeKit::isViewCallback()) + { + if (SfxViewShell* pViewShell = SfxViewFrame::Current()->GetViewShell()) +@@ -950,13 +958,69 @@ static void jsonToPropertyValues(const char* pJSON, uno::Sequence ++{ ++ OString maCommand; ///< Command for which this is the result. ++ LibreOfficeKitCallback mpCallback; ///< Callback to call. ++ void* mpCallbackData; ///< The callback's data. ++ ++public: ++ DispatchResultListener(const char* pCommand, LibreOfficeKitCallback pCallback, void* pCallbackData) ++ : maCommand(pCommand) ++ , mpCallback(pCallback) ++ , mpCallbackData(pCallbackData) ++ { ++ assert(mpCallback); ++ } ++ ++ virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& rEvent) throw(css::uno::RuntimeException, std::exception) override ++ { ++ boost::property_tree::ptree aTree; ++ aTree.put("commandName", maCommand.getStr()); ++ ++ if (rEvent.State != frame::DispatchResultState::DONTKNOW) ++ { ++ bool bSuccess = (rEvent.State == frame::DispatchResultState::SUCCESS); ++ aTree.put("success", bSuccess); ++ } ++ ++ // TODO UNO Any rEvent.Result -> JSON ++ // aTree.put("result": "..."); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ mpCallback(LOK_CALLBACK_UNO_COMMAND_RESULT, strdup(aStream.str().c_str()), mpCallbackData); ++ } ++ ++ virtual void SAL_CALL disposing(const css::lang::EventObject&) throw (css::uno::RuntimeException, std::exception) override {} ++}; ++ ++static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pCommand, const char* pArguments, bool bNotifyWhenFinished) + { + OUString aCommand(pCommand, strlen(pCommand), RTL_TEXTENCODING_UTF8); + + uno::Sequence aPropertyValues; + jsonToPropertyValues(pArguments, aPropertyValues); +- if (!comphelper::dispatchCommand(aCommand, aPropertyValues)) ++ bool bResult = false; ++ ++ LibLODocument_Impl* pDocument = static_cast(pThis); ++ ++ if (bNotifyWhenFinished && pDocument->mpCallback) ++ { ++ bResult = comphelper::dispatchCommand(aCommand, aPropertyValues, ++ new DispatchResultListener(pCommand, pDocument->mpCallback, pDocument->mpCallbackData)); ++ } ++ else ++ bResult = comphelper::dispatchCommand(aCommand, aPropertyValues); ++ ++ if (!bResult) + { + gImpl->maLastExceptionMsg = "Failed to dispatch the .uno: command"; + } +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index d83717b4a809..c887f5f64b8a 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -12,6 +12,11 @@ + + #include + ++#ifdef LOK_USE_UNSTABLE_API ++// the unstable API needs C99's bool ++#include ++#endif ++ + #include + + #ifdef __cplusplus +@@ -144,7 +149,8 @@ struct _LibreOfficeKitDocumentClass + /// @see lok::Document::postUnoCommand + void (*postUnoCommand) (LibreOfficeKitDocument* pThis, + const char* pCommand, +- const char* pArguments); ++ const char* pArguments, ++ bool bNotifyWhenFinished); + + /// @see lok::Document::setTextSelection + void (*setTextSelection) (LibreOfficeKitDocument* pThis, +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 6673cd731eb7..c51339fa3ba8 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -220,9 +220,9 @@ public: + * @param pCommand uno command to be posted to the document, like ".uno:Bold" + * @param pArguments arguments of the uno command. + */ +- inline void postUnoCommand(const char* pCommand, const char* pArguments = 0) ++ inline void postUnoCommand(const char* pCommand, const char* pArguments = 0, bool bNotifyWhenFinished = false) + { +- mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments); ++ mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments, bNotifyWhenFinished); + } + + /** +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 459da5d196f4..86d9e6bfd873 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -180,7 +180,22 @@ typedef enum + * - searchResultSelection is an array of part-number and rectangle list + * pairs, in LOK_CALLBACK_SET_PART / LOK_CALLBACK_TEXT_SELECTION format. + */ +- LOK_CALLBACK_SEARCH_RESULT_SELECTION ++ LOK_CALLBACK_SEARCH_RESULT_SELECTION, ++ ++ /** ++ * Result of the UNO command execution when bNotifyWhenFinished was set ++ * to 'true' during the postUnoCommand() call. ++ * ++ * The result returns a success / failure state, and potentially ++ * additional data: ++ * ++ * { ++ * "commandName": "...", // the command for which this is the result ++ * "success": true/false, // when the result is "don't know", this is missing ++ * // TODO "result": "..." // UNO Any converted to JSON (not implemented yet) ++ * } ++ */ ++ LOK_CALLBACK_UNO_COMMAND_RESULT + } + LibreOfficeKitCallbackType; + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 81f42105d374..32cb66963220 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -184,12 +184,14 @@ gboolean lok_doc_view_get_edit (LOKDocView* + * @pDocView: the #LOKDocView instance + * @pCommand: the command to issue to LO core + * @pArguments: the arguments to the given command ++ * @bNotifyWhenFinished: normally false, but it may be useful for eg. .uno:Save + * + * Posts the .uno: command to the LibreOfficeKit. + */ + void lok_doc_view_post_command (LOKDocView* pDocView, + const gchar* pCommand, +- const gchar* pArguments); ++ const gchar* pArguments, ++ gboolean bNotifyWhenFinished); + + /** + * lok_doc_view_pixel_to_twip: +diff --git a/include/comphelper/dispatchcommand.hxx b/include/comphelper/dispatchcommand.hxx +index 58aa0b940f4e..7b76bd5a0310 100644 +--- a/include/comphelper/dispatchcommand.hxx ++++ b/include/comphelper/dispatchcommand.hxx +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + + namespace comphelper + { +@@ -24,7 +25,9 @@ namespace comphelper + + @return true on success. + */ +-COMPHELPER_DLLPUBLIC bool dispatchCommand(const OUString& rCommand, const css::uno::Sequence& rArguments); ++COMPHELPER_DLLPUBLIC bool dispatchCommand(const OUString& rCommand, ++ const css::uno::Sequence& rArguments, ++ css::uno::Reference aListener = css::uno::Reference()); + + } + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 795fb4ed7ff7..96a69fcf64f8 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -595,7 +595,7 @@ static void doSearch(GtkWidget* pButton, bool bBackwards) + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); + +- lok_doc_view_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str()); ++ lok_doc_view_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str(), false); + } + + /// Click handler for the search next button. +@@ -671,6 +671,12 @@ static void signalCommand(LOKDocView* pLOKDocView, char* pPayload, gpointer /*pD + } + } + ++/// LOKDocView command finished -> just write it to the console, not that useful for the viewer. ++static void signalCommandResult(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer /*pData*/) ++{ ++ fprintf(stderr, "Command finished: %s\n", pPayload); ++} ++ + static void loadChanged(LOKDocView* /*pLOKDocView*/, gdouble fValue, gpointer pData) + { + GtkWidget* pProgressBar = GTK_WIDGET (pData); +@@ -773,7 +779,11 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + GtkToolItem* pItem = GTK_TOOL_ITEM(pWidget); + const std::string& rString = rWindow.m_aToolItemCommandNames[pItem]; + g_info("toggleToolItem: lok_doc_view_post_command('%s')", rString.c_str()); +- lok_doc_view_post_command(pLOKDocView, rString.c_str(), 0); ++ ++ // notify about the finished Save ++ gboolean bNotify = (rString == ".uno:Save"); ++ ++ lok_doc_view_post_command(pLOKDocView, rString.c_str(), 0, bNotify); + } + } + +@@ -1171,6 +1181,7 @@ static void setupDocView(GtkWidget* pDocView) + #endif + g_signal_connect(pDocView, "edit-changed", G_CALLBACK(signalEdit), NULL); + g_signal_connect(pDocView, "command-changed", G_CALLBACK(signalCommand), NULL); ++ g_signal_connect(pDocView, "command-result", G_CALLBACK(signalCommandResult), NULL); + g_signal_connect(pDocView, "search-not-found", G_CALLBACK(signalSearch), NULL); + g_signal_connect(pDocView, "search-result-count", G_CALLBACK(signalSearchResultCount), NULL); + g_signal_connect(pDocView, "part-changed", G_CALLBACK(signalPart), NULL); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 49d5ecc54f65..bcb1d136b749 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -180,6 +180,7 @@ enum + HYPERLINK_CLICKED, + CURSOR_CHANGED, + SEARCH_RESULT_COUNT, ++ COMMAND_RESULT, + + LAST_SIGNAL + }; +@@ -461,6 +462,11 @@ static void searchResultCount(LOKDocView* pDocView, const std::string& rString) + g_signal_emit(pDocView, doc_view_signals[SEARCH_RESULT_COUNT], 0, rString.c_str()); + } + ++static void commandResult(LOKDocView* pDocView, const std::string& rString) ++{ ++ g_signal_emit(pDocView, doc_view_signals[COMMAND_RESULT], 0, rString.c_str()); ++} ++ + static void + setPart(LOKDocView* pDocView, const std::string& rString) + { +@@ -752,6 +758,11 @@ callback (gpointer pData) + searchResultCount(pDocView, std::to_string(nCount)); + } + break; ++ case LOK_CALLBACK_UNO_COMMAND_RESULT: ++ { ++ commandResult(pDocView, pCallback->m_aPayload); ++ } ++ break; + default: + g_assert(false); + break; +@@ -1520,7 +1531,7 @@ postCommandInThread (gpointer data) + std::stringstream ss; + ss << "lok::Document::postUnoCommand(" << pLOEvent->m_pCommand << ", " << pLOEvent->m_pArguments << ")"; + g_info(ss.str().c_str()); +- priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments); ++ priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments, pLOEvent->m_bNotifyWhenFinished); + } + + static void +@@ -2077,6 +2088,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_NONE, 4, + G_TYPE_INT, G_TYPE_INT, + G_TYPE_INT, G_TYPE_INT); ++ + /** + * LOKDocView::search-result-count: + * @pDocView: the #LOKDocView on which the signal is emitted +@@ -2092,6 +2104,22 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_NONE, 1, + G_TYPE_STRING); + ++ /** ++ * LOKDocView::command-result: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aCommand: JSON containing the info about the command that finished, ++ * and its success status. ++ */ ++ doc_view_signals[COMMAND_RESULT] = ++ g_signal_new("command-result", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, NULL, ++ g_cclosure_marshal_VOID__STRING, ++ G_TYPE_NONE, 1, ++ G_TYPE_STRING); ++ + } + + SAL_DLLPUBLIC_EXPORT GtkWidget* +@@ -2326,7 +2354,8 @@ lok_doc_view_get_edit (LOKDocView* pDocView) + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_post_command (LOKDocView* pDocView, + const gchar* pCommand, +- const gchar* pArguments) ++ const gchar* pArguments, ++ gboolean bNotifyWhenFinished) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +@@ -2334,6 +2363,7 @@ lok_doc_view_post_command (LOKDocView* pDocView, + GError* error = NULL; + pLOEvent->m_pCommand = pCommand; + pLOEvent->m_pArguments = g_strdup(pArguments); ++ pLOEvent->m_bNotifyWhenFinished = bNotifyWhenFinished; + + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 5e1ea1a27049..8a8569eeb306 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -171,6 +171,7 @@ struct LOEvent + ///@{ + const gchar* m_pCommand; + gchar* m_pArguments; ++ gboolean m_bNotifyWhenFinished; + ///@} + + /// @name open_document parameter +@@ -223,6 +224,7 @@ struct LOEvent + : m_nType(type) + , m_pCommand(0) + , m_pArguments(0) ++ , m_bNotifyWhenFinished(false) + , m_pPath(0) + , m_bEdit(false) + , m_nPartMode(0) +-- +2.12.0 + diff --git a/SOURCES/0265-build-fix.patch b/SOURCES/0265-build-fix.patch new file mode 100644 index 0000000..fe6fa5b --- /dev/null +++ b/SOURCES/0265-build-fix.patch @@ -0,0 +1,27 @@ +From adee960bb03e45e26fffae2ccc36dad3eaa4d72b Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 3 Nov 2015 14:20:01 +0100 +Subject: [PATCH 265/398] build fix? + +Change-Id: Icb48acfdba90b95ae55d2f4b9f05871dc3a8732b +(cherry picked from commit dc586816a94f8deba2b6f8868f3aeb3ba0f6be51) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index d4135b66d1d8..c14261e82db6 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -333,7 +333,7 @@ void DesktopLOKTest::testPasteWriter() + + CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", aText.getStr(), aText.getLength())); + +- pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", 0); ++ pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", 0, false); + char* pText = pDocument->pClass->getTextSelection(pDocument, "text/plain;charset=utf-8", 0); + CPPUNIT_ASSERT_EQUAL(OString("hello"), OString(pText)); + free(pText); +-- +2.12.0 + diff --git a/SOURCES/0266-sc-lok-allow-requesting-row-headers-only-for-a-logic.patch b/SOURCES/0266-sc-lok-allow-requesting-row-headers-only-for-a-logic.patch new file mode 100644 index 0000000..439ef52 --- /dev/null +++ b/SOURCES/0266-sc-lok-allow-requesting-row-headers-only-for-a-logic.patch @@ -0,0 +1,249 @@ +From b9bafd8ec0d8725350c4f00bcb9e60d2b06b976c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 3 Nov 2015 15:05:37 +0100 +Subject: [PATCH 266/398] sc lok: allow requesting row headers only for a logic + area + +So that for large documents it's not needed to query all of them on +load, but (similar to tiled rendering itself) it's possible to query the +data that affects the visible area. + +One catch is that the row sizes are relative, so there is a placeholder +row in case the visible area is not the top left corner, and +constructing its size needs special care. Normally the handed out twip +values have to be floored after twip->px conversion, but this one is +already rounded (as the total is a sum of px values, again becase of the +previous floor rule), so need to play the +0.5 trick to allow clients +always just flooring the logic conversion result they get. + +Change-Id: I64a155582acdee7b2acc741d77a2c462409b91a8 +(cherry picked from commit 75303695eb4bfe6c8fdea2cad0d3ed3f912f95c9) +--- + desktop/source/lib/init.cxx | 45 +++++++++++++++++++++- + include/vcl/ITiledRenderable.hxx | 5 ++- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 12 +++++- + sc/inc/docuno.hxx | 2 +- + sc/source/ui/inc/tabview.hxx | 2 +- + sc/source/ui/unoobj/docuno.cxx | 4 +- + sc/source/ui/view/tabview.cxx | 36 ++++++++++++++--- + 7 files changed, 92 insertions(+), 14 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 9ba26c414d8c..b9aeedd5e21c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1204,6 +1204,9 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + + static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand) + { ++ OString aCommand(pCommand); ++ static const OString aViewRowColumnHeaders(".uno:ViewRowColumnHeaders"); ++ + if (!strcmp(pCommand, ".uno:CharFontName")) + { + return getFonts(pCommand); +@@ -1212,7 +1215,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + { + return getStyles(pThis, pCommand); + } +- else if (OString(pCommand) == ".uno:ViewRowColumnHeaders") ++ else if (aCommand.startsWith(aViewRowColumnHeaders)) + { + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) +@@ -1221,7 +1224,45 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + return 0; + } + +- OUString aHeaders = pDoc->getRowColumnHeaders(); ++ Rectangle aRectangle; ++ if (aCommand.getLength() > aViewRowColumnHeaders.getLength()) ++ { ++ // Command has parameters. ++ int nX = 0; ++ int nY = 0; ++ int nWidth = 0; ++ int nHeight = 0; ++ OString aArguments = aCommand.copy(aViewRowColumnHeaders.getLength() + 1); ++ sal_Int32 nParamIndex = 0; ++ do ++ { ++ OString aParamToken = aArguments.getToken(0, '&', nParamIndex); ++ sal_Int32 nIndex = 0; ++ OString aKey; ++ OString aValue; ++ do ++ { ++ OString aToken = aParamToken.getToken(0, '=', nIndex); ++ if (!aKey.getLength()) ++ aKey = aToken; ++ else ++ aValue = aToken; ++ } ++ while (nIndex >= 0); ++ if (aKey == "x") ++ nX = aValue.toInt32(); ++ else if (aKey == "y") ++ nY = aValue.toInt32(); ++ else if (aKey == "width") ++ nWidth = aValue.toInt32(); ++ else if (aKey == "height") ++ nHeight = aValue.toInt32(); ++ } ++ while (nParamIndex >= 0); ++ aRectangle = Rectangle(nX, nY, nX + nWidth, nY + nHeight); ++ } ++ ++ OUString aHeaders = pDoc->getRowColumnHeaders(aRectangle); + OString aString = OUStringToOString(aHeaders, RTL_TEXTENCODING_UTF8); + char* pMemory = static_cast(malloc(aString.getLength() + 1)); + strcpy(pMemory, aString.getStr()); +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 48a13ffc1275..efa9bc272b40 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -150,8 +150,11 @@ public: + + /** + * Get position and content of row/column headers of Calc documents. ++ * ++ * @param rRectangle - if not empty, then limit the output only to the area of this rectangle ++ * @return a JSON describing position/content of rows/columns + */ +- virtual OUString getRowColumnHeaders() ++ virtual OUString getRowColumnHeaders(const Rectangle& /*rRectangle*/) + { + return OUString(); + } +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 96a69fcf64f8..953eeb0f1db2 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -256,8 +256,16 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView)); + if (pDocument && pDocument->pClass->getDocumentType(pDocument) == LOK_DOCTYPE_SPREADSHEET) + { +- g_info("lok::Document::getCommandValues(.uno:ViewRowColumnHeaders)"); +- char* pValues = pDocument->pClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); ++ std::stringstream aCommand; ++ aCommand << ".uno:ViewRowColumnHeaders"; ++ aCommand << "?x=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pColumnBar->m_nPositionPixel)); ++ aCommand << "&width=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pColumnBar->m_nSizePixel)); ++ aCommand << "&y=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pRowBar->m_nPositionPixel)); ++ aCommand << "&height=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pRowBar->m_nSizePixel)); ++ std::stringstream ss; ++ ss << "lok::Document::getCommandValues(" << aCommand.str() << ")"; ++ g_info(ss.str().c_str()); ++ char* pValues = pDocument->pClass->getCommandValues(pDocument, aCommand.str().c_str()); + std::stringstream aStream(pValues); + free(pValues); + assert(!aStream.str().empty()); +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index b4711c54c883..828fc1af7ea0 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -423,7 +423,7 @@ public: + virtual bool isMimeTypeSupported() override; + + /// @see vcl::ITiledRenderable::getRowColumnHeaders(). +- virtual OUString getRowColumnHeaders() override; ++ virtual OUString getRowColumnHeaders(const Rectangle& rRectangle) override; + }; + + class ScDrawPagesObj : public cppu::WeakImplHelper2< +diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx +index 5b0852041108..548742c6c22b 100644 +--- a/sc/source/ui/inc/tabview.hxx ++++ b/sc/source/ui/inc/tabview.hxx +@@ -521,7 +521,7 @@ public: + void ResetAutoSpell(); + void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector* pRanges ); + /// @see ScModelObj::getRowColumnHeaders(). +- OUString getRowColumnHeaders(); ++ OUString getRowColumnHeaders(const Rectangle& rRectangle); + }; + + #endif +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index 267798d4e949..1316fd73d328 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -873,7 +873,7 @@ bool ScModelObj::isMimeTypeSupported() + return EditEngine::HasValidData(aDataHelper.GetTransferable()); + } + +-OUString ScModelObj::getRowColumnHeaders() ++OUString ScModelObj::getRowColumnHeaders(const Rectangle& rRectangle) + { + ScViewData* pViewData = ScDocShell::GetViewData(); + if (!pViewData) +@@ -883,7 +883,7 @@ OUString ScModelObj::getRowColumnHeaders() + if (!pTabView) + return OUString(); + +- return pTabView->getRowColumnHeaders(); ++ return pTabView->getRowColumnHeaders(rRectangle); + } + + void ScModelObj::initializeForTiledRendering() +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index 2d886bca6003..1cb869cbd432 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2303,7 +2303,7 @@ void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vectorGetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow); + + boost::property_tree::ptree aRows; ++ long nTotal = 0; ++ long nTotalPixels = 0; + for (SCROW nRow = 0; nRow <= nEndRow; ++nRow) + { +- boost::property_tree::ptree aRow; + sal_uInt16 nSize = pDoc->GetOriginalHeight(nRow, aViewData.GetTabNo()); +- aRow.put("size", OString::number(nSize).getStr()); + OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); +- aRow.put("text", aText.toUtf8().getStr()); +- aRows.push_back(std::make_pair("", aRow)); ++ ++ bool bSkip = false; ++ if (!rRectangle.IsEmpty()) ++ { ++ long nTop = std::max(rRectangle.Top(), nTotal); ++ long nBottom = std::min(rRectangle.Bottom(), nTotal + nSize); ++ if (nBottom < nTop) ++ // They do not intersect. ++ bSkip = true; ++ } ++ if (!bSkip) ++ { ++ if (aRows.empty()) ++ { ++ // The sizes are relative sizes, so include the total skipped size before the real items. ++ boost::property_tree::ptree aRow; ++ // Client is required to floor(), rather than round() the sizes in general, so add 0.5 here to have rounding. ++ aRow.put("size", OString::number(long((nTotalPixels + 0.5) / aViewData.GetPPTY())).getStr()); ++ aRow.put("text", ""); ++ aRows.push_back(std::make_pair("", aRow)); ++ } ++ boost::property_tree::ptree aRow; ++ aRow.put("size", OString::number(nSize).getStr()); ++ aRow.put("text", aText.toUtf8().getStr()); ++ aRows.push_back(std::make_pair("", aRow)); ++ } ++ nTotal += nSize; ++ nTotalPixels += long(nSize * aViewData.GetPPTY()); + } + + boost::property_tree::ptree aCols; +-- +2.12.0 + diff --git a/SOURCES/0267-sc-lok-allow-requesting-column-headers-only-for-a-lo.patch b/SOURCES/0267-sc-lok-allow-requesting-column-headers-only-for-a-lo.patch new file mode 100644 index 0000000..de08deb --- /dev/null +++ b/SOURCES/0267-sc-lok-allow-requesting-column-headers-only-for-a-lo.patch @@ -0,0 +1,62 @@ +From fb9903c682fdabcc425caea737d81eda1a33f902 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 3 Nov 2015 15:37:31 +0100 +Subject: [PATCH 267/398] sc lok: allow requesting column headers only for a + logic area + +Change-Id: Iacd8f11917e929c6a1579c6a1553eb7840df5fba +(cherry picked from commit 0fe622f66ee04f25b05c2069f573010e6f517915) +--- + sc/source/ui/view/tabview.cxx | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index 1cb869cbd432..ab77b47bed0c 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2351,14 +2351,38 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + } + + boost::property_tree::ptree aCols; ++ nTotal = 0; ++ nTotalPixels = 0; + for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol) + { +- boost::property_tree::ptree aCol; + sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo()); +- aCol.put("size", OString::number(nSize).getStr()); + OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); +- aCol.put("text", aText.toUtf8().getStr()); +- aCols.push_back(std::make_pair("", aCol)); ++ ++ bool bSkip = false; ++ if (!rRectangle.IsEmpty()) ++ { ++ long nLeft = std::max(rRectangle.Left(), nTotal); ++ long nRight = std::min(rRectangle.Right(), nTotal + nSize); ++ if (nRight < nLeft) ++ // They do not intersect. ++ bSkip = true; ++ } ++ if (!bSkip) ++ { ++ if (aCols.empty()) ++ { ++ boost::property_tree::ptree aCol; ++ aCol.put("size", OString::number(long((nTotalPixels + 0.5) / aViewData.GetPPTX())).getStr()); ++ aCol.put("text", ""); ++ aCols.push_back(std::make_pair("", aCol)); ++ } ++ boost::property_tree::ptree aCol; ++ aCol.put("size", OString::number(nSize).getStr()); ++ aCol.put("text", aText.toUtf8().getStr()); ++ aCols.push_back(std::make_pair("", aCol)); ++ } ++ nTotal += nSize; ++ nTotalPixels += long(nSize * aViewData.GetPPTX()); + } + + boost::property_tree::ptree aTree; +-- +2.12.0 + diff --git a/SOURCES/0268-Werror-Wformat-security.patch b/SOURCES/0268-Werror-Wformat-security.patch new file mode 100644 index 0000000..c3b4bc1 --- /dev/null +++ b/SOURCES/0268-Werror-Wformat-security.patch @@ -0,0 +1,27 @@ +From 9e14d0d17a06e002b0729c710f6abe6b1d7ef220 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 3 Nov 2015 16:06:26 +0100 +Subject: [PATCH 268/398] -Werror,-Wformat-security + +Change-Id: I34976a4900a73505a91d3e58736675ab39ad174c +(cherry picked from commit 1347b90c9e5f54fd0b7e7147519f34d3c1b282d5) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 953eeb0f1db2..ae9f2600440c 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -264,7 +264,7 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + aCommand << "&height=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pRowBar->m_nSizePixel)); + std::stringstream ss; + ss << "lok::Document::getCommandValues(" << aCommand.str() << ")"; +- g_info(ss.str().c_str()); ++ g_info("%s", ss.str().c_str()); + char* pValues = pDocument->pClass->getCommandValues(pDocument, aCommand.str().c_str()); + std::stringstream aStream(pValues); + free(pValues); +-- +2.12.0 + diff --git a/SOURCES/0269-sc-lok-avoid-placeholder-row-when-providing-all-head.patch b/SOURCES/0269-sc-lok-avoid-placeholder-row-when-providing-all-head.patch new file mode 100644 index 0000000..50dbd07 --- /dev/null +++ b/SOURCES/0269-sc-lok-avoid-placeholder-row-when-providing-all-head.patch @@ -0,0 +1,103 @@ +From 177773ea3cb22e81fa30dd9ffc89aa7e8a8fa4f1 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 3 Nov 2015 16:26:46 +0100 +Subject: [PATCH 269/398] sc lok: avoid placeholder row when providing all + headers + +In case the logic visible area is known, info is provided only about the +visible headers. Given that only relative sizes (no absolute positions) +are provided, a placeholder row/col is added to the result that contains +the total size of the skipped items. + +These placeholder items are not needed when providing all headers, so +don't emit them. + +Change-Id: I48ccb73554313f4d2bb420e4402995719b0f9f7d +(cherry picked from commit 788cec0a60dcfce6d86c820e9d0f7a1eb634f7bf) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 32 +++++++++++++++++++++++++++++ + sc/source/ui/view/tabview.cxx | 4 ++-- + 2 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index c14261e82db6..29b0aedd4dfa 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -66,6 +66,7 @@ public: + void testSaveAs(); + void testSaveAsCalc(); + void testPasteWriter(); ++ void testRowColumnHeaders(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -78,6 +79,7 @@ public: + CPPUNIT_TEST(testSaveAs); + CPPUNIT_TEST(testSaveAsCalc); + CPPUNIT_TEST(testPasteWriter); ++ CPPUNIT_TEST(testRowColumnHeaders); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -346,6 +348,36 @@ void DesktopLOKTest::testPasteWriter() + comphelper::LibreOfficeKit::setActive(false); + } + ++void DesktopLOKTest::testRowColumnHeaders() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("search.ods"); ++ boost::property_tree::ptree aTree; ++ char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); ++ std::stringstream aStream(pJSON); ++ free(pJSON); ++ CPPUNIT_ASSERT(!aStream.str().empty()); ++ ++ boost::property_tree::read_json(aStream, aTree); ++ for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) ++ { ++ sal_Int32 nSize = OString(rValue.second.get("size").c_str()).toInt32(); ++ CPPUNIT_ASSERT(nSize > 0); ++ OString aText(rValue.second.get("text").c_str()); ++ // This failed, as the first item did not contain the text of the first row. ++ CPPUNIT_ASSERT_EQUAL(OString("1"), aText); ++ break; ++ } ++ ++ for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns")) ++ { ++ sal_Int32 nSize = OString(rValue.second.get("size").c_str()).toInt32(); ++ CPPUNIT_ASSERT(nSize > 0); ++ OString aText(rValue.second.get("text").c_str()); ++ CPPUNIT_ASSERT_EQUAL(OString("A"), aText); ++ break; ++ } ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index ab77b47bed0c..8edec1b22f3a 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2332,7 +2332,7 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + } + if (!bSkip) + { +- if (aRows.empty()) ++ if (aRows.empty() && nTotal > 0) + { + // The sizes are relative sizes, so include the total skipped size before the real items. + boost::property_tree::ptree aRow; +@@ -2369,7 +2369,7 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + } + if (!bSkip) + { +- if (aCols.empty()) ++ if (aCols.empty() && nTotal > 0) + { + boost::property_tree::ptree aCol; + aCol.put("size", OString::number(long((nTotalPixels + 0.5) / aViewData.GetPPTX())).getStr()); +-- +2.12.0 + diff --git a/SOURCES/0270-lok-Unit-test-for-LOK_CALLBACK_UNO_COMMAND_RESULT.patch b/SOURCES/0270-lok-Unit-test-for-LOK_CALLBACK_UNO_COMMAND_RESULT.patch new file mode 100644 index 0000000..129fe84 --- /dev/null +++ b/SOURCES/0270-lok-Unit-test-for-LOK_CALLBACK_UNO_COMMAND_RESULT.patch @@ -0,0 +1,95 @@ +From 8e7c77d0706c4a2870de61948364667b575ff027 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 3 Nov 2015 16:43:03 +0100 +Subject: [PATCH 270/398] lok: Unit test for LOK_CALLBACK_UNO_COMMAND_RESULT. + +Change-Id: I917d47478504dc6fafd3fc675fe8458690c7cc2a +(cherry picked from commit a4988d227c3933721098b2a61a087ec18eaa6c8e) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 36 +++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 29b0aedd4dfa..15fe123fdc37 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -67,6 +68,7 @@ public: + void testSaveAsCalc(); + void testPasteWriter(); + void testRowColumnHeaders(); ++ void testCommandResult(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -80,12 +82,17 @@ public: + CPPUNIT_TEST(testSaveAsCalc); + CPPUNIT_TEST(testPasteWriter); + CPPUNIT_TEST(testRowColumnHeaders); ++ CPPUNIT_TEST(testCommandResult); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; + OString m_aTextSelection; + std::vector m_aSearchResultSelection; + std::vector m_aSearchResultPart; ++ ++ // for testCommandResult ++ osl::Condition m_aCommandResultCondition; ++ OString m_aCommandResult; + }; + + LibLODocument_Impl* DesktopLOKTest::loadDoc(const char* pName, LibreOfficeKitDocumentType eType) +@@ -149,6 +156,12 @@ void DesktopLOKTest::callbackImpl(int nType, const char* pPayload) + } + } + break; ++ case LOK_CALLBACK_UNO_COMMAND_RESULT: ++ { ++ m_aCommandResult = pPayload; ++ m_aCommandResultCondition.set(); ++ } ++ break; + } + } + +@@ -378,6 +391,29 @@ void DesktopLOKTest::testRowColumnHeaders() + } + } + ++void DesktopLOKTest::testCommandResult() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); ++ ++ // the postUnoCommand() is supposed to be async, let's test it safely ++ // [no idea if it is async in reality - most probably we are operating ++ // under some solar mutex or something anyway ;-) - but...] ++ m_aCommandResultCondition.reset(); ++ ++ pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", 0, true); ++ ++ TimeValue aTimeValue = { 2 , 0 }; // 2 seconds max ++ m_aCommandResultCondition.wait(aTimeValue); ++ ++ boost::property_tree::ptree aTree; ++ std::stringstream aStream(m_aCommandResult.getStr()); ++ boost::property_tree::read_json(aStream, aTree); ++ ++ CPPUNIT_ASSERT_EQUAL(aTree.get_child("commandName").get_value(), std::string(".uno:Bold")); ++ CPPUNIT_ASSERT_EQUAL(aTree.get_child("success").get_value(), true); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +-- +2.12.0 + diff --git a/SOURCES/0271-lok-Fix-crash-due-to-non-initialized-callback.patch b/SOURCES/0271-lok-Fix-crash-due-to-non-initialized-callback.patch new file mode 100644 index 0000000..62fe436 --- /dev/null +++ b/SOURCES/0271-lok-Fix-crash-due-to-non-initialized-callback.patch @@ -0,0 +1,67 @@ +From d048d2bb9464d5bb86b37e7da436be6ffe13ab29 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Tue, 3 Nov 2015 16:52:46 +0100 +Subject: [PATCH 271/398] lok: Fix crash due to non-initialized callback. + +Yay for unit tests! :-) + +Change-Id: I06b3f929b53d5c03f5722acfdaf0eaf841325e34 +(cherry picked from commit b846b03c709130564527da8d264660a131361221) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 15 ++++++++++++--- + desktop/source/lib/init.cxx | 6 ++++-- + 2 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 15fe123fdc37..4c23ecb50b73 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -394,16 +394,25 @@ void DesktopLOKTest::testRowColumnHeaders() + void DesktopLOKTest::testCommandResult() + { + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); +- pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); + + // the postUnoCommand() is supposed to be async, let's test it safely + // [no idea if it is async in reality - most probably we are operating + // under some solar mutex or something anyway ;-) - but...] +- m_aCommandResultCondition.reset(); ++ TimeValue aTimeValue = { 2 , 0 }; // 2 seconds max + ++ // nothing is triggered when we have no callback yet, we just time out on ++ // the condition var. ++ m_aCommandResultCondition.reset(); + pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", 0, true); ++ m_aCommandResultCondition.wait(aTimeValue); + +- TimeValue aTimeValue = { 2 , 0 }; // 2 seconds max ++ CPPUNIT_ASSERT(m_aCommandResult.isEmpty()); ++ ++ // but we get some real values when the callback is set up ++ pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); ++ ++ m_aCommandResultCondition.reset(); ++ pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", 0, true); + m_aCommandResultCondition.wait(aTimeValue); + + boost::property_tree::ptree aTree; +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index b9aeedd5e21c..bf244cd7aefa 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -268,8 +268,10 @@ static void doc_setView(LibreOfficeKitDocument* pThis, int nId); + static int doc_getView(LibreOfficeKitDocument* pThis); + static int doc_getViews(LibreOfficeKitDocument* pThis); + +-LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) : +- mxComponent( xComponent ) ++LibLODocument_Impl::LibLODocument_Impl(const uno::Reference &xComponent) ++ : mxComponent(xComponent) ++ , mpCallback(nullptr) ++ , mpCallbackData(nullptr) + { + if (!(m_pDocumentClass = gDocumentClass.lock())) + { +-- +2.12.0 + diff --git a/SOURCES/0272-Werror-Wformat-security.patch b/SOURCES/0272-Werror-Wformat-security.patch new file mode 100644 index 0000000..4d37a05 --- /dev/null +++ b/SOURCES/0272-Werror-Wformat-security.patch @@ -0,0 +1,36 @@ +From c2a9d38653fb3732dd8dbece557443423ba4b956 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 3 Nov 2015 22:20:45 +0100 +Subject: [PATCH 272/398] -Werror,-Wformat-security + +Change-Id: I23f4b906456fdba84f2772a4ed15ac6c141a094d +(cherry picked from commit 02b39996fa8447305900adad509250646c0a3b80) +--- + libreofficekit/source/gtk/lokdocview.cxx | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index bcb1d136b749..9cf78a3f5429 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1530,7 +1530,7 @@ postCommandInThread (gpointer data) + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + std::stringstream ss; + ss << "lok::Document::postUnoCommand(" << pLOEvent->m_pCommand << ", " << pLOEvent->m_pArguments << ")"; +- g_info(ss.str().c_str()); ++ g_info("%s", ss.str().c_str()); + priv->m_pDocument->pClass->postUnoCommand(priv->m_pDocument, pLOEvent->m_pCommand, pLOEvent->m_pArguments, pLOEvent->m_bNotifyWhenFinished); + } + +@@ -1566,7 +1566,7 @@ paintTileInThread (gpointer data) + << aTileRectangle.x << ", " << aTileRectangle.y << ", " + << pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) << ", " + << pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom) << ")"; +- g_info(ss.str().c_str()); ++ g_info("%s", ss.str().c_str()); + priv->m_pDocument->pClass->paintTile(priv->m_pDocument, + pBuffer, + nTileSizePixels, nTileSizePixels, +-- +2.12.0 + diff --git a/SOURCES/0273-sc-lok-return-absolute-positions-for-row-column-head.patch b/SOURCES/0273-sc-lok-return-absolute-positions-for-row-column-head.patch new file mode 100644 index 0000000..596bac0 --- /dev/null +++ b/SOURCES/0273-sc-lok-return-absolute-positions-for-row-column-head.patch @@ -0,0 +1,181 @@ +From b3c590099965fbe3adb89a1b40e8d346f82d3d76 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 4 Nov 2015 10:32:23 +0100 +Subject: [PATCH 273/398] sc lok: return absolute positions for row/column + headers + +This simplifies both LOK API implementation and client code, and also +clients are no longer required to floor() the twip -> pixel conversion +result. + +Change-Id: I63dbc05f53e8f7582b964c43d5da3aad51ede10d +(cherry picked from commit 84dedf4ff8e7267efa95674e6545c80c9b995cb2) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 36 ++++++++-------------- + sc/source/ui/view/tabview.cxx | 26 ++++------------ + 2 files changed, 19 insertions(+), 43 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index ae9f2600440c..6ebd5bcc6ef5 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -192,16 +192,16 @@ gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + { + cairo_set_source_rgb(pCairo, 0, 0, 0); + +- int nTotal = 0; ++ int nPrevious = 0; + for (const Header& rHeader : m_aHeaders) + { + GdkRectangle aRectangle; + if (m_eType == ROW) + { + aRectangle.x = 0; +- aRectangle.y = nTotal - 1; ++ aRectangle.y = nPrevious - 1; + aRectangle.width = ROW_HEADER_WIDTH - 1; +- aRectangle.height = rHeader.m_nSize; ++ aRectangle.height = rHeader.m_nSize - nPrevious; + // Left line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.y, 1, aRectangle.height); + cairo_fill(pCairo); +@@ -214,9 +214,9 @@ gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + } + else + { +- aRectangle.x = nTotal - 1; ++ aRectangle.x = nPrevious - 1; + aRectangle.y = 0; +- aRectangle.width = rHeader.m_nSize; ++ aRectangle.width = rHeader.m_nSize - nPrevious; + aRectangle.height = COLUMN_HEADER_HEIGHT - 1; + // Top line. + cairo_rectangle(pCairo, aRectangle.x, aRectangle.y, aRectangle.width, 1); +@@ -229,8 +229,8 @@ gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + cairo_fill(pCairo); + } + drawText(pCairo, aRectangle, rHeader.m_aText); +- nTotal += rHeader.m_nSize; +- if (nTotal > m_nSizePixel) ++ nPrevious = rHeader.m_nSize; ++ if (rHeader.m_nSize > m_nSizePixel) + break; + } + +@@ -275,39 +275,29 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + gtk_widget_show(rWindow.m_pCornerButton->m_pDrawingArea); + + rWindow.m_pRowBar->m_aHeaders.clear(); +- int nTotal = 0; + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { +- int nSize = lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str())); +- int nScrolledSize = nSize; +- if (nTotal + nSize >= rWindow.m_pRowBar->m_nPositionPixel) ++ int nSize = std::round(lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str()))); ++ if (nSize >= rWindow.m_pRowBar->m_nPositionPixel) + { +- if (nTotal < rWindow.m_pRowBar->m_nPositionPixel) +- // First visible row: reduce height because the row is only partially visible. +- nScrolledSize = nTotal + nSize - rWindow.m_pRowBar->m_nPositionPixel; ++ int nScrolledSize = nSize - rWindow.m_pRowBar->m_nPositionPixel; + Header aHeader(nScrolledSize, rValue.second.get("text")); + rWindow.m_pRowBar->m_aHeaders.push_back(aHeader); + } +- nTotal += nSize; + } + gtk_widget_show(rWindow.m_pRowBar->m_pDrawingArea); + gtk_widget_queue_draw(rWindow.m_pRowBar->m_pDrawingArea); + + rWindow.m_pColumnBar->m_aHeaders.clear(); +- nTotal = 0; + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns")) + { +- int nSize = lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str())); +- int nScrolledSize = nSize; +- if (nTotal + nSize >= rWindow.m_pColumnBar->m_nPositionPixel) ++ int nSize = std::round(lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), std::atof(rValue.second.get("size").c_str()))); ++ if (nSize >= rWindow.m_pColumnBar->m_nPositionPixel) + { +- if (nTotal < rWindow.m_pColumnBar->m_nPositionPixel) +- // First visible column: reduce width because the column is only partially visible. +- nScrolledSize = nTotal + nSize - rWindow.m_pColumnBar->m_nPositionPixel; ++ int nScrolledSize = nSize - rWindow.m_pColumnBar->m_nPositionPixel; + Header aHeader(nScrolledSize, rValue.second.get("text")); + rWindow.m_pColumnBar->m_aHeaders.push_back(aHeader); + } +- nTotal += nSize; + } + gtk_widget_show(rWindow.m_pColumnBar->m_pDrawingArea); + gtk_widget_queue_draw(rWindow.m_pColumnBar->m_pDrawingArea); +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index 8edec1b22f3a..d8fcd4ff4a73 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2319,6 +2319,7 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + for (SCROW nRow = 0; nRow <= nEndRow; ++nRow) + { + sal_uInt16 nSize = pDoc->GetOriginalHeight(nRow, aViewData.GetTabNo()); ++ long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTY()); + OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow); + + bool bSkip = false; +@@ -2332,22 +2333,13 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + } + if (!bSkip) + { +- if (aRows.empty() && nTotal > 0) +- { +- // The sizes are relative sizes, so include the total skipped size before the real items. +- boost::property_tree::ptree aRow; +- // Client is required to floor(), rather than round() the sizes in general, so add 0.5 here to have rounding. +- aRow.put("size", OString::number(long((nTotalPixels + 0.5) / aViewData.GetPPTY())).getStr()); +- aRow.put("text", ""); +- aRows.push_back(std::make_pair("", aRow)); +- } + boost::property_tree::ptree aRow; +- aRow.put("size", OString::number(nSize).getStr()); ++ aRow.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY()).getStr()); + aRow.put("text", aText.toUtf8().getStr()); + aRows.push_back(std::make_pair("", aRow)); + } + nTotal += nSize; +- nTotalPixels += long(nSize * aViewData.GetPPTY()); ++ nTotalPixels += nSizePixels; + } + + boost::property_tree::ptree aCols; +@@ -2356,6 +2348,7 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol) + { + sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo()); ++ long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTX()); + OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol); + + bool bSkip = false; +@@ -2369,20 +2362,13 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + } + if (!bSkip) + { +- if (aCols.empty() && nTotal > 0) +- { +- boost::property_tree::ptree aCol; +- aCol.put("size", OString::number(long((nTotalPixels + 0.5) / aViewData.GetPPTX())).getStr()); +- aCol.put("text", ""); +- aCols.push_back(std::make_pair("", aCol)); +- } + boost::property_tree::ptree aCol; +- aCol.put("size", OString::number(nSize).getStr()); ++ aCol.put("size", OString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX()).getStr()); + aCol.put("text", aText.toUtf8().getStr()); + aCols.push_back(std::make_pair("", aCol)); + } + nTotal += nSize; +- nTotalPixels += long(nSize * aViewData.GetPPTX()); ++ nTotalPixels += nSizePixels; + } + + boost::property_tree::ptree aTree; +-- +2.12.0 + diff --git a/SOURCES/0274-CppunitTest_desktop_lib-test-absolute-positions-for-.patch b/SOURCES/0274-CppunitTest_desktop_lib-test-absolute-positions-for-.patch new file mode 100644 index 0000000..0323a3b --- /dev/null +++ b/SOURCES/0274-CppunitTest_desktop_lib-test-absolute-positions-for-.patch @@ -0,0 +1,99 @@ +From 8cef5dbaf83e049e929d6319acb785bdaac447a5 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 4 Nov 2015 10:59:08 +0100 +Subject: [PATCH 274/398] CppunitTest_desktop_lib: test absolute positions for + row/column headers + +Change-Id: If2526647221fef2c6b18b21b589192239d8a89ad +(cherry picked from commit 2bed1867531fc91d1bd20da226d3fa012356125d) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 54 ++++++++++++++++++++++++++--- + 1 file changed, 49 insertions(+), 5 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 4c23ecb50b73..8c622a577231 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -363,6 +363,35 @@ void DesktopLOKTest::testPasteWriter() + + void DesktopLOKTest::testRowColumnHeaders() + { ++ /* ++ * Payload example: ++ * ++ * { ++ * "rows": [ ++ * { ++ * "size": "254.987250637468", ++ * "text": "1" ++ * }, ++ * { ++ * "size": "509.974501274936", ++ * "text": "2" ++ * } ++ * ], ++ * "columns": [ ++ * { ++ * "size": "1274.93625318734", ++ * "text": "A" ++ * }, ++ * { ++ * "size": "2549.87250637468", ++ * "text": "B" ++ * } ++ * ] ++ * } ++ * ++ * "size" defines the bottom/right boundary of a row/column in twips (size between 0 and boundary) ++ * "text" has the header label in UTF-8 ++ */ + LibLODocument_Impl* pDocument = loadDoc("search.ods"); + boost::property_tree::ptree aTree; + char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); +@@ -371,23 +400,38 @@ void DesktopLOKTest::testRowColumnHeaders() + CPPUNIT_ASSERT(!aStream.str().empty()); + + boost::property_tree::read_json(aStream, aTree); ++ sal_Int32 nPrevious = 0; + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("rows")) + { + sal_Int32 nSize = OString(rValue.second.get("size").c_str()).toInt32(); + CPPUNIT_ASSERT(nSize > 0); + OString aText(rValue.second.get("text").c_str()); +- // This failed, as the first item did not contain the text of the first row. +- CPPUNIT_ASSERT_EQUAL(OString("1"), aText); +- break; ++ if (!nPrevious) ++ // This failed, as the first item did not contain the text of the first row. ++ CPPUNIT_ASSERT_EQUAL(OString("1"), aText); ++ else ++ { ++ // Make sure that size is absolute: the first two items have the same relative size. ++ CPPUNIT_ASSERT(nPrevious < nSize); ++ break; ++ } ++ nPrevious = nSize; + } + ++ nPrevious = 0; + for (boost::property_tree::ptree::value_type& rValue : aTree.get_child("columns")) + { + sal_Int32 nSize = OString(rValue.second.get("size").c_str()).toInt32(); + CPPUNIT_ASSERT(nSize > 0); + OString aText(rValue.second.get("text").c_str()); +- CPPUNIT_ASSERT_EQUAL(OString("A"), aText); +- break; ++ if (!nPrevious) ++ CPPUNIT_ASSERT_EQUAL(OString("A"), aText); ++ else ++ { ++ CPPUNIT_ASSERT(nPrevious < nSize); ++ break; ++ } ++ nPrevious = nSize; + } + } + +-- +2.12.0 + diff --git a/SOURCES/0275-lokdocview-Don-t-render-tiles-while-tile-buffer-has-.patch b/SOURCES/0275-lokdocview-Don-t-render-tiles-while-tile-buffer-has-.patch new file mode 100644 index 0000000..24b30ac --- /dev/null +++ b/SOURCES/0275-lokdocview-Don-t-render-tiles-while-tile-buffer-has-.patch @@ -0,0 +1,176 @@ +From 26a44f8b7e9ce4e5e9a097f5fedc04d4717fd51d Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 1 Nov 2015 17:11:09 +0530 +Subject: [PATCH 275/398] lokdocview: Don't render tiles while tile buffer has + changed + +This is common when widget gets a zoom request, resulting in a +new tile buffer, and the tiles from the old tile buffer are still +waiting to be processed in the LOK thread, for old tile buffer. If +we allow these useless operations to execute successfully, they +would end up writing in new tile buffer giving false results. + +Lets tag every paint tile operations with their respective tile +buffer during `task` creation, and then check whether the tile +buffer has changed or not before writing to the tile buffer. + +Change-Id: If784341a67ad430bc3415b765137badaad6b97f6 +Reviewed-on: https://gerrit.libreoffice.org/19726 +Reviewed-by: Miklos Vajna +Tested-by: Miklos Vajna +(cherry picked from commit 93f98e98e42d75914a3e1d8f85bd3c6328d2e111) +--- + libreofficekit/source/gtk/lokdocview.cxx | 38 ++++++++++++++++++++++++++++++-- + libreofficekit/source/gtk/tilebuffer.cxx | 6 +++++ + libreofficekit/source/gtk/tilebuffer.hxx | 15 +++++++++++++ + 3 files changed, 57 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 9cf78a3f5429..575116f4d028 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -912,7 +912,12 @@ paintTileCallback(GObject* sourceObject, GAsyncResult* res, gpointer userData) + GdkPixbuf* pPixBuf = static_cast(paintTileFinish(pDocView, res, &error)); + if (error != NULL) + { +- g_warning("Unable to get painted GdkPixbuf: %s", error->message); ++ if (error->domain == LOK_TILEBUFFER_ERROR && ++ error->code == LOK_TILEBUFFER_CHANGED) ++ g_info("Skipping paint tile request because corresponding" ++ "tile buffer has been destroyed"); ++ else ++ g_warning("Unable to get painted GdkPixbuf: %s", error->message); + g_error_free(error); + return; + } +@@ -977,6 +982,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + pLOEvent->m_nPaintTileX = nRow; + pLOEvent->m_nPaintTileY = nColumn; + pLOEvent->m_fPaintTileZoom = priv->m_fZoom; ++ pLOEvent->m_pTileBuffer = &*priv->m_pTileBuffer; + GTask* task = g_task_new(pDocView, NULL, paintTileCallback, pLOEvent); + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +@@ -1541,6 +1547,17 @@ paintTileInThread (gpointer data) + LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); + LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ ++ // check if "source" tile buffer is different from "current" tile buffer ++ if (pLOEvent->m_pTileBuffer != &*priv->m_pTileBuffer) ++ { ++ pLOEvent->m_pTileBuffer = nullptr; ++ g_task_return_new_error(task, ++ LOK_TILEBUFFER_ERROR, ++ LOK_TILEBUFFER_CHANGED, ++ "TileBuffer has changed"); ++ return; ++ } + std::unique_ptr& buffer = priv->m_pTileBuffer; + int index = pLOEvent->m_nPaintTileX * buffer->m_nWidth + pLOEvent->m_nPaintTileY; + if (buffer->m_mTiles.find(index) != buffer->m_mTiles.end() && +@@ -1550,7 +1567,10 @@ paintTileInThread (gpointer data) + GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); + if (!pPixBuf) + { +- g_info ("Error allocating memory to pixbuf"); ++ g_task_return_new_error(task, ++ LOK_TILEBUFFER_ERROR, ++ LOK_TILEBUFFER_MEMORY, ++ "Error allocating memory to GdkPixbuf"); + return; + } + +@@ -1574,6 +1594,20 @@ paintTileInThread (gpointer data) + pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom), + pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom)); + ++ // Its likely that while the tilebuffer has changed, one of the paint tile ++ // requests has passed the previous check at start of this function, and has ++ // rendered the tile already. We want to stop such rendered tiles from being ++ // stored in new tile buffer. ++ if (pLOEvent->m_pTileBuffer != &*priv->m_pTileBuffer) ++ { ++ pLOEvent->m_pTileBuffer = nullptr; ++ g_task_return_new_error(task, ++ LOK_TILEBUFFER_ERROR, ++ LOK_TILEBUFFER_CHANGED, ++ "TileBuffer has changed"); ++ return; ++ } ++ + g_task_return_pointer(task, pPixBuf, g_object_unref); + } + +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 1158209b2273..32a9534e884c 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -121,4 +121,10 @@ void LOEvent::destroy(void* pMemory) + delete pLOEvent; + } + ++GQuark ++LOKTileBufferErrorQuark(void) ++{ ++ return g_quark_from_static_string("lok-tilebuffer-error"); ++} ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 8a8569eeb306..9407257e5fec 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -19,6 +19,8 @@ + #include + #include + ++#define LOK_TILEBUFFER_ERROR (LOKTileBufferErrorQuark()) ++ + // We know that VirtualDevices use a DPI of 96. + const int DPI = 96; + // Lets use a square of side 256 pixels for each tile. +@@ -45,6 +47,11 @@ float pixelToTwip(float fInput, float zoom); + float twipToPixel(float fInput, float zoom); + + /** ++ Gets GQuark identifying this tile buffer errors ++*/ ++GQuark LOKTileBufferErrorQuark(void); ++ ++/** + This class represents a single tile in the tile buffer. + It encloses a reference to GdkPixBuf containing the pixel data of the tile. + */ +@@ -155,6 +162,12 @@ enum + LOK_SET_GRAPHIC_SELECTION + }; + ++enum ++{ ++ LOK_TILEBUFFER_CHANGED, ++ LOK_TILEBUFFER_MEMORY ++}; ++ + /** + A struct that we use to store the data about the LOK call. + +@@ -200,6 +213,7 @@ struct LOEvent + int m_nPaintTileX; + int m_nPaintTileY; + float m_fPaintTileZoom; ++ TileBuffer* m_pTileBuffer; + ///@} + + /// @name postMouseEvent parameters +@@ -235,6 +249,7 @@ struct LOEvent + , m_nPaintTileX(0) + , m_nPaintTileY(0) + , m_fPaintTileZoom(0) ++ , m_pTileBuffer(nullptr) + , m_nPostMouseEventType(0) + , m_nPostMouseEventX(0) + , m_nPostMouseEventY(0) +-- +2.12.0 + diff --git a/SOURCES/0276-sc-lok-Cell-Cursor-callback.patch b/SOURCES/0276-sc-lok-Cell-Cursor-callback.patch new file mode 100644 index 0000000..1902dc7 --- /dev/null +++ b/SOURCES/0276-sc-lok-Cell-Cursor-callback.patch @@ -0,0 +1,177 @@ +From 8289d40ed650611d5c5dbfe84810ac48af3665dc Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Mon, 2 Nov 2015 11:43:05 +0100 +Subject: [PATCH 276/398] sc lok: Cell Cursor callback + +This only works correctly for the default zoom level - since +the updateLibreOfficeKitCellCursor call happens during the +internal / hidden rendering, it uses the internal zoom values, +which can differ from the tiled-rendering zoom values. + +Conflicts: + include/LibreOfficeKit/LibreOfficeKitEnums.h + +(cherry picked from commit 799406068d34bb69a077fcc0548bfed002f05641) + +Change-Id: Ie4f344fe771078fca10ad9d6f7a93e88fb93880a +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 9 +++++++- + libreofficekit/source/gtk/lokdocview.cxx | 30 ++++++++++++++++++++++++++ + sc/source/ui/view/gridwin.cxx | 32 ++++++++++++++++++++++++---- + 3 files changed, 66 insertions(+), 5 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 86d9e6bfd873..bf6267585a0a 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -195,7 +195,14 @@ typedef enum + * // TODO "result": "..." // UNO Any converted to JSON (not implemented yet) + * } + */ +- LOK_CALLBACK_UNO_COMMAND_RESULT ++ LOK_CALLBACK_UNO_COMMAND_RESULT, ++ ++ /** ++ * The size and/or the position of the cell cursor changed. ++ * ++ * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES. ++ */ ++ LOK_CALLBACK_CELL_CURSOR + } + LibreOfficeKitCallbackType; + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 575116f4d028..73b01797dbf9 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -79,6 +79,7 @@ struct LOKDocViewPrivateImpl + /// Position and size of the selection end. + GdkRectangle m_aTextSelectionEnd; + GdkRectangle m_aGraphicSelection; ++ GdkRectangle m_aCellCursor; + gboolean m_bInDragGraphicSelection; + + /// @name Start/middle/end handle. +@@ -140,6 +141,7 @@ struct LOKDocViewPrivateImpl + m_aTextSelectionStart({0, 0, 0, 0}), + m_aTextSelectionEnd({0, 0, 0, 0}), + m_aGraphicSelection({0, 0, 0, 0}), ++ m_aCellCursor({0, 0, 0, 0}), + m_bInDragGraphicSelection(false), + m_pHandleStart(0), + m_aHandleStartRect({0, 0, 0, 0}), +@@ -275,6 +277,8 @@ callbackTypeToString (int nType) + return "LOK_CALLBACK_CURSOR_VISIBLE"; + case LOK_CALLBACK_GRAPHIC_SELECTION: + return "LOK_CALLBACK_GRAPHIC_SELECTION"; ++ case LOK_CALLBACK_CELL_CURSOR: ++ return "LOK_CALLBACK_CELL_CURSOR"; + case LOK_CALLBACK_HYPERLINK_CLICKED: + return "LOK_CALLBACK_HYPERLINK_CLICKED"; + case LOK_CALLBACK_STATE_CHANGED: +@@ -719,6 +723,15 @@ callback (gpointer pData) + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + break; ++ case LOK_CALLBACK_CELL_CURSOR: ++ { ++ if (pCallback->m_aPayload != "EMPTY") ++ priv->m_aCellCursor = payloadToRectangle(pDocView, pCallback->m_aPayload.c_str()); ++ else ++ memset(&priv->m_aCellCursor, 0, sizeof(priv->m_aCellCursor)); ++ gtk_widget_queue_draw(GTK_WIDGET(pDocView)); ++ } ++ break; + case LOK_CALLBACK_HYPERLINK_CLICKED: + { + hyperlinkClicked(pDocView, pCallback->m_aPayload); +@@ -1074,6 +1087,22 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + g_free (handleGraphicPath); + } + ++ if (!isEmptyRectangle(priv->m_aCellCursor)) ++ { ++ cairo_set_source_rgb(pCairo, 0, 0, 0); ++ cairo_rectangle(pCairo, ++ twipToPixel(priv->m_aCellCursor.x, priv->m_fZoom), ++ twipToPixel(priv->m_aCellCursor.y, priv->m_fZoom), ++ twipToPixel(priv->m_aCellCursor.width, priv->m_fZoom), ++ twipToPixel(priv->m_aCellCursor.height, priv->m_fZoom)); ++ // priv->m_aCellCursor.x - 1, ++ // priv->m_aCellCursor.y - 1, ++ // priv->m_aCellCursor.width + 2, ++ // priv->m_aCellCursor.height + 2); ++ cairo_set_line_width(pCairo, 2.0); ++ cairo_stroke(pCairo); ++ } ++ + return FALSE; + } + +@@ -2331,6 +2360,7 @@ lok_doc_view_reset_view(LOKDocView* pDocView) + memset(&priv->m_aTextSelectionEnd, 0, sizeof(priv->m_aTextSelectionEnd)); + memset(&priv->m_aGraphicSelection, 0, sizeof(priv->m_aGraphicSelection)); + priv->m_bInDragGraphicSelection = false; ++ memset(&priv->m_aCellCursor, 0, sizeof(priv->m_aCellCursor)); + + cairo_surface_destroy(priv->m_pHandleStart); + priv->m_pHandleStart = 0; +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index f24b42f3b27e..7ab88c6c0eb1 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -5782,13 +5782,38 @@ bool ScGridWindow::InsideVisibleRange( SCCOL nPosX, SCROW nPosY ) + return maVisibleRange.isInside(nPosX, nPosY); + } + +-// #114409# ++static void updateLibreOfficeKitCellCursor(ScViewData* pViewData, ScSplitPos eWhich) { ++ ScDocument* pDoc = pViewData->GetDocument(); ++ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); ++ ++ if (!pDrawLayer->isTiledRendering()) ++ return; ++ ++ SCCOL nX = pViewData->GetCurX(); ++ SCROW nY = pViewData->GetCurY(); ++ Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true ); ++ ++ long nSizeXPix; ++ long nSizeYPix; ++ pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); ++ ++ double fPPTX = pViewData->GetPPTX(); ++ double fPPTY = pViewData->GetPPTY(); ++ Rectangle aRect(Point(aScrPos.getX() / fPPTX, aScrPos.getY() / fPPTY), ++ Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY)); ++ ++ pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, aRect.toString().getStr()); ++ ++} ++ + void ScGridWindow::CursorChanged() + { + // here the created OverlayObjects may be transformed in later versions. For + // now, just re-create them + + UpdateCursorOverlay(); ++ ++ updateLibreOfficeKitCellCursor(pViewData, eWhich); + } + + // #114409# +@@ -5942,9 +5967,8 @@ void ScGridWindow::UpdateCursorOverlay() + { + ScDocument* pDoc = pViewData->GetDocument(); + +- // never show the cell cursor when the tiled rendering is going on; either +- // we want to show the editeng selection, or the cell selection, but not +- // the cell cursor by itself ++ // The cursor is rendered client-side in tiled rendering - ++ // see updateLibreOfficeKitCellCursor. + if (pDoc->GetDrawLayer()->isTiledRendering()) + return; + +-- +2.12.0 + diff --git a/SOURCES/0277-sc-lok-Cache-viewdata-zoom-and-reuse-for-cursor-call.patch b/SOURCES/0277-sc-lok-Cache-viewdata-zoom-and-reuse-for-cursor-call.patch new file mode 100644 index 0000000..6c2fb1a --- /dev/null +++ b/SOURCES/0277-sc-lok-Cache-viewdata-zoom-and-reuse-for-cursor-call.patch @@ -0,0 +1,124 @@ +From a8b236d905a757af8028cc8ed14bbc7144e41072 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Mon, 2 Nov 2015 13:24:12 +0100 +Subject: [PATCH 277/398] sc lok: Cache viewdata zoom and reuse for cursor + callback + +As of a1605d6860e3c4510177c42ab6d2fda569506f57 we reset the zoom +level to the default when processing LOK mouse events. The exact +cell cursor position is dependent on the zoom level (due to the +rounding in the cell position summing calculations), hence we need +to make sure we have the correct zoom level for those calculations +(or else the rounding errors will result in incorrect cell cursor +positions). Caching the zoom level and reusing it only here seems +to be the most efficient way of solving this for now. + +(An alternative would be to only send the cell ID in the callback, + and have the frontend then request the pixel positions together + with the current frontend zoom level - however especially for + LOOL minimising the number of trips is probably wise.) + +(cherry picked from commit fab3c48a0cd5a0517025993502a04358308fe5ef) + +Change-Id: Iae3aabfd7ea9bec7057be7b63670885766870c4f +--- + sc/source/ui/inc/gridwin.hxx | 10 ++++++++++ + sc/source/ui/view/gridwin.cxx | 12 +++++++++--- + sc/source/ui/view/gridwin4.cxx | 6 +++--- + 3 files changed, 22 insertions(+), 6 deletions(-) + +diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx +index b8425a8e34c3..747ce88c2038 100644 +--- a/sc/source/ui/inc/gridwin.hxx ++++ b/sc/source/ui/inc/gridwin.hxx +@@ -200,6 +200,15 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou + bool bAutoMarkVisible:1; + bool bListValButton:1; + ++ // We cache the tiled rendering zoom level in order to be able to ++ // calculate the correct cell cursor position (which is dependent ++ // on the zoom level). The caching is necessary since ++ // ScModelObj::postMouseEvent resets the zoom level to the default, ++ // which means we have the default zoom level set during the ++ // cell cursor position calculations in updateLibreOfficeKitCellCursor(). ++ Fraction mTiledZoomX; ++ Fraction mTiledZoomY; ++ + DECL_LINK( PopupModeEndHdl, void* ); + DECL_LINK( PopupSpellingHdl, SpellCallbackInfo* ); + +@@ -292,6 +301,7 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou + + void GetSelectionRects( ::std::vector< Rectangle >& rPixelRects ); + ++ void updateLibreOfficeKitCellCursor(); + protected: + virtual void PrePaint(vcl::RenderContext& rRenderContext) SAL_OVERRIDE; + virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE; +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index 7ab88c6c0eb1..dd958e519249 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -5782,7 +5782,7 @@ bool ScGridWindow::InsideVisibleRange( SCCOL nPosX, SCROW nPosY ) + return maVisibleRange.isInside(nPosX, nPosY); + } + +-static void updateLibreOfficeKitCellCursor(ScViewData* pViewData, ScSplitPos eWhich) { ++void ScGridWindow::updateLibreOfficeKitCellCursor() { + ScDocument* pDoc = pViewData->GetDocument(); + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); + +@@ -5791,8 +5791,12 @@ static void updateLibreOfficeKitCellCursor(ScViewData* pViewData, ScSplitPos eWh + + SCCOL nX = pViewData->GetCurX(); + SCROW nY = pViewData->GetCurY(); +- Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true ); + ++ Fraction defaultZoomX = pViewData->GetZoomX(); ++ Fraction defaultZoomY = pViewData->GetZoomX(); ++ pViewData->SetZoom(mTiledZoomX, mTiledZoomY, true); ++ ++ Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true ); + long nSizeXPix; + long nSizeYPix; + pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); +@@ -5802,6 +5806,8 @@ static void updateLibreOfficeKitCellCursor(ScViewData* pViewData, ScSplitPos eWh + Rectangle aRect(Point(aScrPos.getX() / fPPTX, aScrPos.getY() / fPPTY), + Size(nSizeXPix / fPPTX, nSizeYPix / fPPTY)); + ++ pViewData->SetZoom(defaultZoomX, defaultZoomY, true); ++ + pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, aRect.toString().getStr()); + + } +@@ -5813,7 +5819,7 @@ void ScGridWindow::CursorChanged() + + UpdateCursorOverlay(); + +- updateLibreOfficeKitCellCursor(pViewData, eWhich); ++ updateLibreOfficeKitCellCursor(); + } + + // #114409# +diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx +index ceaf3d8d7c3a..cfdde43e1a04 100644 +--- a/sc/source/ui/view/gridwin4.cxx ++++ b/sc/source/ui/view/gridwin4.cxx +@@ -955,11 +955,11 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice, + // Similarly to Writer, we should set the mapmode once on the rDevice, and + // not care about any zoom settings. + +- Fraction aFracX(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth); +- Fraction aFracY(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight); ++ mTiledZoomX = Fraction(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth); ++ mTiledZoomY = Fraction(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight); + + // page break zoom, and aLogicMode in ScViewData +- pViewData->SetZoom(aFracX, aFracY, true); ++ pViewData->SetZoom(mTiledZoomX, mTiledZoomY, true); + + double fTilePosXPixel = static_cast(nTilePosX) * nOutputWidth / nTileWidth; + double fTilePosYPixel = static_cast(nTilePosY) * nOutputHeight / nTileHeight; +-- +2.12.0 + diff --git a/SOURCES/0278-sc-lok-make-cell-cursor-behaviour-consistent-with-de.patch b/SOURCES/0278-sc-lok-make-cell-cursor-behaviour-consistent-with-de.patch new file mode 100644 index 0000000..02ee28c --- /dev/null +++ b/SOURCES/0278-sc-lok-make-cell-cursor-behaviour-consistent-with-de.patch @@ -0,0 +1,150 @@ +From 21fcedc3a2989b6b979296164f014b59ae74d450 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 3 Nov 2015 10:14:02 +0100 +Subject: [PATCH 278/398] sc lok: make cell cursor behaviour consistent with + desktop + +I.e. single click selects cell, typing activates the EditView +(and hides the cell cursor). (Previously: single click activates +the edit view, text cursor is shown, and no clean way of hiding +the cell cursor again.) + +(cherry picked from commit f859dac52e40759fb8202d891df4e1442bc35803) + +Change-Id: I184630277e8935e9f8a97a856191497ec5d62111 +--- + sc/source/ui/view/gridwin.cxx | 75 +++++++++++++++++++++++-------------------- + 1 file changed, 40 insertions(+), 35 deletions(-) + +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index dd958e519249..daca987b14b2 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -2412,7 +2412,9 @@ void ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt ) + bEditAllowed = false; + } + +- if ( bEditAllowed ) ++ // We don't want to activate the edit view for a single click in tiled rendering ++ // (but we should probably keep the same behaviour for double clicks). ++ if ( bEditAllowed && (!bIsTiledRendering || bDouble) ) + { + // don't forward the event to an empty cell, causes deselection in + // case we used the double-click to select the empty cell +@@ -5809,7 +5811,6 @@ void ScGridWindow::updateLibreOfficeKitCellCursor() { + pViewData->SetZoom(defaultZoomX, defaultZoomY, true); + + pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, aRect.toString().getStr()); +- + } + + void ScGridWindow::CursorChanged() +@@ -5818,8 +5819,6 @@ void ScGridWindow::CursorChanged() + // now, just re-create them + + UpdateCursorOverlay(); +- +- updateLibreOfficeKitCellCursor(); + } + + // #114409# +@@ -5856,6 +5855,9 @@ void ScGridWindow::UpdateAllOverlays() + + void ScGridWindow::DeleteCursorOverlay() + { ++ ScDocument* pDoc = pViewData->GetDocument(); ++ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); ++ pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, "EMPTY"); + mpOOCursors.reset(); + } + +@@ -5973,11 +5975,6 @@ void ScGridWindow::UpdateCursorOverlay() + { + ScDocument* pDoc = pViewData->GetDocument(); + +- // The cursor is rendered client-side in tiled rendering - +- // see updateLibreOfficeKitCellCursor. +- if (pDoc->GetDrawLayer()->isTiledRendering()) +- return; +- + MapMode aDrawMode = GetDrawMapMode(); + MapMode aOldMode = GetMapMode(); + if ( aOldMode != aDrawMode ) +@@ -6096,40 +6093,48 @@ void ScGridWindow::UpdateCursorOverlay() + } + } + ++ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); ++ + if ( !aPixelRects.empty() ) + { +- // #i70788# get the OverlayManager safely +- rtl::Reference xOverlayManager = getOverlayManager(); +- +- if (xOverlayManager.is()) ++ if (pDrawLayer->isTiledRendering()) { ++ updateLibreOfficeKitCellCursor(); ++ } ++ else + { +- Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); +- if (pViewData->GetActivePart() != eWhich) +- // non-active pane uses a different color. +- aCursorColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor; +- std::vector< basegfx::B2DRange > aRanges; +- const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); ++ // #i70788# get the OverlayManager safely ++ rtl::Reference xOverlayManager = getOverlayManager(); + +- for(sal_uInt32 a(0); a < aPixelRects.size(); a++) ++ if (xOverlayManager.is()) + { +- const Rectangle aRA(aPixelRects[a]); +- basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); +- aRB.transform(aTransform); +- aRanges.push_back(aRB); +- } ++ Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); ++ if (pViewData->GetActivePart() != eWhich) ++ // non-active pane uses a different color. ++ aCursorColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor; ++ std::vector< basegfx::B2DRange > aRanges; ++ const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); ++ ++ for(size_t a(0); a < aPixelRects.size(); a++) ++ { ++ const Rectangle aRA(aPixelRects[a]); ++ basegfx::B2DRange aRB(aRA.Left(), aRA.Top(), aRA.Right() + 1, aRA.Bottom() + 1); ++ aRB.transform(aTransform); ++ aRanges.push_back(aRB); ++ } + +- sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( +- sdr::overlay::OVERLAY_SOLID, +- aCursorColor, +- aRanges, +- false); ++ sdr::overlay::OverlayObject* pOverlay = new sdr::overlay::OverlaySelection( ++ sdr::overlay::OVERLAY_SOLID, ++ aCursorColor, ++ aRanges, ++ false); + +- xOverlayManager->add(*pOverlay); +- mpOOCursors.reset(new sdr::overlay::OverlayObjectList); +- mpOOCursors->append(*pOverlay); ++ xOverlayManager->add(*pOverlay); ++ mpOOCursors.reset(new sdr::overlay::OverlayObjectList); ++ mpOOCursors->append(*pOverlay); + +- // notify the LibreOfficeKit too +- updateLibreOfficeKitSelection(pViewData, pDoc->GetDrawLayer(), aPixelRects); ++ // notify the LibreOfficeKit too ++ updateLibreOfficeKitSelection(pViewData, pDoc->GetDrawLayer(), aPixelRects); ++ } + } + } + +-- +2.12.0 + diff --git a/SOURCES/0279-sc-lok-tdf-94605-introduce-uno-CellCursor.patch b/SOURCES/0279-sc-lok-tdf-94605-introduce-uno-CellCursor.patch new file mode 100644 index 0000000..1ceca1a --- /dev/null +++ b/SOURCES/0279-sc-lok-tdf-94605-introduce-uno-CellCursor.patch @@ -0,0 +1,259 @@ +From 07f52f4e37afec5952dc42a9cafbcaac9c2152ae Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Wed, 4 Nov 2015 17:24:15 +0100 +Subject: [PATCH 279/398] sc lok: tdf#94605 introduce uno:CellCursor + +This allows the client to rerequest the current cursor position, +which is necessary e.g. on zoom-level changes. + +Conflicts: + desktop/source/lib/init.cxx + sc/inc/docuno.hxx + +Change-Id: I10d81e220a56a36e2ec0c59005cd1d4f134857d5 +(cherry picked from commit 2bcaffd12263e8f3c2a2fbf8ccc4b9bba2642146) +--- + desktop/source/lib/init.cxx | 43 ++++++++++++++++++++++++++++++++++++++++ + include/vcl/ITiledRenderable.hxx | 12 +++++++++++ + sc/inc/docuno.hxx | 6 ++++++ + sc/source/ui/inc/gridwin.hxx | 9 +++++++++ + sc/source/ui/unoobj/docuno.cxx | 17 ++++++++++++++++ + sc/source/ui/view/gridwin.cxx | 36 ++++++++++++++++++++++++++++----- + 6 files changed, 118 insertions(+), 5 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index bf244cd7aefa..3ca554d7e6f9 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -1208,6 +1209,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + { + OString aCommand(pCommand); + static const OString aViewRowColumnHeaders(".uno:ViewRowColumnHeaders"); ++ static const OString aCellCursor(".uno:CellCursor"); + + if (!strcmp(pCommand, ".uno:CharFontName")) + { +@@ -1266,6 +1268,47 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + + OUString aHeaders = pDoc->getRowColumnHeaders(aRectangle); + OString aString = OUStringToOString(aHeaders, RTL_TEXTENCODING_UTF8); ++ ++ char* pMemory = static_cast(malloc(aString.getLength() + 1)); ++ strcpy(pMemory, aString.getStr()); ++ return pMemory; ++ } ++ else if (aCommand.startsWith(aCellCursor) ++ { ++ ITiledRenderable* pDoc = getTiledRenderable(pThis); ++ if (!pDoc) ++ { ++ gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; ++ return 0; ++ } ++ ++ OString aString; ++ OString aParams = aCommand.copy(OString(".uno:CellCursor:").getLength()); ++ ++ sal_Int32 nIndex = 0; ++ OString aOutputWidth = aParams.getToken(0, ',', nIndex); ++ OString aOutputHeight = aParams.getToken(0, ',', nIndex); ++ OString aTileWidth = aParams.getToken(0, ',', nIndex); ++ OString aTileHeight = aParams.getToken(0, ',', nIndex); ++ ++ int nOutputWidth, nOutputHeight; ++ long nTileWidth, nTileHeight; ++ if (!(comphelper::string::getTokenCount(aParams, ',') == 4 ++ && !aOutputWidth.isEmpty() ++ && (nOutputWidth = aOutputWidth.toInt32()) != 0 ++ && !aOutputHeight.isEmpty() ++ && (nOutputHeight = aOutputHeight.toInt32()) != 0 ++ && !aTileWidth.isEmpty() ++ && (nTileWidth = aTileWidth.toInt64()) != 0 ++ && !aTileHeight.isEmpty() ++ && (nTileHeight = aTileHeight.toInt64()) != 0)) ++ { ++ gImpl->maLastExceptionMsg = "Can't parse arguments for .uno:CellCursor, no cursor returned"; ++ return NULL; ++ } ++ ++ OString aString = pDoc->getCellCursor(nOutputWidth, nOutputHeight, nTileWidth, nTileHeight); ++ + char* pMemory = static_cast(malloc(aString.getLength() + 1)); + strcpy(pMemory, aString.getStr()); + return pMemory; +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index efa9bc272b40..963f1fc7054a 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -159,6 +159,18 @@ public: + return OUString(); + } + ++ /** ++ * Get position and size of cell cursor in Calc. ++ * (This could maybe also be used for tables in Writer/Impress in future?) ++ */ ++ virtual OString getCellCursor(int /*nOutputWidth*/, ++ int /*nOutputHeight*/, ++ long /*nTileWidth*/, ++ long /*nTileHeight*/) ++ { ++ return OString(); ++ } ++ + /// Sets the clipboard of the component. + virtual void setClipboard(const css::uno::Reference& xClipboard) = 0; + +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index 828fc1af7ea0..70f61ca03548 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -424,6 +424,12 @@ public: + + /// @see vcl::ITiledRenderable::getRowColumnHeaders(). + virtual OUString getRowColumnHeaders(const Rectangle& rRectangle) override; ++ ++ /// @see vcl::ITiledRenderable::getCellCursor(). ++ virtual OString getCellCursor( int nOutputWidth, ++ int nOutputHeight, ++ long nTileWidth, ++ long nTileHeight ) override; + }; + + class ScDrawPagesObj : public cppu::WeakImplHelper2< +diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx +index 747ce88c2038..8081f107409c 100644 +--- a/sc/source/ui/inc/gridwin.hxx ++++ b/sc/source/ui/inc/gridwin.hxx +@@ -301,6 +301,7 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou + + void GetSelectionRects( ::std::vector< Rectangle >& rPixelRects ); + ++ + void updateLibreOfficeKitCellCursor(); + protected: + virtual void PrePaint(vcl::RenderContext& rRenderContext) SAL_OVERRIDE; +@@ -445,6 +446,14 @@ public: + void UpdateShrinkOverlay(); + void UpdateAllOverlays(); + ++ /// @see ScModelObj::getCellCursor(). ++ OString getCellCursor(const Fraction& rZoomX, ++ const Fraction& rZoomY); ++ OString getCellCursor(int nOutputWidth, ++ int nOutputHeight, ++ long nTileWidth, ++ long nTileHeight); ++ + protected: + // #114409# + void ImpCreateOverlayObjects(); +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index 1316fd73d328..66794f3c6f27 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -886,6 +886,23 @@ OUString ScModelObj::getRowColumnHeaders(const Rectangle& rRectangle) + return pTabView->getRowColumnHeaders(rRectangle); + } + ++OString ScModelObj::getCellCursor( int nOutputWidth, int nOutputHeight, ++ long nTileWidth, long nTileHeight ) ++{ ++ SolarMutexGuard aGuard; ++ ++ ScViewData* pViewData = ScDocShell::GetViewData(); ++ ++ if (!pViewData) ++ return OString(); ++ ++ ScGridWindow* pGridWindow = pViewData->GetActiveWin(); ++ if (!pGridWindow) ++ return OString(); ++ ++ return "{ \"commandName\": \".uno:CellCursor\", \"commandValues\": \"" + pGridWindow->getCellCursor( nOutputWidth, nOutputHeight, nTileWidth, nTileHeight ) + "\" }"; ++} ++ + void ScModelObj::initializeForTiledRendering() + { + SolarMutexGuard aGuard; +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index daca987b14b2..efa8d332ad2a 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -5784,19 +5784,36 @@ bool ScGridWindow::InsideVisibleRange( SCCOL nPosX, SCROW nPosY ) + return maVisibleRange.isInside(nPosX, nPosY); + } + +-void ScGridWindow::updateLibreOfficeKitCellCursor() { ++// Use the same zoom calculations as in paintTile - this ++// means the client can ensure they can get the correct ++// cursor corresponding to their current tile sizings. ++OString ScGridWindow::getCellCursor( int nOutputWidth, int nOutputHeight, ++ long nTileWidth, long nTileHeight ) ++{ ++ Fraction zoomX = Fraction(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth); ++ Fraction zoomY = Fraction(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight); ++ return getCellCursor(zoomX, zoomY); ++} ++ ++OString ScGridWindow::getCellCursor(const Fraction& rZoomX, const Fraction& rZoomY) { + ScDocument* pDoc = pViewData->GetDocument(); + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); + +- if (!pDrawLayer->isTiledRendering()) +- return; ++ // GridWindows stores a shown cell cursor in mpOOCursors, hence ++ // we can use that to determine whether we would want to be showing ++ // one (client-side) for tiled rendering too. ++ if (!pDrawLayer->isTiledRendering() || !mpOOCursors.get()) ++ { ++ return OString("EMPTY"); ++ } + + SCCOL nX = pViewData->GetCurX(); + SCROW nY = pViewData->GetCurY(); + + Fraction defaultZoomX = pViewData->GetZoomX(); + Fraction defaultZoomY = pViewData->GetZoomX(); +- pViewData->SetZoom(mTiledZoomX, mTiledZoomY, true); ++ ++ pViewData->SetZoom(rZoomX, rZoomY, true); + + Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, true ); + long nSizeXPix; +@@ -5810,7 +5827,15 @@ void ScGridWindow::updateLibreOfficeKitCellCursor() { + + pViewData->SetZoom(defaultZoomX, defaultZoomY, true); + +- pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, aRect.toString().getStr()); ++ return aRect.toString(); ++} ++ ++void ScGridWindow::updateLibreOfficeKitCellCursor() ++{ ++ ScDocument* pDoc = pViewData->GetDocument(); ++ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); ++ OString aCursor = getCellCursor(mTiledZoomX, mTiledZoomY); ++ pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, aCursor.getStr()); + } + + void ScGridWindow::CursorChanged() +@@ -6098,6 +6123,7 @@ void ScGridWindow::UpdateCursorOverlay() + if ( !aPixelRects.empty() ) + { + if (pDrawLayer->isTiledRendering()) { ++ mpOOCursors.reset(new sdr::overlay::OverlayObjectList); + updateLibreOfficeKitCellCursor(); + } + else +-- +2.12.0 + diff --git a/SOURCES/0280-sc-lok-update-parameter-syntax-for-.uno-CellCursor.patch b/SOURCES/0280-sc-lok-update-parameter-syntax-for-.uno-CellCursor.patch new file mode 100644 index 0000000..7b462af --- /dev/null +++ b/SOURCES/0280-sc-lok-update-parameter-syntax-for-.uno-CellCursor.patch @@ -0,0 +1,93 @@ +From 01e6ce0c2286016e7a8459d1f0d865b49765f585 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Thu, 5 Nov 2015 10:31:06 +0100 +Subject: [PATCH 280/398] sc lok: update parameter syntax for .uno:CellCursor + +This follows the syntax for .uno:ViewRowColumnHeaders +(which was implemented somewhat concurrentl with CellCursor) + +Change-Id: I8ef03a969abc1716a0e95d95fb7043d75910c828 +(cherry picked from commit e7e0d46dba7b1016968a133330bca23a4bf668ec) +--- + desktop/source/lib/init.cxx | 57 +++++++++++++++++++++++++++------------------ + 1 file changed, 34 insertions(+), 23 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 3ca554d7e6f9..2e6e7e73df1a 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1273,7 +1273,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + strcpy(pMemory, aString.getStr()); + return pMemory; + } +- else if (aCommand.startsWith(aCellCursor) ++ else if (aCommand.startsWith(aCellCursor)) + { + ITiledRenderable* pDoc = getTiledRenderable(pThis); + if (!pDoc) +@@ -1282,29 +1282,40 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + return 0; + } + +- OString aString; +- OString aParams = aCommand.copy(OString(".uno:CellCursor:").getLength()); +- +- sal_Int32 nIndex = 0; +- OString aOutputWidth = aParams.getToken(0, ',', nIndex); +- OString aOutputHeight = aParams.getToken(0, ',', nIndex); +- OString aTileWidth = aParams.getToken(0, ',', nIndex); +- OString aTileHeight = aParams.getToken(0, ',', nIndex); +- +- int nOutputWidth, nOutputHeight; +- long nTileWidth, nTileHeight; +- if (!(comphelper::string::getTokenCount(aParams, ',') == 4 +- && !aOutputWidth.isEmpty() +- && (nOutputWidth = aOutputWidth.toInt32()) != 0 +- && !aOutputHeight.isEmpty() +- && (nOutputHeight = aOutputHeight.toInt32()) != 0 +- && !aTileWidth.isEmpty() +- && (nTileWidth = aTileWidth.toInt64()) != 0 +- && !aTileHeight.isEmpty() +- && (nTileHeight = aTileHeight.toInt64()) != 0)) ++ // Command has parameters. ++ int nOutputWidth = 0; ++ int nOutputHeight = 0; ++ long nTileWidth = 0; ++ long nTileHeight = 0; ++ if (aCommand.getLength() > aCellCursor.getLength()) + { +- gImpl->maLastExceptionMsg = "Can't parse arguments for .uno:CellCursor, no cursor returned"; +- return NULL; ++ OString aArguments = aCommand.copy(aCellCursor.getLength() + 1); ++ sal_Int32 nParamIndex = 0; ++ do ++ { ++ OString aParamToken = aArguments.getToken(0, '&', nParamIndex); ++ sal_Int32 nIndex = 0; ++ OString aKey; ++ OString aValue; ++ do ++ { ++ OString aToken = aParamToken.getToken(0, '=', nIndex); ++ if (!aKey.getLength()) ++ aKey = aToken; ++ else ++ aValue = aToken; ++ } ++ while (nIndex >= 0); ++ if (aKey == "outputWidth") ++ nOutputWidth = aValue.toInt32(); ++ else if (aKey == "outputHeight") ++ nOutputHeight = aValue.toInt32(); ++ else if (aKey == "tileWidth") ++ nTileWidth = aValue.toInt64(); ++ else if (aKey == "tileHeight") ++ nTileHeight = aValue.toInt64(); ++ } ++ while (nParamIndex >= 0); + } + + OString aString = pDoc->getCellCursor(nOutputWidth, nOutputHeight, nTileWidth, nTileHeight); +-- +2.12.0 + diff --git a/SOURCES/0281-sw-tiled-rendering-initial-annotation-support.patch b/SOURCES/0281-sw-tiled-rendering-initial-annotation-support.patch new file mode 100644 index 0000000..b7525fe --- /dev/null +++ b/SOURCES/0281-sw-tiled-rendering-initial-annotation-support.patch @@ -0,0 +1,197 @@ +From 610c160a9762e222182af0de12972fa0924954fd Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 5 Nov 2015 15:58:55 +0100 +Subject: [PATCH 281/398] sw tiled rendering: initial annotation support + +(cherry picked from commit d54aaea33bf2dab86c0ead4bd142c593d017f930) + +Change-Id: I4fcb05f8a58965341cf44a1b7e2367b5cbff981d +--- + sw/inc/PostItMgr.hxx | 3 ++- + sw/inc/SidebarWin.hxx | 3 ++- + sw/source/core/view/viewsh.cxx | 3 +++ + sw/source/uibase/docvw/PostItMgr.cxx | 15 +++++++++++++++ + sw/source/uibase/docvw/SidebarTxtControl.cxx | 20 +++++++++++++++++--- + sw/source/uibase/docvw/SidebarTxtControl.hxx | 3 ++- + sw/source/uibase/docvw/SidebarWin.cxx | 22 +++++++++++++++++++++- + 7 files changed, 62 insertions(+), 7 deletions(-) + +diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx +index 8d1ddd0d65f8..f306f57ba86c 100644 +--- a/sw/inc/PostItMgr.hxx ++++ b/sw/inc/PostItMgr.hxx +@@ -287,7 +287,8 @@ class SwPostItMgr: public SfxListener + void GetAllSidebarWinForFrm( const SwFrm& rFrm, + std::vector< vcl::Window* >* pChildren ); + +- void DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage); ++ void DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage); ++ void PaintTile(OutputDevice& rRenderContext, const Rectangle& rRect); + }; + + #endif +diff --git a/sw/inc/SidebarWin.hxx b/sw/inc/SidebarWin.hxx +index 9514ac0eca90..d21d50d5d7d5 100644 +--- a/sw/inc/SidebarWin.hxx ++++ b/sw/inc/SidebarWin.hxx +@@ -177,7 +177,8 @@ class SwSidebarWin : public vcl::Window + void ChangeSidebarItem( SwSidebarItem& rSidebarItem ); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE; + +- virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) SAL_OVERRIDE; ++ virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) override; ++ void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); + + protected: + virtual void DataChanged( const DataChangedEvent& aEvent) SAL_OVERRIDE; +diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx +index 92480b242089..fad9dc3552db 100644 +--- a/sw/source/core/view/viewsh.cxx ++++ b/sw/source/core/view/viewsh.cxx +@@ -1895,6 +1895,9 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex + // draw - works in logic coordinates + Paint(rDevice, aOutRect); + ++ if (SwPostItMgr* pPostItMgr = GetPostItMgr()) ++ pPostItMgr->PaintTile(rDevice, aOutRect); ++ + // SwViewShell's output device tear down + mpOut = pSaveOut; + mbInLibreOfficeKitCallback = false; +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index 98a98964dbd9..b6bc52c253d0 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -847,6 +847,21 @@ void SwPostItMgr::DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage) + } + } + ++void SwPostItMgr::PaintTile(OutputDevice& rRenderContext, const Rectangle& /*rRect*/) ++{ ++ for (SwSidebarItem* pItem : mvPostItFields) ++ { ++ SwSidebarWin* pPostIt = pItem->pPostIt; ++ if (!pPostIt) ++ continue; ++ ++ Point aPoint(mpEditWin->PixelToLogic(pPostIt->GetPosPixel())); ++ Size aSize(pPostIt->PixelToLogic(pPostIt->GetSizePixel())); ++ Rectangle aRectangle(aPoint, aSize); ++ pPostIt->PaintTile(rRenderContext, aRectangle); ++ } ++} ++ + void SwPostItMgr::Scroll(const long lScroll,const unsigned long aPage) + { + OSL_ENSURE((lScroll % GetScrollSize() )==0,"SwPostItMgr::Scroll: scrolling by wrong value"); +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.cxx b/sw/source/uibase/docvw/SidebarTxtControl.cxx +index e9e1e34afdfe..06dcfea58ff6 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.cxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.cxx +@@ -53,6 +53,8 @@ + #include + #include + #include ++#include ++#include + + namespace sw { namespace sidebarwindows { + +@@ -151,25 +153,37 @@ void SidebarTextControl::Draw(OutputDevice* pDev, const Point& rPt, const Size& + } + } + ++void SidebarTextControl::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect) ++{ ++ Paint(rRenderContext, rRect); ++} ++ + void SidebarTextControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) + { ++ Point aPoint(0, 0); ++ if (comphelper::LibreOfficeKit::isActive()) ++ aPoint = rRect.TopLeft(); ++ + if (!rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode()) + { + if (mrSidebarWin.IsMouseOverSidebarWin() || HasFocus()) + { +- rRenderContext.DrawGradient(Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())), ++ rRenderContext.DrawGradient(Rectangle(aPoint, rRenderContext.PixelToLogic(GetSizePixel())), + Gradient(GradientStyle_LINEAR, mrSidebarWin.ColorDark(), mrSidebarWin.ColorDark())); + } + else + { +- rRenderContext.DrawGradient(Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())), ++ rRenderContext.DrawGradient(Rectangle(aPoint, rRenderContext.PixelToLogic(GetSizePixel())), + Gradient(GradientStyle_LINEAR, mrSidebarWin.ColorLight(), mrSidebarWin.ColorDark())); + } + } + + if (GetTextView()) + { +- GetTextView()->Paint(rRect, &rRenderContext); ++ if (comphelper::LibreOfficeKit::isActive()) ++ GetTextView()->GetOutliner()->Draw(&rRenderContext, rRect); ++ else ++ GetTextView()->Paint(rRect, &rRenderContext); + } + + if (mrSidebarWin.GetLayoutStatus() == SwPostItHelper::DELETED) +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.hxx b/sw/source/uibase/docvw/SidebarTxtControl.hxx +index 1a6d6677cd43..df732434ecf5 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.hxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.hxx +@@ -68,7 +68,8 @@ class SidebarTextControl : public Control + + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE; + +- virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) SAL_OVERRIDE; ++ virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) override; ++ void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); + }; + + } } // end of namespace sw::sidebarwindows +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 9825839ecf33..45916b03f797 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -80,6 +80,8 @@ + #include + #include + #include ++#include ++#include + + namespace sw { namespace sidebarwindows { + +@@ -230,7 +232,25 @@ void SwSidebarWin::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rR + Size(GetMetaButtonAreaWidth(), + mpMetadataAuthor->GetSizePixel().Height() + mpMetadataDate->GetSizePixel().Height())); + +- rRenderContext.DrawRect(PixelToLogic(aRectangle)); ++ if (comphelper::LibreOfficeKit::isActive()) ++ aRectangle = rRect; ++ else ++ aRectangle = PixelToLogic(aRectangle); ++ rRenderContext.DrawRect(aRectangle); ++ } ++} ++ ++void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect) ++{ ++ Paint(rRenderContext, rRect); ++ ++ for (sal_uInt16 i = 0; i < GetChildCount(); ++i) ++ { ++ vcl::Window* pChild = GetChild(i); ++ if (pChild == mpSidebarTextControl.get()) ++ mpSidebarTextControl->PaintTile(rRenderContext, rRect); ++ else ++ SAL_WARN("sw.uibase", "SwSidebarWin::PaintTile: unhandled child " << pChild); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0282-sw-lok-annotations-paint-all-child-window.patch b/SOURCES/0282-sw-lok-annotations-paint-all-child-window.patch new file mode 100644 index 0000000..0dcef3a --- /dev/null +++ b/SOURCES/0282-sw-lok-annotations-paint-all-child-window.patch @@ -0,0 +1,134 @@ +From 141f83a0f86de000c2ad25b207fdd6b0684a1c70 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 6 Nov 2015 10:29:38 +0100 +Subject: [PATCH 282/398] sw lok annotations: paint all child window + +And use map modes to get the painting to the correct position instead of +manually adjusting each and every Paint() method. + +(cherry picked from commit 177e375d2e63f1c3db9f5ab41e4281af740625fb) + +Change-Id: I66798321b8bbf2c7968d6ac1edebb1f8df60bce8 +--- + sw/source/uibase/docvw/PostItMgr.cxx | 11 +++++++++-- + sw/source/uibase/docvw/SidebarTxtControl.cxx | 19 +++---------------- + sw/source/uibase/docvw/SidebarTxtControl.hxx | 1 - + sw/source/uibase/docvw/SidebarWin.cxx | 13 +++++++++---- + 4 files changed, 21 insertions(+), 23 deletions(-) + +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index b6bc52c253d0..35152d05d242 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -855,10 +855,17 @@ void SwPostItMgr::PaintTile(OutputDevice& rRenderContext, const Rectangle& /*rRe + if (!pPostIt) + continue; + +- Point aPoint(mpEditWin->PixelToLogic(pPostIt->GetPosPixel())); ++ rRenderContext.Push(PushFlags::MAPMODE); ++ Point aOffset(mpEditWin->PixelToLogic(pPostIt->GetPosPixel())); ++ MapMode aMapMode(rRenderContext.GetMapMode()); ++ aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset); ++ rRenderContext.SetMapMode(aMapMode); + Size aSize(pPostIt->PixelToLogic(pPostIt->GetSizePixel())); +- Rectangle aRectangle(aPoint, aSize); ++ Rectangle aRectangle(Point(0, 0), aSize); ++ + pPostIt->PaintTile(rRenderContext, aRectangle); ++ ++ rRenderContext.Pop(); + } + } + +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.cxx b/sw/source/uibase/docvw/SidebarTxtControl.cxx +index 06dcfea58ff6..afda8b1952ad 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.cxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.cxx +@@ -54,7 +54,6 @@ + #include + #include + #include +-#include + + namespace sw { namespace sidebarwindows { + +@@ -153,37 +152,25 @@ void SidebarTextControl::Draw(OutputDevice* pDev, const Point& rPt, const Size& + } + } + +-void SidebarTextControl::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect) +-{ +- Paint(rRenderContext, rRect); +-} +- + void SidebarTextControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) + { +- Point aPoint(0, 0); +- if (comphelper::LibreOfficeKit::isActive()) +- aPoint = rRect.TopLeft(); +- + if (!rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode()) + { + if (mrSidebarWin.IsMouseOverSidebarWin() || HasFocus()) + { +- rRenderContext.DrawGradient(Rectangle(aPoint, rRenderContext.PixelToLogic(GetSizePixel())), ++ rRenderContext.DrawGradient(Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())), + Gradient(GradientStyle_LINEAR, mrSidebarWin.ColorDark(), mrSidebarWin.ColorDark())); + } + else + { +- rRenderContext.DrawGradient(Rectangle(aPoint, rRenderContext.PixelToLogic(GetSizePixel())), ++ rRenderContext.DrawGradient(Rectangle(Point(0,0), rRenderContext.PixelToLogic(GetSizePixel())), + Gradient(GradientStyle_LINEAR, mrSidebarWin.ColorLight(), mrSidebarWin.ColorDark())); + } + } + + if (GetTextView()) + { +- if (comphelper::LibreOfficeKit::isActive()) +- GetTextView()->GetOutliner()->Draw(&rRenderContext, rRect); +- else +- GetTextView()->Paint(rRect, &rRenderContext); ++ GetTextView()->Paint(rRect, &rRenderContext); + } + + if (mrSidebarWin.GetLayoutStatus() == SwPostItHelper::DELETED) +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.hxx b/sw/source/uibase/docvw/SidebarTxtControl.hxx +index df732434ecf5..1be8ab3b8b4a 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.hxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.hxx +@@ -69,7 +69,6 @@ class SidebarTextControl : public Control + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE; + + virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) override; +- void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); + }; + + } } // end of namespace sw::sidebarwindows +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 45916b03f797..1d0374b7f92d 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -247,10 +247,15 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + for (sal_uInt16 i = 0; i < GetChildCount(); ++i) + { + vcl::Window* pChild = GetChild(i); +- if (pChild == mpSidebarTextControl.get()) +- mpSidebarTextControl->PaintTile(rRenderContext, rRect); +- else +- SAL_WARN("sw.uibase", "SwSidebarWin::PaintTile: unhandled child " << pChild); ++ rRenderContext.Push(PushFlags::MAPMODE); ++ Point aOffset(PixelToLogic(pChild->GetPosPixel())); ++ MapMode aMapMode(rRenderContext.GetMapMode()); ++ aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset); ++ rRenderContext.SetMapMode(aMapMode); ++ ++ pChild->Paint(rRenderContext, rRect); ++ ++ rRenderContext.Pop(); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0283-gtktiledviewer-larger-default-window-size.patch b/SOURCES/0283-gtktiledviewer-larger-default-window-size.patch new file mode 100644 index 0000000..60b9a41 --- /dev/null +++ b/SOURCES/0283-gtktiledviewer-larger-default-window-size.patch @@ -0,0 +1,29 @@ +From 99ddae57c6bd55b33a39eb728bb362ee56e85e81 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 6 Nov 2015 10:58:18 +0100 +Subject: [PATCH 283/398] gtktiledviewer: larger default window size + +So comments in an otherwise empty Writer doc are immediately visible. + +Change-Id: I189c4eff6e83274f609ce016f9610c307c47ff16 +(cherry picked from commit 2dba3c1b403e10f5725723193127c3e0fffd3d64) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 6ebd5bcc6ef5..08e756fa3ef6 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -902,7 +902,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + { + GtkWidget *pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW(pWindow), "LibreOfficeKit GTK Tiled Viewer"); +- gtk_window_set_default_size(GTK_WINDOW(pWindow), 1024, 768); ++ gtk_window_set_default_size(GTK_WINDOW(pWindow), 1280, 720); + g_signal_connect(pWindow, "destroy", G_CALLBACK(gtk_main_quit), 0); + + rWindow.m_pVBox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); +-- +2.12.0 + diff --git a/SOURCES/0284-sw-lok-annotations-disable-the-scrollbar-for-now.patch b/SOURCES/0284-sw-lok-annotations-disable-the-scrollbar-for-now.patch new file mode 100644 index 0000000..9cecb22 --- /dev/null +++ b/SOURCES/0284-sw-lok-annotations-disable-the-scrollbar-for-now.patch @@ -0,0 +1,31 @@ +From dd2f74e8a695449bc80a606b73c80ed023ebff0d Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 6 Nov 2015 13:30:54 +0100 +Subject: [PATCH 284/398] sw lok annotations: disable the scrollbar for now + +Change-Id: I7493eaab55c23c79ca0878c34a97dfb4af857260 +(cherry picked from commit 8fc6aafcb4769271bc7b208e9b9b430b875b6104) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 1d0374b7f92d..038bdb243e65 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -247,6 +247,12 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + for (sal_uInt16 i = 0; i < GetChildCount(); ++i) + { + vcl::Window* pChild = GetChild(i); ++ ++ // This would at the moment just draw a gray rectangle at the top right ++ // corner, need to sort out later. ++ if (pChild == mpVScrollbar.get()) ++ continue; ++ + rRenderContext.Push(PushFlags::MAPMODE); + Point aOffset(PixelToLogic(pChild->GetPosPixel())); + MapMode aMapMode(rRenderContext.GetMapMode()); +-- +2.12.0 + diff --git a/SOURCES/0285-sc-lok-annotations-paint-range-and-anchor-overlay.patch b/SOURCES/0285-sc-lok-annotations-paint-range-and-anchor-overlay.patch new file mode 100644 index 0000000..8ec0d55 --- /dev/null +++ b/SOURCES/0285-sc-lok-annotations-paint-range-and-anchor-overlay.patch @@ -0,0 +1,40 @@ +From 6c76b4b478428d2326ea672d1bd87d1fa9654797 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 6 Nov 2015 17:12:46 +0100 +Subject: [PATCH 285/398] sc lok annotations: paint range and anchor overlay + +Change-Id: I16e51e074704026a45471e7a08c3b96846d44053 +(cherry picked from commit 5f68759810496ff3fadf5a883203449772c7392f) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 038bdb243e65..e3e238715365 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -263,6 +263,21 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + + rRenderContext.Pop(); + } ++ ++ const drawinglayer::geometry::ViewInformation2D aViewInformation; ++ std::unique_ptr pProcessor(drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(rRenderContext, aViewInformation)); ++ ++ // drawinglayer sets the map mode to pixels, not needed here. ++ rRenderContext.Pop(); ++ // Work in document-global twips. ++ rRenderContext.Pop(); ++ if (mpAnchor) ++ pProcessor->process(mpAnchor->getOverlayObjectPrimitive2DSequence()); ++ if (mpTextRangeOverlay) ++ pProcessor->process(mpTextRangeOverlay->getOverlayObjectPrimitive2DSequence()); ++ rRenderContext.Push(PushFlags::NONE); ++ pProcessor.reset(); ++ rRenderContext.Push(PushFlags::NONE); + } + + void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, sal_uLong nInFlags) +-- +2.12.0 + diff --git a/SOURCES/0286-Revert-sc-lok-Cache-viewdata-zoom-and-reuse-for-curs.patch b/SOURCES/0286-Revert-sc-lok-Cache-viewdata-zoom-and-reuse-for-curs.patch new file mode 100644 index 0000000..ce3e2c5 --- /dev/null +++ b/SOURCES/0286-Revert-sc-lok-Cache-viewdata-zoom-and-reuse-for-curs.patch @@ -0,0 +1,82 @@ +From cc6294f25ba79ab1ad55f5cae600666eb8700d7b Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Fri, 6 Nov 2015 17:36:18 +0100 +Subject: [PATCH 286/398] Revert "sc lok: Cache viewdata zoom and reuse for + cursor callback" + +This reverts fab3c48a0cd5a0517025993502a04358308fe5ef for now. +The correct solution is to have the client "hint" at the current +resolution, which is still being developed +(gerrit-id: I34b5afcdcc06a671a8ac92c03e87404e42adf4cd). +For now the cursor will be wrongly positioned when moved as the result +of a mouse click. + +Reviewed-on: https://gerrit.libreoffice.org/19827 +Tested-by: Andrzej Hunt +Reviewed-by: Andrzej Hunt +(cherry picked from commit 064fb1f73abbc103226a8fce8a46b7e8b8347dac) + +Change-Id: I68d56eac958e607e8e2e3ad16aff4e1a7dd0b6dd +--- + sc/source/ui/inc/gridwin.hxx | 9 --------- + sc/source/ui/view/gridwin.cxx | 4 +++- + sc/source/ui/view/gridwin4.cxx | 6 +++--- + 3 files changed, 6 insertions(+), 13 deletions(-) + +diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx +index 8081f107409c..dc1cec7fd8c7 100644 +--- a/sc/source/ui/inc/gridwin.hxx ++++ b/sc/source/ui/inc/gridwin.hxx +@@ -200,15 +200,6 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou + bool bAutoMarkVisible:1; + bool bListValButton:1; + +- // We cache the tiled rendering zoom level in order to be able to +- // calculate the correct cell cursor position (which is dependent +- // on the zoom level). The caching is necessary since +- // ScModelObj::postMouseEvent resets the zoom level to the default, +- // which means we have the default zoom level set during the +- // cell cursor position calculations in updateLibreOfficeKitCellCursor(). +- Fraction mTiledZoomX; +- Fraction mTiledZoomY; +- + DECL_LINK( PopupModeEndHdl, void* ); + DECL_LINK( PopupSpellingHdl, SpellCallbackInfo* ); + +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index efa8d332ad2a..d6887b6f4e07 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -5834,7 +5834,9 @@ void ScGridWindow::updateLibreOfficeKitCellCursor() + { + ScDocument* pDoc = pViewData->GetDocument(); + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); +- OString aCursor = getCellCursor(mTiledZoomX, mTiledZoomY); ++ // TODO: the zoom levels here should be replaced by the setClientZoom values ++ // in a patch currently in gerrit (https://gerrit.libreoffice.org/#/c/19822/) ++ OString aCursor = getCellCursor(pViewData->GetZoomX(), pViewData->GetZoomY()); + pDrawLayer->libreOfficeKitCallback(LOK_CALLBACK_CELL_CURSOR, aCursor.getStr()); + } + +diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx +index cfdde43e1a04..ceaf3d8d7c3a 100644 +--- a/sc/source/ui/view/gridwin4.cxx ++++ b/sc/source/ui/view/gridwin4.cxx +@@ -955,11 +955,11 @@ void ScGridWindow::PaintTile( VirtualDevice& rDevice, + // Similarly to Writer, we should set the mapmode once on the rDevice, and + // not care about any zoom settings. + +- mTiledZoomX = Fraction(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth); +- mTiledZoomY = Fraction(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight); ++ Fraction aFracX(long(nOutputWidth * TWIPS_PER_PIXEL), nTileWidth); ++ Fraction aFracY(long(nOutputHeight * TWIPS_PER_PIXEL), nTileHeight); + + // page break zoom, and aLogicMode in ScViewData +- pViewData->SetZoom(mTiledZoomX, mTiledZoomY, true); ++ pViewData->SetZoom(aFracX, aFracY, true); + + double fTilePosXPixel = static_cast(nTilePosX) * nOutputWidth / nTileWidth; + double fTilePosYPixel = static_cast(nTilePosY) * nOutputHeight / nTileHeight; +-- +2.12.0 + diff --git a/SOURCES/0287-gtktiledviewer-add-Ctrl-Alt-Shift-shortcut-support.patch b/SOURCES/0287-gtktiledviewer-add-Ctrl-Alt-Shift-shortcut-support.patch new file mode 100644 index 0000000..0f4001f --- /dev/null +++ b/SOURCES/0287-gtktiledviewer-add-Ctrl-Alt-Shift-shortcut-support.patch @@ -0,0 +1,70 @@ +From 71ad9009f87480488f45f36888c0b08ce245220e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?L=C3=A1szl=C3=B3=20N=C3=A9meth?= + +Date: Fri, 6 Nov 2015 19:26:29 +0100 +Subject: [PATCH 287/398] gtktiledviewer: add Ctrl, Alt, Shift shortcut support + +For example in Writer: + +Ctrl-B for bold text +Ctrl-Shift-B/P for subscript/superscript +Ctrl-Alt-C insert comment +Ctrl-1 apply Heading 1 paragraph style + +Change-Id: Iaeb8341f2cb273980b637ff2fed89585094e0d9d +(cherry picked from commit 63d2d50ecb3f3a83374a1a01713edce14ba378ed) +--- + libreofficekit/source/gtk/lokdocview.cxx | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 73b01797dbf9..8f0a053677fa 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -337,7 +337,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + return FALSE; + } + +- priv->m_nKeyModifier = 0; ++ priv->m_nKeyModifier &= KEY_MOD2; + switch (pEvent->keyval) + { + case GDK_KEY_BackSpace: +@@ -381,6 +381,8 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + case GDK_KEY_Alt_R: + if (pEvent->type == GDK_KEY_PRESS) + priv->m_nKeyModifier |= KEY_MOD2; ++ else ++ priv->m_nKeyModifier &= ~KEY_MOD2; + break; + default: + if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26) +@@ -395,6 +397,25 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + if (pEvent->state & GDK_SHIFT_MASK) + nKeyCode |= KEY_SHIFT; + ++ if (pEvent->state & GDK_CONTROL_MASK) ++ nKeyCode |= KEY_MOD1; ++ ++ if (priv->m_nKeyModifier & KEY_MOD2) ++ nKeyCode |= KEY_MOD2; ++ ++ if (nKeyCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)) { ++ if (pEvent->keyval >= GDK_KEY_a && pEvent->keyval <= GDK_KEY_z) ++ { ++ nKeyCode |= 512 + (pEvent->keyval - GDK_KEY_a); ++ } ++ else if (pEvent->keyval >= GDK_KEY_A && pEvent->keyval <= GDK_KEY_Z) { ++ nKeyCode |= 512 + (pEvent->keyval - GDK_KEY_A); ++ } ++ else if (pEvent->keyval >= GDK_KEY_0 && pEvent->keyval <= GDK_KEY_9) { ++ nKeyCode |= 256 + (pEvent->keyval - GDK_KEY_0); ++ } ++ } ++ + if (pEvent->type == GDK_KEY_RELEASE) + { + GTask* task = g_task_new(pDocView, NULL, NULL, NULL); +-- +2.12.0 + diff --git a/SOURCES/0288-sc-lok-Add-initial-test-for-.uno-CellCursor.patch b/SOURCES/0288-sc-lok-Add-initial-test-for-.uno-CellCursor.patch new file mode 100644 index 0000000..b51547c --- /dev/null +++ b/SOURCES/0288-sc-lok-Add-initial-test-for-.uno-CellCursor.patch @@ -0,0 +1,88 @@ +From 605efe926ab66ddf5aa790051008c3ed35b9a0e9 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Fri, 6 Nov 2015 18:09:34 +0100 +Subject: [PATCH 288/398] sc lok: Add initial test for .uno:CellCursor + +This should be extended with checking that we receive "EMPTY" +when there is no cursor shown - that would require e.g. simulating +keyboard input to hide the cell cursor. + +Change-Id: Ia7be5ec3e158f21967b4c307ac10abb2b5e2a56a +Reviewed-on: https://gerrit.libreoffice.org/19828 +Tested-by: Jenkins +Reviewed-by: Andrzej Hunt +Tested-by: Andrzej Hunt +(cherry picked from commit 2f13f051c3c39f77d5f65ff0e3f4a476ccb95f1a) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 20 ++++++++++++++++++++ + sc/source/ui/view/gridwin.cxx | 7 ++----- + 2 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 8c622a577231..df803c4bdaf0 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -68,6 +68,7 @@ public: + void testSaveAsCalc(); + void testPasteWriter(); + void testRowColumnHeaders(); ++ void testCellCursor(); + void testCommandResult(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); +@@ -82,6 +83,7 @@ public: + CPPUNIT_TEST(testSaveAsCalc); + CPPUNIT_TEST(testPasteWriter); + CPPUNIT_TEST(testRowColumnHeaders); ++ CPPUNIT_TEST(testCellCursor); + CPPUNIT_TEST(testCommandResult); + CPPUNIT_TEST_SUITE_END(); + +@@ -435,6 +437,24 @@ void DesktopLOKTest::testRowColumnHeaders() + } + } + ++void DesktopLOKTest::testCellCursor() ++{ ++ LibLODocument_Impl* pDocument = loadDoc("search.ods"); ++ ++ boost::property_tree::ptree aTree; ++ ++ char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:CellCursor?tileWidth=1&tileHeight=1&outputWidth=1&outputHeight=1"); ++ ++ std::stringstream aStream(pJSON); ++ free(pJSON); ++ CPPUNIT_ASSERT(!aStream.str().empty()); ++ ++ boost::property_tree::read_json(aStream, aTree); ++ ++ OString aRectangle(aTree.get("commandValues").c_str()); ++ CPPUNIT_ASSERT_EQUAL(aRectangle, OString("0, 0, 1278, 254")); ++} ++ + void DesktopLOKTest::testCommandResult() + { + LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index d6887b6f4e07..c2d391d038ef 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -5796,13 +5796,10 @@ OString ScGridWindow::getCellCursor( int nOutputWidth, int nOutputHeight, + } + + OString ScGridWindow::getCellCursor(const Fraction& rZoomX, const Fraction& rZoomY) { +- ScDocument* pDoc = pViewData->GetDocument(); +- ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); +- +- // GridWindows stores a shown cell cursor in mpOOCursors, hence ++ // GridWindow stores a shown cell cursor in mpOOCursors, hence + // we can use that to determine whether we would want to be showing + // one (client-side) for tiled rendering too. +- if (!pDrawLayer->isTiledRendering() || !mpOOCursors.get()) ++ if (!mpOOCursors.get()) + { + return OString("EMPTY"); + } +-- +2.12.0 + diff --git a/SOURCES/0289-sc-lok-add-missing-commandName.patch b/SOURCES/0289-sc-lok-add-missing-commandName.patch new file mode 100644 index 0000000..3d2de80 --- /dev/null +++ b/SOURCES/0289-sc-lok-add-missing-commandName.patch @@ -0,0 +1,28 @@ +From 715f9d097d814abf67872bf0c15222243c668219 Mon Sep 17 00:00:00 2001 +From: Henry Castro +Date: Sun, 8 Nov 2015 15:55:57 -0400 +Subject: [PATCH 289/398] sc lok: add missing commandName + +LOOL requires to filter a requested command values message + +Change-Id: If2eeb9990e0f9aec6410a70f7a6c132c080bda80 +(cherry picked from commit c615699af18635c1aa1e7c9b930748eca004c5fc) +--- + sc/source/ui/view/tabview.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx +index d8fcd4ff4a73..b1cbe8d6f950 100644 +--- a/sc/source/ui/view/tabview.cxx ++++ b/sc/source/ui/view/tabview.cxx +@@ -2372,6 +2372,7 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle) + } + + boost::property_tree::ptree aTree; ++ aTree.put("commandName", ".uno:ViewRowColumnHeaders"); + aTree.add_child("rows", aRows); + aTree.add_child("columns", aCols); + std::stringstream aStream; +-- +2.12.0 + diff --git a/SOURCES/0290-lokdocview-assert-that-loading-of-handle-bitmaps-suc.patch b/SOURCES/0290-lokdocview-assert-that-loading-of-handle-bitmaps-suc.patch new file mode 100644 index 0000000..9eb2c30 --- /dev/null +++ b/SOURCES/0290-lokdocview-assert-that-loading-of-handle-bitmaps-suc.patch @@ -0,0 +1,194 @@ +From 6be255b70ed61eeba0035d6b03bf4455d0ce6cac Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 10 Nov 2015 09:40:10 +0100 +Subject: [PATCH 290/398] lokdocview: assert that loading of handle bitmaps + succeeded + +A number of such bitmaps were removed by accident in commit +74463457b39c9def1add630b7b0581dc195549c8 (android: chanhe handles to use +alias, tint handles with color, 2015-11-01). + +Change-Id: I253c4b5790e82de32e6fd06896645adf360fa586 +(cherry picked from commit c044e51b9983d373cf3ea74aec0ffd37752f07a0) +--- + android/source/res/drawable/handle_end.png | Bin 0 -> 1734 bytes + android/source/res/drawable/handle_middle.png | Bin 0 -> 1850 bytes + android/source/res/drawable/handle_start.png | Bin 0 -> 1676 bytes + libreofficekit/source/gtk/lokdocview.cxx | 13 +++++++++++++ + 4 files changed, 13 insertions(+) + create mode 100644 android/source/res/drawable/handle_end.png + create mode 100644 android/source/res/drawable/handle_middle.png + create mode 100644 android/source/res/drawable/handle_start.png + +diff --git a/android/source/res/drawable/handle_end.png b/android/source/res/drawable/handle_end.png +new file mode 100644 +index 0000000000000000000000000000000000000000..32b77dfa6e26a4560c1e921110e2ce0b4ed5bd76 +GIT binary patch +literal 1734 +zcmbVNX;2eq7!C-?AyNcvsU6$~wO}F1=2()2NOLVv4WxkzqZJIv0uhppn}sCcNbwd$ +zbgDu@6qxb0D5%v6Rk0{q1PW9Hybu&3LO}&7OdY#Hu>NrT(VgA>zVF@ldER?=t1LXk +z+3{0H3Weev7AlsLs~7qB+1rtCe4V`wxp)$i7$Oo&APfo|r3h45JPL$q6p5%DRj5p> +zZ=gXG%CsbPR16U#T>>jH4NYOup&2zg5>2551sin=Wim>(4g`UI0FwbS=?wCQ{6RL%fna6;FnLi)Yq%-_ +zmWz=|TjYsPO(F;#Os5+R2AY9I!|+5p$m8)W989J^so}3TX$ghVU#s_?Vi2QxC9c*H +zYD^1Q7!~nYD#53cp1uh|qmxSC5^MF7i6T=*H!5^=kj9{EG?us~wDp7>{m+f}YU`s+ +zI+QL)^;jydBh&)EM=+#WJwr->60)WAc}+lAE`pA)>;I< +zmIA$rSB&E7G*pG)m#DXYeM}K}}gqy&<_CbGI2`zYW +z!GcyQa(t`(mFiG8!K|-l)~pw@&DF(Tp&4CWSJ#(*pKt7RksU+aa;Dq9p5?M>{j&`R +zx5V$f(z+?lux6Ubvz2Chy4lGiMBs3I2yA5R>b()R%G0|rCX%w9hhBYzqH0t*dlY#r=Nn$UY|(FIM!$X)t_`;kv_C4a_6?@r#><6D}Kewq2`RF-?PonXFIs9u&t>mEnFkZH#^D? +z`&=kHl-iWj`z7qu5?^Q@f8kN|c+4kT>vwl(^~uuH=t%o`v%eiR?^R^(=8g`7Tal(N +zb}6ynboSi0IY*sf)Y`>uQO78@`r1K+M7dlVa;p*%*=cq{$lH$h(-7A +zdF)#jDyWFEZpS}kFFQDo$c#Ta*J;$)_+&@t*^Qjga?m@?CRp+~=VpCk{Ye +z9f|QRm*+gKWj5U4Qp;YqS?Q;bI-Pjb)jvH3C%ghL!XDKUo$Gfty*5vGYdqV|j9i}m +z#f6ZeeRh|kTk@~AQP6=JPE7j~&%7bOs(o1o$E+;xJu>xt&z1b5ys$Bs9UJ1f{Y*nOIBbe-@a&th +z`BmpBj~BV=`>%B@9(u{vcX)4F*7Z8bFL+_^?TU?Fr)7t^#Gc2yt~cqkZuIPR8x@xH +q=o0^KFFy1WUpP>3-qaCiWk(S+KZ*OMysydfX9<&pi_3&7*Zm8TgRNQs + +literal 0 +HcmV?d00001 + +diff --git a/android/source/res/drawable/handle_middle.png b/android/source/res/drawable/handle_middle.png +new file mode 100644 +index 0000000000000000000000000000000000000000..751eb898b136ab9814248a83df833d43f0e778dc +GIT binary patch +literal 1850 +zcmbVNdss|q7$0(}q-eJimSduXxtzJ2xzrfbTrx2u(;%|yG;^joo4J^CG*hUAHe1NL +zC9xH1TO=$|(p4^N*5ev-%i3)Tg+DD_uikgI$Rk#*mbxo +zi9{MKpDIxi>nP%x`ww1zlkl +zBYJddk_CxKQmQpc@fx0%ESwAk+xP^50l{IwW>{#%_%;FgJujcwJH#|H@LmOv7mz$NO;4aVL^$azzZcN&0+&$#N`qJnfOB0qFTO;%aMT~hehWw +z=nxkKxpXd57Q*0(cw#Ao!329bK8F=SAd?M=cp)+#3k0PgPt1e35*e2(VsfNh8KV~~ +zH)1$!)F8cfQNnHymit94Uu;2O++_bF{}N +z?b0hEdeE``*!;xd|#L#wY +z_M%(2u-rpSWa$+9+|cM79+P#y^X|M!ZVlS9wY@AmPwTAyH70Ah!qe3!H!N%wa-hz? +z4>F*_gMIkwu?52F#QVX40ZwrzLzYmzuZ((LV<=8`oAuZJgvk~2Z|1n=c{x>Gc*09M +zKEJvA6y5&!g@BDax7FTe*tb`ns2hHu!=6fMc(7@6+Qql^=>ZAPv!<^pqL)jjoDmq( +zeTzy%no=HTRff5BMaTFZc)A_`M!y&G2s(EtjP2TxkEiqv#8#~5sC`FUSrx8HRH$JOFw_Yk*KAM^8=`m1mCbbrwN4HgNhGS>Ez3{HE_PfG>?V_``Z72DYP$Fht*6Hn`_2JZ8Yu39`^I59^P(>0QHu;ns1 +zq`x4p^{kt2L-LhBD=(p!pV?Cp?Xn+UMd9BnUKaFiQ|%DR@>>*-)v=+ENo +zPUi$^O7W8X)7}#}znv6+)pGLXROHS$>wZ=3Sp){mss +z&mLFzFsCGAQ({o#+8rleln%PrYR>H%`+8N}+uX-Z)7%?2~SZY~ktPxRovI +zI+T6N^RV4Dfo9jdzQr}&e#2Z!W1F-4HFR}*bqSoG*V5^#`qjdFucC(NR=rr7lsQmX +zGwq4Ttsi%O&kAh)NxL`NXAJlC&;>4yo=zKlI(2<-W5e&ZH+UZ0nMXDAm3NwIc6Ere +zQR;=@to8b$Gi+?fB^TvC8-1KY$4{EF#;2)ro_`?xkU51n6mAglbEDICMg5Yox_byR +z$;HpVtvakpbQV>v4E?#WX_)35NAiG_AW0rXC%v=zxu;IQa@+AYlS`G7(vX<6e*p&9 +B)mZ=l + +literal 0 +HcmV?d00001 + +diff --git a/android/source/res/drawable/handle_start.png b/android/source/res/drawable/handle_start.png +new file mode 100644 +index 0000000000000000000000000000000000000000..cf12a0dcdcf3b27566fb4a4cd990306965759d3d +GIT binary patch +literal 1676 +zcmbVNeNfY87%wP_D7RCl4n&PX5T~?FKhid%Vrd%%DOAd8k&Ppyfo9OAwxJ)K?65eo +zIAuef2yQy3%&KE@Zf*yDP8i3;0dooiJUwOV2E(0-4w>Cj1m_=~e=L{eecva~@ArIP +z-0I{N!9ig`EEX#`VWlFKS?4j&(!fc~+u{nG$Sk3>Qb%j39NLaq2$oDwWfMSx5z8e~ +z2~6)?*FwaySQ89nnvT|~k`SCSvN4|y+hH^_Xcj9r&SA#zJc0(YiCoeo1@AVT0Rd7k +z1=k2wT$Nc)7|4}{7D7{)oQ4 +z6*^A}K6Of`QUh|zLI6TGKL+PQ5CFq$NFan^Xeq$sLOc$ax#1W{fCyoPCj!PUkg;ab +z=OC#Hbj%iWl7a@BHX|I4-EL>w`E1IP%Yh^kiI0QFi(xcktWFb+IbuxKh;ar5VZ|+^ +znIgo)Md@V~Ju?#&KX~4#ehij7DEvquN$FmH5w%7iwG6 +zoMwWPN?54^3(nLdCt@7TR#co9|xLtL4dD~LxW0tiw<61fBxD^Rgm#uq8Y +zC~q8_V6xJf2`9$wl8oIkEdQlgL~bE4nzE!(RQ`Aes0|cNSq+pKkZWKdT7}`H$tPIs +zE6~$;6@-Pf5qi`@8G+FZBjgJ_fD|wc%lJwNeJ*ks6^J3e2$k>z;22i_f3n75oZ$mVbSMLYC&}9;j@~3z5CroNE(ZJ}`xp +z|1ArvD~s8&_H__;)s@AaeQ-;b5p*Izc5>*3a^T#g!=e;#bk`w~bhvZkD?ypv2RsYD +z?wQ}M&uxD6k-L`MwQwXNllNz2!}-CHzEi^$&d?tui*CslN6vfy&~NpdliZHDX?IR# +zl-zFJp6QD8JGkn;Xt0JIURc^0|H+0|iowzdziXf0_Pn=5UWkB2P0oWs+Spva!ZAr(V2|gq=hD<;enm+2 +z$sLIsGaqi+^6`Qye8-x=5+_UZVO^ir1F0Li9ozFXEiz~AqRP+S_0HXQ^kMqmj4Z+G +zK-E`byVE=1zSp?=A6|d^Dx~kPwi0!J+%{VfTzyAaX;}FC1^(XJduXP1Pn98OsrLk@ +ze%^|Zmi48gu;q1Ai{R?;Q<53$J9>sX6&I&9?RMYOMp=UM;niVD0uup>&gF!}xZFRA +zaIhf@m(K4E9js1l;@gt+lLyM&RRME)(xZxs9^WW_(B)>1mkyTZ&O%ePQQMA%-`|;7 +zj}ENawIM*b^K!t=wyGJLxbjl#)ubc&=8Kpu(EDb4zl-Qq_GRxj9Jv14JH?;sevN;U +zy5#%Q9_x1n_A4PHE#10`fUdg*lcUpHhrN@#`Uj5-i{WpBO(i|ouWTqt4zy2kHH6#@ +zcHQsMTaUya(uhx&uhX7rDM#1N_eQN+w*1O=scgmv;d`31YOba2KiyVQUUSz!^bhIK +zlyl9bIxc!r&>Ii@;fy)^i1yj)S(O=OO(jnC@?L6-ZFBcgfh|RMYi9f5&1Wc&&@Ut8 +z(c$xFj?bKqs~RsKP2BoRL9y#b>;A&^St7jEJX;!dw&Cp0k0xmRDwH+03vW&B+$i2A +fy{_GQ&3_te*fBRN_wAw#-~S;&nXIUd&vN|>yUu?= + +literal 0 +HcmV?d00001 + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 8f0a053677fa..9dfa2f3b44a6 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -1059,7 +1060,10 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + // Have a cursor, but no selection: we need the middle handle. + gchar* handleMiddlePath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_middle.png", NULL); + if (!priv->m_pHandleMiddle) ++ { + priv->m_pHandleMiddle = cairo_image_surface_create_from_png(handleMiddlePath); ++ assert(cairo_surface_status(priv->m_pHandleMiddle) == CAIRO_STATUS_SUCCESS); ++ } + g_free (handleMiddlePath); + renderHandle(pDocView, pCairo, priv->m_aVisibleCursor, priv->m_pHandleMiddle, priv->m_aHandleMiddleRect); + } +@@ -1084,7 +1088,10 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + // Have a start position: we need a start handle. + gchar* handleStartPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_start.png", NULL); + if (!priv->m_pHandleStart) ++ { + priv->m_pHandleStart = cairo_image_surface_create_from_png(handleStartPath); ++ assert(cairo_surface_status(priv->m_pHandleStart) == CAIRO_STATUS_SUCCESS); ++ } + renderHandle(pDocView, pCairo, priv->m_aTextSelectionStart, priv->m_pHandleStart, priv->m_aHandleStartRect); + g_free (handleStartPath); + } +@@ -1093,7 +1100,10 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + // Have a start position: we need an end handle. + gchar* handleEndPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_end.png", NULL); + if (!priv->m_pHandleEnd) ++ { + priv->m_pHandleEnd = cairo_image_surface_create_from_png(handleEndPath); ++ assert(cairo_surface_status(priv->m_pHandleEnd) == CAIRO_STATUS_SUCCESS); ++ } + renderHandle(pDocView, pCairo, priv->m_aTextSelectionEnd, priv->m_pHandleEnd, priv->m_aHandleEndRect); + g_free (handleEndPath); + } +@@ -1103,7 +1113,10 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo) + { + gchar* handleGraphicPath = g_strconcat (priv->m_aLOPath, "/../..", CURSOR_HANDLE_DIR, "handle_graphic.png", NULL); + if (!priv->m_pGraphicHandle) ++ { + priv->m_pGraphicHandle = cairo_image_surface_create_from_png(handleGraphicPath); ++ assert(cairo_surface_status(priv->m_pGraphicHandle) == CAIRO_STATUS_SUCCESS); ++ } + renderGraphicHandle(pDocView, pCairo, priv->m_aGraphicSelection, priv->m_pGraphicHandle); + g_free (handleGraphicPath); + } +-- +2.12.0 + diff --git a/SOURCES/0291-loplugin-nullptr-automatic-rewrite.patch b/SOURCES/0291-loplugin-nullptr-automatic-rewrite.patch new file mode 100644 index 0000000..76a8863 --- /dev/null +++ b/SOURCES/0291-loplugin-nullptr-automatic-rewrite.patch @@ -0,0 +1,82 @@ +From 4c85fb2dfb79b09598d8196d134398a8bb688b20 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 10 Nov 2015 10:09:37 +0100 +Subject: [PATCH 291/398] loplugin:nullptr (automatic rewrite) + +Change-Id: Ifbab1c3bdf0bb481477e600978c640cdc052be74 +(cherry picked from commit ebc194c696e5c9b1acf320cfc582b4ab56c14900) +--- + include/LibreOfficeKit/LibreOfficeKit.hxx | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index c51339fa3ba8..dde371ddc95b 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -47,7 +47,7 @@ public: + * @param pFormat the format to use while exporting, when omitted, then deducted from pURL's extension + * @param pFilterOptions options for the export filter, e.g. SkipImages. + */ +- inline bool saveAs(const char* pUrl, const char* pFormat = NULL, const char* pFilterOptions = NULL) ++ inline bool saveAs(const char* pUrl, const char* pFormat = nullptr, const char* pFilterOptions = nullptr) + { + return mpDoc->pClass->saveAs(mpDoc, pUrl, pFormat, pFilterOptions) != 0; + } +@@ -220,7 +220,7 @@ public: + * @param pCommand uno command to be posted to the document, like ".uno:Bold" + * @param pArguments arguments of the uno command. + */ +- inline void postUnoCommand(const char* pCommand, const char* pArguments = 0, bool bNotifyWhenFinished = false) ++ inline void postUnoCommand(const char* pCommand, const char* pArguments = nullptr, bool bNotifyWhenFinished = false) + { + mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments, bNotifyWhenFinished); + } +@@ -243,7 +243,7 @@ public: + * @param pMimeType suggests the return format, for example text/plain;charset=utf-8. + * @param pUsedMimeType output parameter to inform about the determined format (suggested one or plain text). + */ +- inline char* getTextSelection(const char* pMimeType, char** pUsedMimeType = 0) ++ inline char* getTextSelection(const char* pMimeType, char** pUsedMimeType = nullptr) + { + return mpDoc->pClass->getTextSelection(mpDoc, pMimeType, pUsedMimeType); + } +@@ -361,17 +361,17 @@ public: + * @param pUrl the URL of the document to load + * @param pFilterOptions options for the import filter, e.g. SkipImages. + */ +- inline Document* documentLoad(const char* pUrl, const char* pFilterOptions = NULL) ++ inline Document* documentLoad(const char* pUrl, const char* pFilterOptions = nullptr) + { +- LibreOfficeKitDocument* pDoc = NULL; ++ LibreOfficeKitDocument* pDoc = nullptr; + + if (LIBREOFFICEKIT_HAS(mpThis, documentLoadWithOptions)) + pDoc = mpThis->pClass->documentLoadWithOptions(mpThis, pUrl, pFilterOptions); + else + pDoc = mpThis->pClass->documentLoad(mpThis, pUrl); + +- if (pDoc == NULL) +- return NULL; ++ if (pDoc == nullptr) ++ return nullptr; + + return new Document(pDoc); + } +@@ -405,11 +405,11 @@ public: + }; + + /// Factory method to create a lok::Office instance. +-inline Office* lok_cpp_init(const char* pInstallPath, const char* pUserProfilePath = NULL) ++inline Office* lok_cpp_init(const char* pInstallPath, const char* pUserProfilePath = nullptr) + { + LibreOfficeKit* pThis = lok_init_2(pInstallPath, pUserProfilePath); +- if (pThis == NULL || pThis->pClass->nSize == 0) +- return NULL; ++ if (pThis == nullptr || pThis->pClass->nSize == 0) ++ return nullptr; + return new ::lok::Office(pThis); + } + +-- +2.12.0 + diff --git a/SOURCES/0292-loplugin-nullptr-automatic-rewrite.patch b/SOURCES/0292-loplugin-nullptr-automatic-rewrite.patch new file mode 100644 index 0000000..40a2993 --- /dev/null +++ b/SOURCES/0292-loplugin-nullptr-automatic-rewrite.patch @@ -0,0 +1,1004 @@ +From 7a2ed28a86aad93edca7fa6c2706a7ff78653b21 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 10 Nov 2015 10:18:58 +0100 +Subject: [PATCH 292/398] loplugin:nullptr (automatic rewrite) + +Change-Id: Ibdb6409664cdf9499b6fec95c5de3549887b8106 +(cherry picked from commit 5678a4ce9eee64cafdbdb4fc1290535f9e03208f) +--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 96 ++++++------- + libreofficekit/qa/tilebench/tilebench.cxx | 6 +- + libreofficekit/source/gtk/lokdocview.cxx | 160 ++++++++++----------- + libreofficekit/source/gtk/tilebuffer.cxx | 12 +- + libreofficekit/source/gtk/tilebuffer.hxx | 10 +- + 5 files changed, 142 insertions(+), 142 deletions(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 08e756fa3ef6..3f57b5c6c6b9 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -119,31 +119,31 @@ public: + std::shared_ptr m_pCornerButton; + + TiledWindow() +- : m_pDocView(0), +- m_pStatusBar(0), +- m_pProgressBar(0), +- m_pStatusbarLabel(0), +- m_pZoomLabel(0), +- m_pEnableEditing(0), +- m_pBold(0), +- m_pItalic(0), +- m_pUnderline(0), +- m_pStrikethrough(0), +- m_pSuperscript(0), +- m_pSubscript(0), +- m_pLeftpara(0), +- m_pCenterpara(0), +- m_pRightpara(0), +- m_pJustifypara(0), +- m_pScrolledWindow(0), ++ : m_pDocView(nullptr), ++ m_pStatusBar(nullptr), ++ m_pProgressBar(nullptr), ++ m_pStatusbarLabel(nullptr), ++ m_pZoomLabel(nullptr), ++ m_pEnableEditing(nullptr), ++ m_pBold(nullptr), ++ m_pItalic(nullptr), ++ m_pUnderline(nullptr), ++ m_pStrikethrough(nullptr), ++ m_pSuperscript(nullptr), ++ m_pSubscript(nullptr), ++ m_pLeftpara(nullptr), ++ m_pCenterpara(nullptr), ++ m_pRightpara(nullptr), ++ m_pJustifypara(nullptr), ++ m_pScrolledWindow(nullptr), + m_bToolItemBroadcast(true), +- m_pVBox(0), +- m_pPartSelector(0), +- m_pPartModeComboBox(0), ++ m_pVBox(nullptr), ++ m_pPartSelector(nullptr), ++ m_pPartModeComboBox(nullptr), + m_bPartSelectorBroadcast(true), +- m_pFindbar(0), +- m_pFindbarEntry(0), +- m_pFindbarLabel(0), ++ m_pFindbar(nullptr), ++ m_pFindbarEntry(nullptr), ++ m_pFindbarLabel(nullptr), + m_bFindAll(false) + { + } +@@ -240,7 +240,7 @@ gboolean TiledRowColumnBar::drawImpl(GtkWidget* /*pWidget*/, cairo_t* pCairo) + void TiledRowColumnBar::docAdjustmentChanged(GtkAdjustment* /*pAdjustment*/, gpointer pData) + { + GtkWidget* pDocView = static_cast(pData); +- docConfigureEvent(pDocView, 0, 0); ++ docConfigureEvent(pDocView, nullptr, nullptr); + } + + gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfigure* /*pEvent*/, gpointer /*pData*/) +@@ -470,11 +470,11 @@ static void createView(GtkWidget* pButton, gpointer /*pItem*/) + /// Creates a new model, i.e. LOK init and document load, one view implicitly. + static void createModelAndView(const char* pLOPath, const char* pDocPath) + { +- GtkWidget* pDocView = lok_doc_view_new(pLOPath, 0, 0); ++ GtkWidget* pDocView = lok_doc_view_new(pLOPath, nullptr, nullptr); + + setupWidgetAndCreateWindow(pDocView); + +- lok_doc_view_open_document(LOK_DOC_VIEW(pDocView), pDocPath, 0, openDocumentCallback, pDocView); ++ lok_doc_view_open_document(LOK_DOC_VIEW(pDocView), pDocPath, nullptr, openDocumentCallback, pDocView); + } + + /// Our GtkClipboardGetFunc implementation for HTML. +@@ -494,7 +494,7 @@ static void htmlClearFunc(GtkClipboard* /*pClipboard*/, gpointer pData) + /// Same as gtk_clipboard_set_text(), but sets HTML. + static void clipboardSetHtml(GtkClipboard* pClipboard, const char* pSelection) + { +- GtkTargetList* pList = gtk_target_list_new(0, 0); ++ GtkTargetList* pList = gtk_target_list_new(nullptr, 0); + GdkAtom aAtom(gdk_atom_intern("text/html", false)); + gtk_target_list_add(pList, aAtom, 0, 0); + gint nTargets = 0; +@@ -512,7 +512,7 @@ static void doCopy(GtkWidget* pButton, gpointer /*pItem*/) + TiledWindow& rWindow = lcl_getTiledWindow(pButton); + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); +- char* pUsedFormat = 0; ++ char* pUsedFormat = nullptr; + char* pSelection = pDocument->pClass->getTextSelection(pDocument, "text/html", &pUsedFormat); + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(rWindow.m_pDocView), GDK_SELECTION_CLIPBOARD); +@@ -708,9 +708,9 @@ static void signalPart(LOKDocView* pLOKDocView, int nPart, gpointer /*pData*/) + /// User clicked on a command button -> inform LOKDocView. + static void signalHyperlink(LOKDocView* /*pLOKDocView*/, char* pPayload, gpointer /*pData*/) + { +- GError* pError = NULL; +- gtk_show_uri(NULL, pPayload, GDK_CURRENT_TIME, &pError); +- if (pError != NULL) ++ GError* pError = nullptr; ++ gtk_show_uri(nullptr, pPayload, GDK_CURRENT_TIME, &pError); ++ if (pError != nullptr) + { + g_warning("Unable to show URI %s : %s", pPayload, pError->message); + g_error_free(pError); +@@ -781,7 +781,7 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + // notify about the finished Save + gboolean bNotify = (rString == ".uno:Save"); + +- lok_doc_view_post_command(pLOKDocView, rString.c_str(), 0, bNotify); ++ lok_doc_view_post_command(pLOKDocView, rString.c_str(), nullptr, bNotify); + } + } + +@@ -863,8 +863,8 @@ static void openDocumentCallback (GObject* source_object, GAsyncResult* res, gpo + { + LOKDocView* pDocView = LOK_DOC_VIEW (source_object); + TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pDocView)); +- GError* error = NULL; +- GList *focusChain = NULL; ++ GError* error = nullptr; ++ GList *focusChain = nullptr; + + if (!lok_doc_view_open_document_finish(pDocView, res, &error)) + { +@@ -913,7 +913,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_set_style(GTK_TOOLBAR(pUpperToolbar), GTK_TOOLBAR_ICONS); + + // Save. +- GtkToolItem* pSave = gtk_tool_button_new(NULL, NULL); ++ GtkToolItem* pSave = gtk_tool_button_new(nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pSave), "document-save-symbolic"); + gtk_tool_item_set_tooltip_text(pSave, "Save"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pSave, -1); +@@ -922,12 +922,12 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + lcl_registerToolItem(rWindow, pSave, ".uno:Save"); + + // Copy and paste. +- GtkToolItem* pCopyButton = gtk_tool_button_new( NULL, NULL); ++ GtkToolItem* pCopyButton = gtk_tool_button_new( nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pCopyButton), "edit-copy-symbolic"); + gtk_tool_item_set_tooltip_text(pCopyButton, "Copy"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pCopyButton, -1); + g_signal_connect(G_OBJECT(pCopyButton), "clicked", G_CALLBACK(doCopy), NULL); +- GtkToolItem* pPasteButton = gtk_tool_button_new( NULL, NULL); ++ GtkToolItem* pPasteButton = gtk_tool_button_new( nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pPasteButton), "edit-paste-symbolic"); + gtk_tool_item_set_tooltip_text(pPasteButton, "Paste"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pPasteButton, -1); +@@ -935,13 +935,13 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_insert( GTK_TOOLBAR(pUpperToolbar), gtk_separator_tool_item_new(), -1); + + // Undo and redo. +- GtkToolItem* pUndo = gtk_tool_button_new(NULL, NULL); ++ GtkToolItem* pUndo = gtk_tool_button_new(nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pUndo), "edit-undo-symbolic"); + gtk_tool_item_set_tooltip_text(pUndo, "Undo"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pUndo, -1); + g_signal_connect(G_OBJECT(pUndo), "clicked", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(rWindow, pUndo, ".uno:Undo"); +- GtkToolItem* pRedo = gtk_tool_button_new(NULL, NULL); ++ GtkToolItem* pRedo = gtk_tool_button_new(nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pRedo), "edit-redo-symbolic"); + gtk_tool_item_set_tooltip_text(pRedo, "Redo"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pRedo, -1); +@@ -950,7 +950,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), gtk_separator_tool_item_new(), -1); + + // Find. +- GtkToolItem* pFindButton = gtk_tool_button_new( NULL, NULL); ++ GtkToolItem* pFindButton = gtk_tool_button_new( nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindButton), "edit-find-symbolic"); + gtk_tool_item_set_tooltip_text(pFindButton, "Find"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pFindButton, -1); +@@ -958,19 +958,19 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), gtk_separator_tool_item_new(), -1); + + // Misc upper toolbar. +- GtkToolItem* pZoomIn = gtk_tool_button_new(NULL, NULL); ++ GtkToolItem* pZoomIn = gtk_tool_button_new(nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomIn), "zoom-in-symbolic"); + gtk_tool_item_set_tooltip_text(pZoomIn, "Zoom In"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pZoomIn, -1); + g_signal_connect(G_OBJECT(pZoomIn), "clicked", G_CALLBACK(changeZoom), NULL); + +- GtkToolItem* pZoom1 = gtk_tool_button_new(NULL, NULL); ++ GtkToolItem* pZoom1 = gtk_tool_button_new(nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pZoom1), "zoom-original-symbolic"); + gtk_tool_item_set_tooltip_text(pZoom1, "Normal Size"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pZoom1, -1); + g_signal_connect(G_OBJECT(pZoom1), "clicked", G_CALLBACK(changeZoom), NULL); + +- GtkToolItem* pZoomOut = gtk_tool_button_new(NULL, NULL); ++ GtkToolItem* pZoomOut = gtk_tool_button_new(nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pZoomOut), "zoom-out-symbolic"); + gtk_tool_item_set_tooltip_text(pZoomOut, "Zoom Out"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pZoomOut, -1); +@@ -995,7 +995,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pEnableEditing, -1); + g_signal_connect(G_OBJECT(pEnableEditing), "toggled", G_CALLBACK(toggleEditing), NULL); + +- GtkToolItem* pNewViewButton = gtk_tool_button_new( NULL, NULL); ++ GtkToolItem* pNewViewButton = gtk_tool_button_new( nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pNewViewButton), "view-continuous-symbolic"); + gtk_tool_item_set_tooltip_text(pNewViewButton, "New View"); + gtk_toolbar_insert(GTK_TOOLBAR(pUpperToolbar), pNewViewButton, -1); +@@ -1079,7 +1079,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + rWindow.m_pFindbar = gtk_toolbar_new(); + gtk_toolbar_set_style(GTK_TOOLBAR(rWindow.m_pFindbar), GTK_TOOLBAR_ICONS); + +- GtkToolItem* pFindbarClose = gtk_tool_button_new( NULL, NULL); ++ GtkToolItem* pFindbarClose = gtk_tool_button_new( nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarClose), "window-close-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarClose, -1); + g_signal_connect(G_OBJECT(pFindbarClose), "clicked", G_CALLBACK(toggleFindbar), NULL); +@@ -1090,12 +1090,12 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + g_signal_connect(rWindow.m_pFindbarEntry, "key-press-event", G_CALLBACK(signalFindbar), 0); + gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pEntryContainer, -1); + +- GtkToolItem* pFindbarNext = gtk_tool_button_new( NULL, NULL); ++ GtkToolItem* pFindbarNext = gtk_tool_button_new( nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarNext), "go-down-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarNext, -1); + g_signal_connect(G_OBJECT(pFindbarNext), "clicked", G_CALLBACK(signalSearchNext), NULL); + +- GtkToolItem* pFindbarPrev = gtk_tool_button_new( NULL, NULL); ++ GtkToolItem* pFindbarPrev = gtk_tool_button_new( nullptr, nullptr); + gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON (pFindbarPrev), "go-up-symbolic"); + gtk_toolbar_insert(GTK_TOOLBAR(rWindow.m_pFindbar), pFindbarPrev, -1); + g_signal_connect(G_OBJECT(pFindbarPrev), "clicked", G_CALLBACK(signalSearchPrev), NULL); +@@ -1126,7 +1126,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_grid_attach(GTK_GRID(pGrid), rWindow.m_pColumnBar->m_pDrawingArea, 1, 0, 1, 1); + + // Scrolled window for DocView +- rWindow.m_pScrolledWindow = gtk_scrolled_window_new(0, 0); ++ rWindow.m_pScrolledWindow = gtk_scrolled_window_new(nullptr, nullptr); + gtk_widget_set_hexpand(rWindow.m_pScrolledWindow, TRUE); + gtk_widget_set_vexpand(rWindow.m_pScrolledWindow, TRUE); + // "B2" cell of the grid +diff --git a/libreofficekit/qa/tilebench/tilebench.cxx b/libreofficekit/qa/tilebench/tilebench.cxx +index e72c730a6dfe..20777de49fe1 100644 +--- a/libreofficekit/qa/tilebench/tilebench.cxx ++++ b/libreofficekit/qa/tilebench/tilebench.cxx +@@ -42,7 +42,7 @@ int main( int argc, char* argv[] ) + const char *mpName; + double mfTime; + +- TimeRecord() : mpName(NULL), mfTime(getTimeNow()) { } ++ TimeRecord() : mpName(nullptr), mfTime(getTimeNow()) { } + explicit TimeRecord(const char *pName) : + mpName(pName ), mfTime(getTimeNow()) { } + }; +@@ -62,7 +62,7 @@ int main( int argc, char* argv[] ) + Office *pOffice = lok_cpp_init(argv[1]); + aTimes.push_back(TimeRecord()); + +- if (argv[2] != NULL) ++ if (argv[2] != nullptr) + { + aTimes.push_back(TimeRecord("load document")); + Document *pDocument(pOffice->documentLoad(argv[2])); +@@ -157,7 +157,7 @@ int main( int argc, char* argv[] ) + { + double nDelta = aTimes[i+1].mfTime - aTimes[i].mfTime; + fprintf (stderr, " %s - %2.4f(ms)\n", aTimes[i].mpName, nDelta * 1000.0); +- if (aTimes[i+1].mpName == NULL) ++ if (aTimes[i+1].mpName == nullptr) + i++; // skip it. + nTotal += nDelta; + } +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 9dfa2f3b44a6..0d1dec1ddb05 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -119,15 +119,15 @@ struct LOKDocViewPrivateImpl + int m_nViewId; + + LOKDocViewPrivateImpl() +- : m_aLOPath(0), +- m_aDocPath(0), ++ : m_aLOPath(nullptr), ++ m_aDocPath(nullptr), + m_nLoadProgress(0), + m_bIsLoading(false), + m_bCanZoomIn(false), + m_bCanZoomOut(false), +- m_pOffice(0), +- m_pDocument(0), +- lokThreadPool(0), ++ m_pOffice(nullptr), ++ m_pDocument(nullptr), ++ lokThreadPool(nullptr), + m_fZoom(0), + m_nDocumentWidthTwips(0), + m_nDocumentHeightTwips(0), +@@ -144,16 +144,16 @@ struct LOKDocViewPrivateImpl + m_aGraphicSelection({0, 0, 0, 0}), + m_aCellCursor({0, 0, 0, 0}), + m_bInDragGraphicSelection(false), +- m_pHandleStart(0), ++ m_pHandleStart(nullptr), + m_aHandleStartRect({0, 0, 0, 0}), + m_bInDragStartHandle(0), +- m_pHandleMiddle(0), ++ m_pHandleMiddle(nullptr), + m_aHandleMiddleRect({0, 0, 0, 0}), + m_bInDragMiddleHandle(false), +- m_pHandleEnd(0), ++ m_pHandleEnd(nullptr), + m_aHandleEndRect({0, 0, 0, 0}), + m_bInDragEndHandle(false), +- m_pGraphicHandle(0), ++ m_pGraphicHandle(nullptr), + m_nViewId(0) + { + memset(&m_aGraphicHandleRects, 0, sizeof(m_aGraphicHandleRects)); +@@ -299,7 +299,7 @@ callbackTypeToString (int nType) + case LOK_CALLBACK_SEARCH_RESULT_SELECTION: + return "LOK_CALLBACK_SEARCH_RESULT_SELECTION"; + } +- return 0; ++ return nullptr; + } + + static bool +@@ -330,7 +330,7 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + LOKDocViewPrivate& priv = getPrivate(pDocView); + int nCharCode = 0; + int nKeyCode = 0; +- GError* error = NULL; ++ GError* error = nullptr; + + if (!priv->m_bEdit) + { +@@ -419,14 +419,14 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + + if (pEvent->type == GDK_KEY_RELEASE) + { +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY); + pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYUP; + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_POST_KEY: %s", error->message); + g_clear_error(&error); +@@ -435,14 +435,14 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent) + } + else + { +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY); + pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYINPUT; + pLOEvent->m_nCharCode = nCharCode; + pLOEvent->m_nKeyCode = nKeyCode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_POST_KEY: %s", error->message); + g_clear_error(&error); +@@ -664,7 +664,7 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) + { + for (int j = aStart.y; j < aEnd.y; j++) + { +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + priv->m_pTileBuffer->setInvalid(i, j, priv->m_fZoom, task, priv->lokThreadPool); + g_object_unref(task); + } +@@ -927,7 +927,7 @@ paintTileFinish(LOKDocView* pDocView, GAsyncResult* res, GError **error) + + g_return_val_if_fail(LOK_IS_DOC_VIEW(pDocView), NULL); + g_return_val_if_fail(g_task_is_valid(res, pDocView), NULL); +- g_return_val_if_fail(error == NULL || *error == NULL, NULL); ++ g_return_val_if_fail(error == nullptr || *error == nullptr, NULL); + + return g_task_propagate_pointer(task, error); + } +@@ -943,9 +943,9 @@ paintTileCallback(GObject* sourceObject, GAsyncResult* res, gpointer userData) + int index = pLOEvent->m_nPaintTileX * buffer->m_nWidth + pLOEvent->m_nPaintTileY; + GError* error; + +- error = NULL; ++ error = nullptr; + GdkPixbuf* pPixBuf = static_cast(paintTileFinish(pDocView, res, &error)); +- if (error != NULL) ++ if (error != nullptr) + { + if (error->domain == LOK_TILEBUFFER_ERROR && + error->code == LOK_TILEBUFFER_CHANGED) +@@ -1008,7 +1008,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + aTileRectangleTwips.width = pixelToTwip(aTileRectanglePixels.width, priv->m_fZoom); + aTileRectangleTwips.height = pixelToTwip(aTileRectanglePixels.height, priv->m_fZoom); + +- if (!gdk_rectangle_intersect(&aVisibleArea, &aTileRectangleTwips, 0)) ++ if (!gdk_rectangle_intersect(&aVisibleArea, &aTileRectangleTwips, nullptr)) + bPaint = false; + + if (bPaint) +@@ -1018,7 +1018,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) + pLOEvent->m_nPaintTileY = nColumn; + pLOEvent->m_fPaintTileZoom = priv->m_fZoom; + pLOEvent->m_pTileBuffer = &*priv->m_pTileBuffer; +- GTask* task = g_task_new(pDocView, NULL, paintTileCallback, pLOEvent); ++ GTask* task = g_task_new(pDocView, nullptr, paintTileCallback, pLOEvent); + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + Tile& currentTile = priv->m_pTileBuffer->getTile(nRow, nColumn, task, priv->lokThreadPool); +@@ -1145,7 +1145,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + { + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GError* error = NULL; ++ GError* error = nullptr; + + g_info("LOKDocView_Impl::signalButton: %d, %d (in twips: %d, %d)", + (int)pEvent->x, (int)pEvent->y, +@@ -1181,7 +1181,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i); + priv->m_bInDragGraphicHandles[i] = false; + +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); +@@ -1189,7 +1189,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); + g_clear_error(&error); +@@ -1205,7 +1205,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + g_info("LOKDocView_Impl::signalButton: end of drag graphic selection"); + priv->m_bInDragGraphicSelection = false; + +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); +@@ -1213,7 +1213,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); + g_clear_error(&error); +@@ -1233,19 +1233,19 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + aClick.height = 1; + if (pEvent->type == GDK_BUTTON_PRESS) + { +- if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, NULL)) ++ if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, nullptr)) + { + g_info("LOKDocView_Impl::signalButton: start of drag start handle"); + priv->m_bInDragStartHandle = true; + return FALSE; + } +- else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, NULL)) ++ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, nullptr)) + { + g_info("LOKDocView_Impl::signalButton: start of drag middle handle"); + priv->m_bInDragMiddleHandle = true; + return FALSE; + } +- else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, NULL)) ++ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, nullptr)) + { + g_info("LOKDocView_Impl::signalButton: start of drag end handle"); + priv->m_bInDragEndHandle = true; +@@ -1254,12 +1254,12 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + + for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) + { +- if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], NULL)) ++ if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], nullptr)) + { + g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i); + priv->m_bInDragGraphicHandles[i] = true; + +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom); +@@ -1267,7 +1267,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); + g_clear_error(&error); +@@ -1291,7 +1291,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + if ((pEvent->time - priv->m_nLastButtonPressTime) < 250) + nCount++; + priv->m_nLastButtonPressTime = pEvent->time; +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT); + pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEBUTTONDOWN; + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); +@@ -1314,7 +1314,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_POST_MOUSE_EVENT: %s", error->message); + g_clear_error(&error); +@@ -1328,7 +1328,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + if ((pEvent->time - priv->m_nLastButtonReleaseTime) < 250) + nCount++; + priv->m_nLastButtonReleaseTime = pEvent->time; +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT); + pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEBUTTONUP; + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); +@@ -1351,7 +1351,7 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_POST_MOUSE_EVENT: %s", error->message); + g_clear_error(&error); +@@ -1389,7 +1389,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + LOKDocView* pDocView = LOK_DOC_VIEW (pWidget); + LOKDocViewPrivate& priv = getPrivate(pDocView); + GdkPoint aPoint; +- GError* error = NULL; ++ GError* error = nullptr; + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + if (priv->m_bInDragMiddleHandle) +@@ -1432,12 +1432,12 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + aMotionInTwipsInTwips.y = pixelToTwip(pEvent->y, priv->m_fZoom); + aMotionInTwipsInTwips.width = 1; + aMotionInTwipsInTwips.height = 1; +- if (gdk_rectangle_intersect(&aMotionInTwipsInTwips, &priv->m_aGraphicSelection, 0)) ++ if (gdk_rectangle_intersect(&aMotionInTwipsInTwips, &priv->m_aGraphicSelection, nullptr)) + { + g_info("lcl_signalMotion: start of drag graphic selection"); + priv->m_bInDragGraphicSelection = true; + +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); + pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; + pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); +@@ -1445,7 +1445,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); + g_clear_error(&error); +@@ -1457,7 +1457,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + + // Otherwise a mouse move, as on the desktop. + +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_POST_MOUSE_EVENT); + pLOEvent->m_nPostMouseEventType = LOK_MOUSEEVENT_MOUSEMOVE; + pLOEvent->m_nPostMouseEventX = pixelToTwip(pEvent->x, priv->m_fZoom); +@@ -1469,7 +1469,7 @@ lok_doc_view_signal_motion (GtkWidget* pWidget, GdkEventMotion* pEvent) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_MOUSEEVENT_MOUSEMOVE: %s", error->message); + g_clear_error(&error); +@@ -1522,7 +1522,7 @@ openDocumentInThread (gpointer data) + if ( priv->m_pDocument ) + { + priv->m_pDocument->pClass->destroy( priv->m_pDocument ); +- priv->m_pDocument = 0; ++ priv->m_pDocument = nullptr; + } + + priv->m_pOffice->pClass->registerCallback(priv->m_pOffice, globalCallbackWorker, pDocView); +@@ -1728,10 +1728,10 @@ static void lok_doc_view_init (LOKDocView* pDocView) + |GDK_KEY_RELEASE_MASK); + + priv->lokThreadPool = g_thread_pool_new(lokThreadFunc, +- NULL, ++ nullptr, + 1, + FALSE, +- NULL); ++ nullptr); + } + + static void lok_doc_view_set_property (GObject* object, guint propId, const GValue *value, GParamSpec *pspec) +@@ -1838,7 +1838,7 @@ static void lok_doc_view_finalize (GObject* object) + if (priv->m_pOffice) + priv->m_pOffice->pClass->destroy (priv->m_pOffice); + delete priv.m_pImpl; +- priv.m_pImpl = 0; ++ priv.m_pImpl = nullptr; + + G_OBJECT_CLASS (lok_doc_view_parent_class)->finalize (object); + } +@@ -1848,12 +1848,12 @@ static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* / + LOKDocView *pDocView = LOK_DOC_VIEW (initable); + LOKDocViewPrivate& priv = getPrivate(pDocView); + +- if (priv->m_pOffice != NULL) ++ if (priv->m_pOffice != nullptr) + return TRUE; + + priv->m_pOffice = lok_init (priv->m_aLOPath); + +- if (priv->m_pOffice == NULL) ++ if (priv->m_pOffice == nullptr) + { + g_set_error (error, + g_quark_from_static_string ("LOK initialization error"), 0, +@@ -1896,7 +1896,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_param_spec_string("lopath", + "LO Path", + "LibreOffice Install Path", +- 0, ++ nullptr, + static_cast(G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS))); +@@ -1926,7 +1926,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_param_spec_string("docpath", + "Document Path", + "The URI of the document to open", +- 0, ++ nullptr, + static_cast(G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS))); + +@@ -2072,7 +2072,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS (pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__DOUBLE, + G_TYPE_NONE, 1, + G_TYPE_DOUBLE); +@@ -2087,7 +2087,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS (pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); +@@ -2102,7 +2102,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +@@ -2117,7 +2117,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +@@ -2132,7 +2132,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); +@@ -2147,7 +2147,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 1, + G_TYPE_INT); +@@ -2162,7 +2162,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +@@ -2180,7 +2180,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_generic, + G_TYPE_NONE, 4, + G_TYPE_INT, G_TYPE_INT, +@@ -2196,7 +2196,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +@@ -2212,7 +2212,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +@@ -2228,7 +2228,7 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOKDocView) + { + LOKDocViewPrivate& pOldPriv = getPrivate(pOldLOKDocView); +- GtkWidget* pNewDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/0, /*error=*/0, ++ GtkWidget* pNewDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/nullptr, /*error=*/nullptr, + "lopath", pOldPriv->m_aLOPath, "lopointer", pOldPriv->m_pOffice, "docpointer", pOldPriv->m_pDocument, NULL)); + + // No documentLoad(), just a createView(). +@@ -2248,7 +2248,7 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr + g_return_val_if_fail(g_task_is_valid(res, pDocView), false); + //FIXME: make source_tag work + //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL); +- g_return_val_if_fail(error == NULL || *error == NULL, false); ++ g_return_val_if_fail(error == nullptr || *error == nullptr, false); + + return g_task_propagate_boolean(task, error); + } +@@ -2262,7 +2262,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + { + GTask* task = g_task_new(pDocView, cancellable, callback, userdata); + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GError* error = NULL; ++ GError* error = nullptr; + + LOEvent* pLOEvent = new LOEvent(LOK_LOAD_DOC); + pLOEvent->m_pPath = pPath; +@@ -2271,7 +2271,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_LOAD_DOC: %s", error->message); + g_clear_error(&error); +@@ -2331,15 +2331,15 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); +- GError* error = NULL; ++ GError* error = nullptr; + + pLOEvent->m_nPart = nPart; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_PART: %s", error->message); + g_clear_error(&error); +@@ -2360,14 +2360,14 @@ lok_doc_view_set_partmode(LOKDocView* pDocView, + int nPartMode) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); +- GError* error = NULL; ++ GError* error = nullptr; + pLOEvent->m_nPartMode = nPartMode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_PARTMODE: %s", error->message); + g_clear_error(&error); +@@ -2397,22 +2397,22 @@ lok_doc_view_reset_view(LOKDocView* pDocView) + memset(&priv->m_aCellCursor, 0, sizeof(priv->m_aCellCursor)); + + cairo_surface_destroy(priv->m_pHandleStart); +- priv->m_pHandleStart = 0; ++ priv->m_pHandleStart = nullptr; + memset(&priv->m_aHandleStartRect, 0, sizeof(priv->m_aHandleStartRect)); + priv->m_bInDragStartHandle = false; + + cairo_surface_destroy(priv->m_pHandleMiddle); +- priv->m_pHandleMiddle = 0; ++ priv->m_pHandleMiddle = nullptr; + memset(&priv->m_aHandleMiddleRect, 0, sizeof(priv->m_aHandleMiddleRect)); + priv->m_bInDragMiddleHandle = false; + + cairo_surface_destroy(priv->m_pHandleEnd); +- priv->m_pHandleEnd = 0; ++ priv->m_pHandleEnd = nullptr; + memset(&priv->m_aHandleEndRect, 0, sizeof(priv->m_aHandleEndRect)); + priv->m_bInDragEndHandle = false; + + cairo_surface_destroy(priv->m_pGraphicHandle); +- priv->m_pGraphicHandle = 0; ++ priv->m_pGraphicHandle = nullptr; + memset(&priv->m_aGraphicHandleRects, 0, sizeof(priv->m_aGraphicHandleRects)); + memset(&priv->m_bInDragGraphicHandles, 0, sizeof(priv->m_bInDragGraphicHandles)); + +@@ -2426,14 +2426,14 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + gboolean bEdit) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); +- GError* error = NULL; ++ GError* error = nullptr; + pLOEvent->m_bEdit = bEdit; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_EDIT: %s", error->message); + g_clear_error(&error); +@@ -2456,16 +2456,16 @@ lok_doc_view_post_command (LOKDocView* pDocView, + gboolean bNotifyWhenFinished) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); +- GError* error = NULL; ++ GError* error = nullptr; + pLOEvent->m_pCommand = pCommand; + pLOEvent->m_pArguments = g_strdup(pArguments); + pLOEvent->m_bNotifyWhenFinished = bNotifyWhenFinished; + + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_POST_COMMAND: %s", error->message); + g_clear_error(&error); +diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx +index 32a9534e884c..f804a1f42140 100644 +--- a/libreofficekit/source/gtk/tilebuffer.cxx ++++ b/libreofficekit/source/gtk/tilebuffer.cxx +@@ -44,7 +44,7 @@ void Tile::setPixbuf(GdkPixbuf *buffer) + if (m_pBuffer == buffer) + return; + g_clear_object(&m_pBuffer); +- if (buffer != NULL) ++ if (buffer != nullptr) + g_object_ref(buffer); + m_pBuffer = buffer; + } +@@ -66,7 +66,7 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, + GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; +- GError* error = NULL; ++ GError* error = nullptr; + if (m_mTiles.find(index) != m_mTiles.end()) + { + m_mTiles[index].valid = false; +@@ -77,7 +77,7 @@ void TileBuffer::setInvalid(int x, int y, float fZoom, GTask* task, + pLOEvent->m_fPaintTileZoom = fZoom; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_PAINT_TILE: %s", error->message); + g_clear_error(&error); +@@ -89,12 +89,12 @@ Tile& TileBuffer::getTile(int x, int y, GTask* task, + GThreadPool* lokThreadPool) + { + int index = x * m_nWidth + y; +- GError* error = NULL; ++ GError* error = nullptr; + + if (m_mTiles.find(index) != m_mTiles.end() && !m_mTiles[index].valid) + { + g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_PAINT_TILE: %s", error->message); + g_clear_error(&error); +@@ -104,7 +104,7 @@ Tile& TileBuffer::getTile(int x, int y, GTask* task, + else if(m_mTiles.find(index) == m_mTiles.end()) + { + g_thread_pool_push(lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_PAINT_TILE: %s", error->message); + g_clear_error(&error); +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 9407257e5fec..5482ea2b2825 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -58,7 +58,7 @@ GQuark LOKTileBufferErrorQuark(void); + class Tile + { + public: +- Tile() : valid(false), m_pBuffer(0) {} ++ Tile() : valid(false), m_pBuffer(nullptr) {} + ~Tile() + { + g_clear_object(&m_pBuffer); +@@ -92,7 +92,7 @@ private: + class TileBuffer + { + public: +- TileBuffer(LibreOfficeKitDocument *document = 0, ++ TileBuffer(LibreOfficeKitDocument *document = nullptr, + int columns = 0) + : m_pLOKDocument(document) + , m_nWidth(columns) +@@ -236,10 +236,10 @@ struct LOEvent + /// Constructor to instantiate an object of type `type`. + LOEvent(int type) + : m_nType(type) +- , m_pCommand(0) +- , m_pArguments(0) ++ , m_pCommand(nullptr) ++ , m_pArguments(nullptr) + , m_bNotifyWhenFinished(false) +- , m_pPath(0) ++ , m_pPath(nullptr) + , m_bEdit(false) + , m_nPartMode(0) + , m_nPart(0) +-- +2.12.0 + diff --git a/SOURCES/0293-Keep-LibreOfficeKit.hxx-compatible-with-C-03.patch b/SOURCES/0293-Keep-LibreOfficeKit.hxx-compatible-with-C-03.patch new file mode 100644 index 0000000..85b7373 --- /dev/null +++ b/SOURCES/0293-Keep-LibreOfficeKit.hxx-compatible-with-C-03.patch @@ -0,0 +1,117 @@ +From 994720658cfc4e3e82493ca5ef1859cc0b42960c Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 10 Nov 2015 11:08:30 +0100 +Subject: [PATCH 293/398] Keep LibreOfficeKit.hxx compatible with C++03 + +Change-Id: Ic2f123c9b341dbb421b766c3bba1fc56c1bfb41d +(cherry picked from commit 1cd6e2e08eba3bc55fbf6dda3cd3d19a5d95f798) +--- + compilerplugins/clang/store/nullptr.cxx | 9 +++++++++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 20 ++++++++++---------- + 2 files changed, 19 insertions(+), 10 deletions(-) + +diff --git a/compilerplugins/clang/store/nullptr.cxx b/compilerplugins/clang/store/nullptr.cxx +index 528bb6aac9bc..83812d0ccd49 100644 +--- a/compilerplugins/clang/store/nullptr.cxx ++++ b/compilerplugins/clang/store/nullptr.cxx +@@ -42,6 +42,8 @@ public: + bool VisitImplicitCastExpr(CastExpr const * expr); + + private: ++ bool isInLokIncludeFile(SourceLocation spellingLocation) const; ++ + bool isFromCIncludeFile(SourceLocation spellingLocation) const; + + bool isMacroBodyExpansion(SourceLocation location) const; +@@ -134,6 +136,8 @@ bool Nullptr::VisitImplicitCastExpr(CastExpr const * expr) { + ((!compiler.getLangOpts().CPlusPlus + || isInUnoIncludeFile( + compiler.getSourceManager().getSpellingLoc(loc)) ++ || isInLokIncludeFile( ++ compiler.getSourceManager().getSpellingLoc(loc)) + || isFromCIncludeFile( + compiler.getSourceManager().getSpellingLoc(loc))) + ? "NULL" : "nullptr")); +@@ -143,6 +147,11 @@ bool Nullptr::VisitImplicitCastExpr(CastExpr const * expr) { + return true; + } + ++bool Nullptr::isInLokIncludeFile(SourceLocation spellingLocation) const { ++ return compiler.getSourceManager().getFilename(spellingLocation) ++ .startswith(SRCDIR "/include/LibreOfficeKit/"); ++} ++ + bool Nullptr::isFromCIncludeFile(SourceLocation spellingLocation) const { + return !compat::isInMainFile(compiler.getSourceManager(), spellingLocation) + && (StringRef( +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index dde371ddc95b..ec48d39368e3 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -47,7 +47,7 @@ public: + * @param pFormat the format to use while exporting, when omitted, then deducted from pURL's extension + * @param pFilterOptions options for the export filter, e.g. SkipImages. + */ +- inline bool saveAs(const char* pUrl, const char* pFormat = nullptr, const char* pFilterOptions = nullptr) ++ inline bool saveAs(const char* pUrl, const char* pFormat = NULL, const char* pFilterOptions = NULL) + { + return mpDoc->pClass->saveAs(mpDoc, pUrl, pFormat, pFilterOptions) != 0; + } +@@ -220,7 +220,7 @@ public: + * @param pCommand uno command to be posted to the document, like ".uno:Bold" + * @param pArguments arguments of the uno command. + */ +- inline void postUnoCommand(const char* pCommand, const char* pArguments = nullptr, bool bNotifyWhenFinished = false) ++ inline void postUnoCommand(const char* pCommand, const char* pArguments = NULL, bool bNotifyWhenFinished = false) + { + mpDoc->pClass->postUnoCommand(mpDoc, pCommand, pArguments, bNotifyWhenFinished); + } +@@ -243,7 +243,7 @@ public: + * @param pMimeType suggests the return format, for example text/plain;charset=utf-8. + * @param pUsedMimeType output parameter to inform about the determined format (suggested one or plain text). + */ +- inline char* getTextSelection(const char* pMimeType, char** pUsedMimeType = nullptr) ++ inline char* getTextSelection(const char* pMimeType, char** pUsedMimeType = NULL) + { + return mpDoc->pClass->getTextSelection(mpDoc, pMimeType, pUsedMimeType); + } +@@ -361,17 +361,17 @@ public: + * @param pUrl the URL of the document to load + * @param pFilterOptions options for the import filter, e.g. SkipImages. + */ +- inline Document* documentLoad(const char* pUrl, const char* pFilterOptions = nullptr) ++ inline Document* documentLoad(const char* pUrl, const char* pFilterOptions = NULL) + { +- LibreOfficeKitDocument* pDoc = nullptr; ++ LibreOfficeKitDocument* pDoc = NULL; + + if (LIBREOFFICEKIT_HAS(mpThis, documentLoadWithOptions)) + pDoc = mpThis->pClass->documentLoadWithOptions(mpThis, pUrl, pFilterOptions); + else + pDoc = mpThis->pClass->documentLoad(mpThis, pUrl); + +- if (pDoc == nullptr) +- return nullptr; ++ if (pDoc == NULL) ++ return NULL; + + return new Document(pDoc); + } +@@ -405,11 +405,11 @@ public: + }; + + /// Factory method to create a lok::Office instance. +-inline Office* lok_cpp_init(const char* pInstallPath, const char* pUserProfilePath = nullptr) ++inline Office* lok_cpp_init(const char* pInstallPath, const char* pUserProfilePath = NULL) + { + LibreOfficeKit* pThis = lok_init_2(pInstallPath, pUserProfilePath); +- if (pThis == nullptr || pThis->pClass->nSize == 0) +- return nullptr; ++ if (pThis == NULL || pThis->pClass->nSize == 0) ++ return NULL; + return new ::lok::Office(pThis); + } + +-- +2.12.0 + diff --git a/SOURCES/0294-Add-a-check-for-non-LIBO_INTERNAL_ONLY-C-03-compatib.patch b/SOURCES/0294-Add-a-check-for-non-LIBO_INTERNAL_ONLY-C-03-compatib.patch new file mode 100644 index 0000000..f8129b0 --- /dev/null +++ b/SOURCES/0294-Add-a-check-for-non-LIBO_INTERNAL_ONLY-C-03-compatib.patch @@ -0,0 +1,96 @@ +From 2ad707f0ab106b238369f9810949f290ab6b9b89 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 10 Nov 2015 13:20:42 +0100 +Subject: [PATCH 294/398] Add a check for non-LIBO_INTERNAL_ONLY, + C++03-compatible LibreOfficeKit.hxx + +Change-Id: I56336b8163de48e424526f5f426c2ad350292627 +(cherry picked from commit b17ca2d4782cea3f4d8576ed29c8760e79fb3a26) +--- + .../CppunitTest_libreofficekit_checkapi.mk | 28 ++++++++++++++++++++++ + libreofficekit/Module_libreofficekit.mk | 4 ++++ + libreofficekit/qa/unit/checkapi.cxx | 22 +++++++++++++++++ + 3 files changed, 54 insertions(+) + create mode 100644 libreofficekit/CppunitTest_libreofficekit_checkapi.mk + create mode 100644 libreofficekit/qa/unit/checkapi.cxx + +diff --git a/libreofficekit/CppunitTest_libreofficekit_checkapi.mk b/libreofficekit/CppunitTest_libreofficekit_checkapi.mk +new file mode 100644 +index 000000000000..600564a2ac13 +--- /dev/null ++++ b/libreofficekit/CppunitTest_libreofficekit_checkapi.mk +@@ -0,0 +1,28 @@ ++# -*- 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,libreofficekit_checkapi)) ++ ++$(eval $(call gb_CppunitTest_add_cxxflags,libreofficekit_checkapi, \ ++ $(gb_CXX03FLAGS) \ ++)) ++ ++$(eval $(call gb_CppunitTest_add_exception_objects,libreofficekit_checkapi, \ ++ libreofficekit/qa/unit/checkapi \ ++)) ++ ++$(eval $(call gb_CppunitTest_set_external_code,libreofficekit_checkapi)) ++ ++ifeq ($(OS),LINUX) ++$(eval $(call gb_CppunitTest_add_libs,libreofficekit_checkapi, \ ++ -ldl \ ++)) ++endif ++ ++# vim: set noet sw=4 ts=4: +diff --git a/libreofficekit/Module_libreofficekit.mk b/libreofficekit/Module_libreofficekit.mk +index 7d1c5ead764e..70cf40b6384e 100644 +--- a/libreofficekit/Module_libreofficekit.mk ++++ b/libreofficekit/Module_libreofficekit.mk +@@ -11,6 +11,10 @@ $(eval $(call gb_Module_Module,libreofficekit)) + + ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) + ++$(eval $(call gb_Module_add_check_targets,libreofficekit, \ ++ CppunitTest_libreofficekit_checkapi \ ++)) ++ + $(eval $(call gb_Module_add_subsequentcheck_targets,libreofficekit,\ + CppunitTest_libreofficekit_tiledrendering \ + )) +diff --git a/libreofficekit/qa/unit/checkapi.cxx b/libreofficekit/qa/unit/checkapi.cxx +new file mode 100644 +index 000000000000..acf00e0b9cb1 +--- /dev/null ++++ b/libreofficekit/qa/unit/checkapi.cxx +@@ -0,0 +1,22 @@ ++/* -*- 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/. ++ */ ++ ++#if defined LIBO_INTERNAL_ONLY ++#error Build system problem; LIBO_INTERNAL_ONLY should not be defined here ++#endif ++ ++#include ++ ++#include ++#include ++#include ++ ++CPPUNIT_PLUGIN_IMPLEMENT(); ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +-- +2.12.0 + diff --git a/SOURCES/0295-Missing-include-for-NULL.patch b/SOURCES/0295-Missing-include-for-NULL.patch new file mode 100644 index 0000000..4c47a77 --- /dev/null +++ b/SOURCES/0295-Missing-include-for-NULL.patch @@ -0,0 +1,27 @@ +From 8a40934a0202b40d4f690fdbe4c0ac28591c8160 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 10 Nov 2015 13:21:28 +0100 +Subject: [PATCH 295/398] Missing include (for NULL) + +Change-Id: I26e448de315b56f36cfeb74a66c0db6a9148d9b0 +(cherry picked from commit 37968fd404ca04333502921e5560f893c7933888) +--- + include/LibreOfficeKit/LibreOfficeKit.hxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index ec48d39368e3..601d3bc147a5 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -10,6 +10,8 @@ + #ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX + #define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKIT_HXX + ++#include ++ + #include "LibreOfficeKit.h" + #include "LibreOfficeKitInit.h" + +-- +2.12.0 + diff --git a/SOURCES/0296-gtktiledviewer-don-t-hide-cursor-after-doc-size-chan.patch b/SOURCES/0296-gtktiledviewer-don-t-hide-cursor-after-doc-size-chan.patch new file mode 100644 index 0000000..4e23372 --- /dev/null +++ b/SOURCES/0296-gtktiledviewer-don-t-hide-cursor-after-doc-size-chan.patch @@ -0,0 +1,35 @@ +From 14e285cf0738a3633812028fddffadcdc7e22e2e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 10 Nov 2015 09:59:36 +0100 +Subject: [PATCH 296/398] gtktiledviewer: don't hide cursor after doc size + changed + +Unconditional call to lok_doc_view_reset_view() resulted in hiding the +cursor, but then nothing enabled it. As a result, the cursor got hidden +after the doc size changed. + +Change-Id: I06e7c9293e7a4cdbc73421a82430816ab0001f90 +(cherry picked from commit 7a87e9718ce8b455c0780ef7606b1c219bf228b5) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 3f57b5c6c6b9..c96ba95e7d99 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -827,8 +827,10 @@ static void changePart( GtkWidget* pSelector, gpointer /* pItem */ ) + TiledWindow& rWindow = lcl_getTiledWindow(pSelector); + + if (rWindow.m_bPartSelectorBroadcast && rWindow.m_pDocView) ++ { + lok_doc_view_set_part( LOK_DOC_VIEW(rWindow.m_pDocView), nPart ); +- lok_doc_view_reset_view(LOK_DOC_VIEW(rWindow.m_pDocView)); ++ lok_doc_view_reset_view(LOK_DOC_VIEW(rWindow.m_pDocView)); ++ } + } + + static void removeChildrenFromStatusbar(GtkWidget* children, gpointer pData) +-- +2.12.0 + diff --git a/SOURCES/0297-sw-lok-fix-width-of-the-notes-sidebar.patch b/SOURCES/0297-sw-lok-fix-width-of-the-notes-sidebar.patch new file mode 100644 index 0000000..2616e27 --- /dev/null +++ b/SOURCES/0297-sw-lok-fix-width-of-the-notes-sidebar.patch @@ -0,0 +1,50 @@ +From b2abef914624cfb7d0fd5f75d098fe37cabaf3d6 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 10 Nov 2015 14:08:26 +0100 +Subject: [PATCH 297/398] sw lok: fix width of the notes sidebar + +The map mode is in general disabled during tiled rendering, so mouse +positions can be sent in using twips, but here we have to temporarily +enable it, otherwise the width will be returned always in pixels. + +With this, the gray background of the sidebar has the proper width, not +e.g. fifteenth of the expected value (using default zoom). + +Change-Id: I4380ee0ba6bcda97cf71735161dbdc826e7a2532 +(cherry picked from commit 6c3dbdbccbcccf914360dac1167599c5b89446a8) +--- + sw/source/uibase/docvw/PostItMgr.cxx | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index 35152d05d242..2310dd64f4de 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -74,6 +74,7 @@ + + #include + #include ++#include + + #include "annotsh.hxx" + #include "swabstdlg.hxx" +@@ -1813,7 +1814,15 @@ unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const + if (bPx) + return aWidth; + else +- return mpEditWin->PixelToLogic(Size( aWidth ,0)).Width(); ++ { ++ bool bEnableMapMode = comphelper::LibreOfficeKit::isActive() && !mpEditWin->IsMapModeEnabled(); ++ if (bEnableMapMode) ++ mpEditWin->EnableMapMode(); ++ long nRet = mpEditWin->PixelToLogic(Size(aWidth, 0)).Width(); ++ if (bEnableMapMode) ++ mpEditWin->EnableMapMode(false); ++ return nRet; ++ } + } + + unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const +-- +2.12.0 + diff --git a/SOURCES/0298-Avoid-Werror-pedantic-when-building-CppunitTest_libr.patch b/SOURCES/0298-Avoid-Werror-pedantic-when-building-CppunitTest_libr.patch new file mode 100644 index 0000000..8774a97 --- /dev/null +++ b/SOURCES/0298-Avoid-Werror-pedantic-when-building-CppunitTest_libr.patch @@ -0,0 +1,33 @@ +From f351aa3ba01945a3219cf4fb0cbb7de01a415dab Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Tue, 10 Nov 2015 14:21:29 +0100 +Subject: [PATCH 298/398] Avoid -Werror=pedantic when building + CppunitTest_libreofficekit_checkapi + +...at least the Linux-deb-x86_64@56-lhm-ubuntu-trusty tinderbox complains that + +> include/LibreOfficeKit/LibreOfficeKitInit.h:223:77: error: ISO C++ forbids casting between pointer-to-function and pointer-to-object [-Werror=pedantic] +> pSym2 = (LokHookFunction2 *) lok_dlsym(dlhandle, "libreofficekit_hook_2"); + +Change-Id: Ibd75a44fcc7da35ea32bde3fd2a300a16493789f +(cherry picked from commit d5f19eb658d8b20619f5591f6de824741e348910) +--- + solenv/gbuild/platform/com_GCC_defs.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/solenv/gbuild/platform/com_GCC_defs.mk b/solenv/gbuild/platform/com_GCC_defs.mk +index a062d8c33e77..05ffd91780cf 100644 +--- a/solenv/gbuild/platform/com_GCC_defs.mk ++++ b/solenv/gbuild/platform/com_GCC_defs.mk +@@ -119,7 +119,7 @@ ifeq ($(COM_GCC_IS_CLANG),TRUE) + gb_CXX03FLAGS := -std=gnu++98 -Werror=c++11-extensions -Wno-c++11-long-long \ + -Wno-deprecated-declarations + else +-gb_CXX03FLAGS := -std=gnu++98 -pedantic-errors -Wno-long-long \ ++gb_CXX03FLAGS := -std=gnu++98 -Wno-long-long \ + -Wno-variadic-macros -Wno-non-virtual-dtor -Wno-deprecated-declarations + endif + +-- +2.12.0 + diff --git a/SOURCES/0299-sw-lok-fix-length-of-the-line-overlay-above-the-note.patch b/SOURCES/0299-sw-lok-fix-length-of-the-line-overlay-above-the-note.patch new file mode 100644 index 0000000..f4806e2 --- /dev/null +++ b/SOURCES/0299-sw-lok-fix-length-of-the-line-overlay-above-the-note.patch @@ -0,0 +1,41 @@ +From 7f5920e44431b79eb9961e9ca07b322dbaf9e8c7 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 10 Nov 2015 19:29:22 +0100 +Subject: [PATCH 299/398] sw lok: fix length of the line overlay above the + notes + +With this, e.g. a line above a note (with width of 180 px) is also 180 +px, not 12 px. + +Change-Id: I7c4eeda1bc904242dc298013411b9671ba0f2149 +(cherry picked from commit 096408073c2de484cba3736d13b57d22b7f48775) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index e3e238715365..4975513ffc34 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -606,6 +606,18 @@ void SwSidebarWin::SetPosAndSize() + break; + } + ++ // LOK has map mode disabled, and we still want to perform pixel -> ++ // twips conversion for the size of the line above the note. ++ bool bEnableMapMode = comphelper::LibreOfficeKit::isActive() && !EditWin().IsMapModeEnabled(); ++ if (bEnableMapMode) ++ EditWin().EnableMapMode(); ++ Size aSize(aLineEnd.getX() - aLineStart.getX(), aLineEnd.getY() - aLineStart.getY()); ++ aSize = EditWin().PixelToLogic(aSize); ++ aLineEnd = aLineStart; ++ aLineEnd.Move(aSize.getWidth(), aSize.getHeight()); ++ if (bEnableMapMode) ++ EditWin().EnableMapMode(false); ++ + if (!IsPreview()) + { + if (mpAnchor) +-- +2.12.0 + diff --git a/SOURCES/0300-This-PixelToLogic-call-can-be-conditional-in-SwSideb.patch b/SOURCES/0300-This-PixelToLogic-call-can-be-conditional-in-SwSideb.patch new file mode 100644 index 0000000..aa15075 --- /dev/null +++ b/SOURCES/0300-This-PixelToLogic-call-can-be-conditional-in-SwSideb.patch @@ -0,0 +1,44 @@ +From d2d19cf40a111c588489876038cb5e5c23908175 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 10 Nov 2015 20:08:49 +0100 +Subject: [PATCH 300/398] This PixelToLogic() call can be conditional in + SwSidebarWin::SetPosAndSize() + +It is only needed when tiled rendering. + +Change-Id: Ie1668f5f3d4d17abc212e2262a6c155dcb855d2e +(cherry picked from commit 88f4866803fc766503292252cb36af4a70ea98fd) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 4975513ffc34..202a96767a39 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -608,15 +608,15 @@ void SwSidebarWin::SetPosAndSize() + + // LOK has map mode disabled, and we still want to perform pixel -> + // twips conversion for the size of the line above the note. +- bool bEnableMapMode = comphelper::LibreOfficeKit::isActive() && !EditWin().IsMapModeEnabled(); +- if (bEnableMapMode) ++ if (comphelper::LibreOfficeKit::isActive() && !EditWin().IsMapModeEnabled()) ++ { + EditWin().EnableMapMode(); +- Size aSize(aLineEnd.getX() - aLineStart.getX(), aLineEnd.getY() - aLineStart.getY()); +- aSize = EditWin().PixelToLogic(aSize); +- aLineEnd = aLineStart; +- aLineEnd.Move(aSize.getWidth(), aSize.getHeight()); +- if (bEnableMapMode) ++ Size aSize(aLineEnd.getX() - aLineStart.getX(), aLineEnd.getY() - aLineStart.getY()); ++ aSize = EditWin().PixelToLogic(aSize); ++ aLineEnd = aLineStart; ++ aLineEnd.Move(aSize.getWidth(), aSize.getHeight()); + EditWin().EnableMapMode(false); ++ } + + if (!IsPreview()) + { +-- +2.12.0 + diff --git a/SOURCES/0301-sd-lok-ccu-1295-force-async-image-swap.patch b/SOURCES/0301-sd-lok-ccu-1295-force-async-image-swap.patch new file mode 100644 index 0000000..48d2311 --- /dev/null +++ b/SOURCES/0301-sd-lok-ccu-1295-force-async-image-swap.patch @@ -0,0 +1,51 @@ +From a181b9e9cf669742278668dc66d6296d506962cf Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 10 Nov 2015 19:45:13 +0100 +Subject: [PATCH 301/398] sd lok: ccu#1295 force async image swap + +This helps ensure that images are swapped in when we actually +render tiles. Previously we'd sometimes have placeholders +instead of the image, which results in either an invalidate +(+rerender of that tile) once the image is swapped in (for +normal tiles) or a permanently missing image in the preview tiles. + +Change-Id: I1a16a913faf9fad20e40a5d1aad3de187038c7a2 +Reviewed-on: https://gerrit.libreoffice.org/19890 +Reviewed-by: Andrzej Hunt +Tested-by: Andrzej Hunt +(cherry picked from commit 9125dbaf5db5bfb07f93be2cfedf43452a28ae32) +--- + sd/source/ui/unoidl/unomodel.cxx | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index d2c6b5e37603..9475ff56c505 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2380,14 +2380,21 @@ void SdXImpressDocument::initializeForTiledRendering() + + mpDoc->setTiledRendering(true); + +- // Disable map mode, so that it's possible to send mouse event coordinates +- // in logic units. + if (DrawViewShell* pViewShell = GetViewShell()) + { ++ // Disable map mode, so that it's possible to send mouse event coordinates ++ // in logic units. + if (sd::Window* pWindow = pViewShell->GetActiveWindow()) + { + pWindow->EnableMapMode(false); + } ++ ++ // Forces all images to be swapped in synchronously, this ++ // ensures that images are available when paintTile is called ++ // (whereas with async loading images start being loaded after ++ // we have painted the tile, resulting in an invalidate, followed ++ // by the tile being rerendered - which is wasteful and ugly). ++ pViewShell->GetDrawView()->SetSwapAsynchron(false); + } + // tdf#93154: in tiled rendering LO doesn't always detect changes + SvtMiscOptions aMiscOpt; +-- +2.12.0 + diff --git a/SOURCES/0302-Implement-LOK_CALLBACK_MOUSE_POINTER.patch b/SOURCES/0302-Implement-LOK_CALLBACK_MOUSE_POINTER.patch new file mode 100644 index 0000000..c29e1b2 --- /dev/null +++ b/SOURCES/0302-Implement-LOK_CALLBACK_MOUSE_POINTER.patch @@ -0,0 +1,273 @@ +From d9ec8bc53bdd81ba9ef71fdd3783522f9fd6c8f8 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Wed, 11 Nov 2015 10:05:25 +0100 +Subject: [PATCH 302/398] Implement LOK_CALLBACK_MOUSE_POINTER + +Change-Id: I8d1f63208baf277b0a9d15908f3ea7ff3b56bf10 +Reviewed-on: https://gerrit.libreoffice.org/19883 +Reviewed-by: Andrzej Hunt +Tested-by: Andrzej Hunt +(cherry picked from commit 81b8ca683d44ba9c37f2dc8c74470a86ce70513f) +--- + desktop/source/lib/init.cxx | 69 ++++++++++++++++++++++++++++ + include/LibreOfficeKit/LibreOfficeKitEnums.h | 9 +++- + include/vcl/ITiledRenderable.hxx | 3 ++ + sc/inc/docuno.hxx | 3 ++ + sc/source/ui/unoobj/docuno.cxx | 15 ++++++ + sd/source/ui/inc/unomodel.hxx | 2 + + sd/source/ui/unoidl/unomodel.cxx | 14 ++++++ + sw/inc/unotxdoc.hxx | 2 + + sw/source/uibase/uno/unotxdoc.cxx | 11 +++++ + 9 files changed, 127 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 2e6e7e73df1a..ddd7859426e7 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -65,6 +65,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -173,6 +174,58 @@ static const ExtensionMap aDrawExtensionMap[] = + { NULL, NULL } + }; + ++/* ++ * Map directly to css cursor styles to avoid further mapping in the client. ++ * Gtk (via gdk_cursor_new_from_name) also supports the same css cursor styles. ++ * ++ * This was created partially with help of the mappings in gtkdata.cxx. ++ * The list is incomplete as some cursor style simply aren't supported ++ * by css, it might turn out to be worth mapping some of these missing cursors ++ * to available cursors? ++ */ ++static const std::map aPointerMap { ++ { PointerStyle::Arrow, "default" }, ++ // PointerStyle::Null ? ++ { PointerStyle::Wait, "wait" }, ++ { PointerStyle::Text, "text" }, ++ { PointerStyle::Help, "help" }, ++ { PointerStyle::Cross, "crosshair" }, ++ { PointerStyle::Move, "move" }, ++ { PointerStyle::NSize, "n-resize" }, ++ { PointerStyle::SSize, "s-resize" }, ++ { PointerStyle::WSize, "w-resize" }, ++ { PointerStyle::ESize, "e-resize" }, ++ { PointerStyle::NWSize, "ne-resize" }, ++ { PointerStyle::NESize, "ne-resize" }, ++ { PointerStyle::SWSize, "sw-resize" }, ++ { PointerStyle::SESize, "se-resize" }, ++ // WindowNSize through WindowSESize ++ { PointerStyle::HSplit, "col-resize" }, ++ { PointerStyle::VSplit, "row-resize" }, ++ { PointerStyle::HSizeBar, "col-resize" }, ++ { PointerStyle::VSizeBar, "row-resize" }, ++ { PointerStyle::Hand, "grab" }, ++ { PointerStyle::RefHand, "grabbing" }, ++ // Pen, Magnify, Fill, Rotate ++ // HShear, VShear ++ // Mirror, Crook, Crop, MovePoint, MoveBezierWeight ++ // MoveData ++ { PointerStyle::CopyData, "copy" }, ++ { PointerStyle::LinkData, "alias" }, ++ // MoveDataLink, CopyDataLink ++ //MoveFile, CopyFile, LinkFile ++ // MoveFileLink, CopyFileLink, MoveFiless, CopyFiles ++ { PointerStyle::NotAllowed, "not-allowed" }, ++ // DrawLine through DrawCaption ++ // Chart, Detective, PivotCol, PivotRow, PivotField, Chain, ChainNotAllowed ++ // TimeEventMove, TimeEventSize ++ // AutoScrollN through AutoScrollNSWE ++ // Airbrush ++ { PointerStyle::TextVertical, "vertical-text" } ++ // Pivot Delete, TabSelectS through TabSelectSW ++ // PaintBrush, HideWhiteSpace, ShowWhiteSpace ++}; ++ + static OUString getUString(const char* pString) + { + if (pString == NULL) +@@ -1039,6 +1092,22 @@ static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX, + } + + pDoc->postMouseEvent(nType, nX, nY, nCount, nButtons, nModifier); ++ ++ Pointer aPointer = pDoc->getPointer(); ++ ++ // We don't map all possible pointers hence we need a default ++ OString aPointerString = "default"; ++ auto aIt = aPointerMap.find(aPointer.GetStyle()); ++ if (aIt != aPointerMap.end()) ++ { ++ aPointerString = aIt->second; ++ } ++ ++ LibLODocument_Impl* pLib = static_cast(pThis); ++ if (pLib->mpCallback && pLib->mpCallbackData) ++ { ++ pLib->mpCallback(LOK_CALLBACK_MOUSE_POINTER, aPointerString.getStr(), pLib->mpCallbackData); ++ } + } + + static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY) +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index bf6267585a0a..37837ea49b86 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -202,7 +202,14 @@ typedef enum + * + * Rectangle format is the same as LOK_CALLBACK_INVALIDATE_TILES. + */ +- LOK_CALLBACK_CELL_CURSOR ++ LOK_CALLBACK_CELL_CURSOR, ++ ++ /** ++ * The current mouse pointer style. ++ * ++ * Payload is a css mouse pointer style. ++ */ ++ LOK_CALLBACK_MOUSE_POINTER + } + LibreOfficeKitCallbackType; + +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index 963f1fc7054a..bf0aa55e32a6 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -14,6 +14,7 @@ + #define LOK_USE_UNSTABLE_API + #include + #include ++#include + #include + + namespace vcl +@@ -171,6 +172,8 @@ public: + return OString(); + } + ++ virtual Pointer getPointer() = 0; ++ + /// Sets the clipboard of the component. + virtual void setClipboard(const css::uno::Reference& xClipboard) = 0; + +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index 70f61ca03548..b73eb12704be 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -430,6 +430,9 @@ public: + int nOutputHeight, + long nTileWidth, + long nTileHeight ) override; ++ ++ /// @see vcl::ITiledRenderable::getPointer(). ++ virtual Pointer getPointer() override; + }; + + class ScDrawPagesObj : public cppu::WeakImplHelper2< +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index 66794f3c6f27..0e5396e5910e 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -903,6 +903,21 @@ OString ScModelObj::getCellCursor( int nOutputWidth, int nOutputHeight, + return "{ \"commandName\": \".uno:CellCursor\", \"commandValues\": \"" + pGridWindow->getCellCursor( nOutputWidth, nOutputHeight, nTileWidth, nTileHeight ) + "\" }"; + } + ++Pointer ScModelObj::getPointer() ++{ ++ SolarMutexGuard aGuard; ++ ++ ScViewData* pViewData = ScDocShell::GetViewData(); ++ if (!pViewData) ++ return Pointer(); ++ ++ ScGridWindow* pGridWindow = pViewData->GetActiveWin(); ++ if (!pGridWindow) ++ return Pointer(); ++ ++ return pGridWindow->GetPointer(); ++} ++ + void ScModelObj::initializeForTiledRendering() + { + SolarMutexGuard aGuard; +diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx +index 8178aab1f1fa..1c444dd478bf 100644 +--- a/sd/source/ui/inc/unomodel.hxx ++++ b/sd/source/ui/inc/unomodel.hxx +@@ -262,6 +262,8 @@ public: + virtual void setClipboard(const css::uno::Reference& xClipboard) override; + /// @see vcl::ITiledRenderable::isMimeTypeSupported(). + virtual bool isMimeTypeSupported() override; ++ /// @see vcl::ITiledRenderable::getPointer(). ++ virtual Pointer getPointer() override; + + // XComponent + +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 9475ff56c505..28ca11878044 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2568,6 +2568,20 @@ bool SdXImpressDocument::isMimeTypeSupported() + return EditEngine::HasValidData(aDataHelper.GetTransferable()); + } + ++Pointer SdXImpressDocument::getPointer() ++{ ++ SolarMutexGuard aGuard; ++ DrawViewShell* pViewShell = GetViewShell(); ++ if (!pViewShell) ++ return Pointer(); ++ ++ Window* pWindow = pViewShell->GetActiveWindow(); ++ if (!pWindow) ++ return Pointer(); ++ ++ return pWindow->GetPointer(); ++} ++ + uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable() + { + uno::Reference< i18n::XForbiddenCharacters > xForb(mxForbidenCharacters); +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index 85605d56c60f..e8cb116bb671 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -438,6 +438,8 @@ public: + virtual void setClipboard(const css::uno::Reference& xClipboard) override; + /// @see vcl::ITiledRenderable::isMimeTypeSupported(). + virtual bool isMimeTypeSupported() override; ++ /// @see vcl::ITiledRenderable::getPointer(). ++ virtual Pointer getPointer() override; + + // ::com::sun::star::tiledrendering::XTiledRenderable + virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) throw (::css::uno::RuntimeException, ::std::exception) SAL_OVERRIDE; +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 4de023d1275c..53bb2506928b 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3214,6 +3214,17 @@ bool SwXTextDocument::isMimeTypeSupported() + return aDataHelper.GetXTransferable().is() && SwTransferable::IsPaste(*pWrtShell, aDataHelper); + } + ++Pointer SwXTextDocument::getPointer() ++{ ++ SolarMutexGuard aGuard; ++ ++ SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); ++ if (!pWrtShell) ++ return Pointer(); ++ ++ return pWrtShell->GetView().GetEditWin().GetPointer(); ++} ++ + int SwXTextDocument::getPart() + { + SolarMutexGuard aGuard; +-- +2.12.0 + diff --git a/SOURCES/0303-lokdocview-support-LOK_CALLBACK_MOUSE_POINTER.patch b/SOURCES/0303-lokdocview-support-LOK_CALLBACK_MOUSE_POINTER.patch new file mode 100644 index 0000000..688368c --- /dev/null +++ b/SOURCES/0303-lokdocview-support-LOK_CALLBACK_MOUSE_POINTER.patch @@ -0,0 +1,46 @@ +From b077183a4d3005427949a6b60fa8aafda4d088c8 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Tue, 10 Nov 2015 11:40:41 +0100 +Subject: [PATCH 303/398] lokdocview: support LOK_CALLBACK_MOUSE_POINTER + +Change-Id: I2052e39fa2e25988a40f293389d5a183a625acd4 +Reviewed-on: https://gerrit.libreoffice.org/19903 +Reviewed-by: Andrzej Hunt +Tested-by: Andrzej Hunt +(cherry picked from commit cc920bc27a0c37233d65ee1b20712e3ac6896c9a) +--- + libreofficekit/source/gtk/lokdocview.cxx | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 0d1dec1ddb05..687323d6ca11 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -282,6 +282,8 @@ callbackTypeToString (int nType) + return "LOK_CALLBACK_CELL_CURSOR"; + case LOK_CALLBACK_HYPERLINK_CLICKED: + return "LOK_CALLBACK_HYPERLINK_CLICKED"; ++ case LOK_CALLBACK_MOUSE_POINTER: ++ return "LOK_CALLBACK_MOUSE_POINTER"; + case LOK_CALLBACK_STATE_CHANGED: + return "LOK_CALLBACK_STATE_CHANGED"; + case LOK_CALLBACK_STATUS_INDICATOR_START: +@@ -736,6 +738,15 @@ callback (gpointer pData) + priv->m_bCursorVisible = pCallback->m_aPayload == "true"; + } + break; ++ case LOK_CALLBACK_MOUSE_POINTER: ++ { ++ // The gtk docs claim that most css cursors should be supported, however ++ // on my system at least this is not true and many cursors are unsupported. ++ // In this case pCursor = null, which results in the default cursor being set. ++ GdkCursor* pCursor = gdk_cursor_new_from_name(gtk_widget_get_display(GTK_WIDGET(pDocView)), pCallback->m_aPayload.c_str()); ++ gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(pDocView)), pCursor); ++ } ++ break; + case LOK_CALLBACK_GRAPHIC_SELECTION: + { + if (pCallback->m_aPayload != "EMPTY") +-- +2.12.0 + diff --git a/SOURCES/0304-sw-lok-fix-sidebarwindows-SwSidebarWin-pixel-positio.patch b/SOURCES/0304-sw-lok-fix-sidebarwindows-SwSidebarWin-pixel-positio.patch new file mode 100644 index 0000000..7e6f673 --- /dev/null +++ b/SOURCES/0304-sw-lok-fix-sidebarwindows-SwSidebarWin-pixel-positio.patch @@ -0,0 +1,61 @@ +From 2d49f2112eacd2e65405505ccabf8d6b8d4c94ab Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 11 Nov 2015 18:05:45 +0100 +Subject: [PATCH 304/398] sw lok: fix sidebarwindows::SwSidebarWin pixel + position + +So SwSidebarWin member functions don't get twip values when they call +GetPosPixel(). + +Change-Id: Ied4ff7f49d0320766b045d78f731900af92d37ef +(cherry picked from commit c4ef30ea916752ba5a057b49960a60a55f70c84c) +--- + sw/source/uibase/docvw/PostItMgr.cxx | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index 2310dd64f4de..2a2e5d596056 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -593,6 +593,10 @@ void SwPostItMgr::PreparePageContainer() + + void SwPostItMgr::LayoutPostIts() + { ++ bool bEnableMapMode = comphelper::LibreOfficeKit::isActive() && !mpEditWin->IsMapModeEnabled(); ++ if (bEnableMapMode) ++ mpEditWin->EnableMapMode(); ++ + if ( !mvPostItFields.empty() && !mbWaitingForCalcRects ) + { + mbLayouting = true; +@@ -809,6 +813,9 @@ void SwPostItMgr::LayoutPostIts() + + mbLayouting = false; + } ++ ++ if (bEnableMapMode) ++ mpEditWin->EnableMapMode(false); + } + + bool SwPostItMgr::BorderOverPageBorder(unsigned long aPage) const +@@ -856,6 +863,8 @@ void SwPostItMgr::PaintTile(OutputDevice& rRenderContext, const Rectangle& /*rRe + if (!pPostIt) + continue; + ++ bool bEnableMapMode = !mpEditWin->IsMapModeEnabled(); ++ mpEditWin->EnableMapMode(); + rRenderContext.Push(PushFlags::MAPMODE); + Point aOffset(mpEditWin->PixelToLogic(pPostIt->GetPosPixel())); + MapMode aMapMode(rRenderContext.GetMapMode()); +@@ -867,6 +876,8 @@ void SwPostItMgr::PaintTile(OutputDevice& rRenderContext, const Rectangle& /*rRe + pPostIt->PaintTile(rRenderContext, aRectangle); + + rRenderContext.Pop(); ++ if (bEnableMapMode) ++ mpEditWin->EnableMapMode(false); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0305-lok-add-Clear-formatting-to-getStyles.patch b/SOURCES/0305-lok-add-Clear-formatting-to-getStyles.patch new file mode 100644 index 0000000..af06bb5 --- /dev/null +++ b/SOURCES/0305-lok-add-Clear-formatting-to-getStyles.patch @@ -0,0 +1,84 @@ +From 9b04a64c64b30faab0cec6c552589940181a4fa1 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Wed, 11 Nov 2015 17:09:47 +0100 +Subject: [PATCH 305/398] lok: add Clear formatting to getStyles() + +This requires client-side support too. + +Change-Id: I5197ed3ed2b8244b50f7faf84a1cadde6a61b2cb +Reviewed-on: https://gerrit.libreoffice.org/19917 +Reviewed-by: Andrzej Hunt +Tested-by: Andrzej Hunt +(cherry picked from commit 0b5991e4862501f0fa8e34f1b403aca40e51436f) +--- + desktop/Library_sofficeapp.mk | 1 + + desktop/qa/desktop_lib/test_desktop_lib.cxx | 8 ++++++-- + desktop/source/lib/init.cxx | 8 ++++++++ + 3 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk +index fb73cfa78f4b..f0c99eee6078 100644 +--- a/desktop/Library_sofficeapp.mk ++++ b/desktop/Library_sofficeapp.mk +@@ -52,6 +52,7 @@ $(eval $(call gb_Library_use_libraries,sofficeapp,\ + sb \ + sfx \ + svl \ ++ svxcore \ + svt \ + tk \ + tl \ +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index df803c4bdaf0..83bd5ac620b4 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -181,14 +181,18 @@ void DesktopLOKTest::testGetStyles() + CPPUNIT_ASSERT( aValues.size() > 0 ); + for (const std::pair& rPair : aValues) + { +- CPPUNIT_ASSERT( rPair.second.size() > 0); ++ if( rPair.first != "ClearStyle") ++ { ++ CPPUNIT_ASSERT( rPair.second.size() > 0); ++ } + if (rPair.first != "CharacterStyles" && + rPair.first != "ParagraphStyles" && + rPair.first != "FrameStyles" && + rPair.first != "PageStyles" && + rPair.first != "NumberingStyles" && + rPair.first != "CellStyles" && +- rPair.first != "ShapeStyles") ++ rPair.first != "ShapeStyles" && ++ rPair.first != "ClearStyle") + { + CPPUNIT_FAIL("Unknown style family: " + rPair.first); + } +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index ddd7859426e7..b7459e03244c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -58,6 +58,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -1265,6 +1267,12 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + } + aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren); + } ++ ++ boost::property_tree::ptree aChildClearFormat; ++ OUString sClearFormat = SVX_RESSTR( RID_SVXSTR_CLEARFORM ); ++ aChildClearFormat.put("", sClearFormat.toUtf8()); ++ aValues.add_child("ClearStyle", aChildClearFormat); ++ + aTree.add_child("commandValues", aValues); + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); +-- +2.12.0 + diff --git a/SOURCES/0306-lok-sw-Place-default-styles-at-top-of-style-selector.patch b/SOURCES/0306-lok-sw-Place-default-styles-at-top-of-style-selector.patch new file mode 100644 index 0000000..57b17a5 --- /dev/null +++ b/SOURCES/0306-lok-sw-Place-default-styles-at-top-of-style-selector.patch @@ -0,0 +1,72 @@ +From 9ec2ecca18e0ac62c5a9a0fcd628c6dde610e174 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Wed, 11 Nov 2015 21:07:13 +0100 +Subject: [PATCH 306/398] lok sw: Place default styles at top of style selector + +The order/list of default styles for Writer should be hardcoded, +(by default the list contains 100+ items), it makes most sense to +place these at the start of the list, allowing the client to then +select how many styles they actually want to show. + +Change-Id: I491a426397e06b3502cee7484c5f8adfd9d9cdf2 +Reviewed-on: https://gerrit.libreoffice.org/19918 +Reviewed-by: Andrzej Hunt +Tested-by: Andrzej Hunt +(cherry picked from commit 5c6119eeaaaed322c884504a53bb558258233fe9) +--- + desktop/source/lib/init.cxx | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index b7459e03244c..e09ad171678e 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1252,12 +1252,45 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + uno::Reference xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); + uno::Sequence aStyleFamilies = xStyleFamilies->getElementNames(); + ++ static const sal_Char* aWriterStyles[] = ++ { ++ "Text body", ++ "Quotations", ++ "Title", ++ "Subtitle", ++ "Heading 1", ++ "Heading 2", ++ "Heading 3" ++ }; ++ + boost::property_tree::ptree aValues; + for (sal_Int32 nStyleFam = 0; nStyleFam < aStyleFamilies.getLength(); ++nStyleFam) + { + boost::property_tree::ptree aChildren; + OUString sStyleFam = aStyleFamilies[nStyleFam]; + uno::Reference xStyleFamily(xStyleFamilies->getByName(sStyleFam), uno::UNO_QUERY); ++ ++ // Writer provides a huge number of styles, we have a list of 7 "default" styles which ++ // should be shown in the normal dropdown, which we should add to the start of the list ++ // to simplify their selection. ++ if (sStyleFam == "ParagraphStyles" ++ && doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT) ++ { ++ for( sal_uInt32 nStyle = 0; nStyle < sizeof( aWriterStyles ) / sizeof( sal_Char*); ++nStyle ) ++ { ++ uno::Reference< beans::XPropertySet > xStyle; ++ xStyleFamily->getByName( OUString::createFromAscii( aWriterStyles[nStyle] )) >>= xStyle; ++ OUString sName; ++ xStyle->getPropertyValue("DisplayName") >>= sName; ++ if( !sName.isEmpty() ) ++ { ++ boost::property_tree::ptree aChild; ++ aChild.put("", sName.toUtf8()); ++ aChildren.push_back(std::make_pair("", aChild)); ++ } ++ } ++ } ++ + uno::Sequence aStyles = xStyleFamily->getElementNames(); + for (sal_Int32 nInd = 0; nInd < aStyles.getLength(); ++nInd) + { +-- +2.12.0 + diff --git a/SOURCES/0307-sw-lok-route-SwEditWin-MouseButtonDown-to-SidebarTex.patch b/SOURCES/0307-sw-lok-route-SwEditWin-MouseButtonDown-to-SidebarTex.patch new file mode 100644 index 0000000..b253ca8 --- /dev/null +++ b/SOURCES/0307-sw-lok-route-SwEditWin-MouseButtonDown-to-SidebarTex.patch @@ -0,0 +1,143 @@ +From 2770d40660412006fec7a5b0441293b89512dadf Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 12 Nov 2015 14:21:03 +0100 +Subject: [PATCH 307/398] sw lok: route SwEditWin::MouseButtonDown to + SidebarTextControl if necessary + +LOK sends all mouse events to SwEditWin, so add initial hit testing in +its mouse handler to forward the mouse events to the right VCL widget. + +(cherry picked from commit b7ecf6279ef3343f12fce776862c027bfeff6617) + +Change-Id: I67e8e19f47156261fd7c7eafd4e63f743e0c4ce9 +--- + sw/inc/PostItMgr.hxx | 6 ++++-- + sw/inc/SidebarWin.hxx | 2 ++ + sw/source/uibase/docvw/PostItMgr.cxx | 31 +++++++++++++++++++++++++++++++ + sw/source/uibase/docvw/SidebarWin.cxx | 8 ++++++++ + sw/source/uibase/docvw/edtwin.cxx | 18 +++++++++++++++++- + 5 files changed, 62 insertions(+), 3 deletions(-) + +diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx +index f306f57ba86c..4356f6daa416 100644 +--- a/sw/inc/PostItMgr.hxx ++++ b/sw/inc/PostItMgr.hxx +@@ -233,8 +233,10 @@ class SwPostItMgr: public SfxListener + Rectangle GetBottomScrollRect(const unsigned long aPage) const; + Rectangle GetTopScrollRect(const unsigned long aPage) const; + +- bool IsHit(const Point &aPointPixel); +- Color GetArrowColor(sal_uInt16 aDirection,unsigned long aPage) const; ++ bool IsHit(const Point &aPointPixel); ++ /// Get the matching window that is responsible for handling mouse events of rPointLogic, if any. ++ vcl::Window* IsHitSidebarWindow(const Point& rPointLogic); ++ Color GetArrowColor(sal_uInt16 aDirection,unsigned long aPage) const; + + sw::annotation::SwAnnotationWin* GetAnnotationWin(const SwPostItField* pField) const; + +diff --git a/sw/inc/SidebarWin.hxx b/sw/inc/SidebarWin.hxx +index d21d50d5d7d5..1eaf982ebf07 100644 +--- a/sw/inc/SidebarWin.hxx ++++ b/sw/inc/SidebarWin.hxx +@@ -179,6 +179,8 @@ class SwSidebarWin : public vcl::Window + + virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) override; + void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); ++ /// Get the matching sub-widget inside this sidebar widget for rPointLogic, if any. ++ vcl::Window* IsHitWindow(const Point& rPointLogic); + + protected: + virtual void DataChanged( const DataChangedEvent& aEvent) SAL_OVERRIDE; +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index 2a2e5d596056..eb5755e20cf9 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -1706,6 +1706,37 @@ bool SwPostItMgr::IsHit(const Point &aPointPixel) + } + return false; + } ++ ++vcl::Window* SwPostItMgr::IsHitSidebarWindow(const Point& rPointLogic) ++{ ++ vcl::Window* pRet = 0; ++ ++ if (HasNotes() && ShowNotes()) ++ { ++ bool bEnableMapMode = !mpEditWin->IsMapModeEnabled(); ++ if (bEnableMapMode) ++ mpEditWin->EnableMapMode(); ++ ++ for (SwSidebarItem* pItem : mvPostItFields) ++ { ++ SwSidebarWin* pPostIt = pItem->pPostIt; ++ if (!pPostIt) ++ continue; ++ ++ if (vcl::Window* pWindow = pPostIt->IsHitWindow(rPointLogic)) ++ { ++ pRet = pWindow; ++ break; ++ } ++ } ++ ++ if (bEnableMapMode) ++ mpEditWin->EnableMapMode(false); ++ } ++ ++ return pRet; ++} ++ + Rectangle SwPostItMgr::GetBottomScrollRect(const unsigned long aPage) const + { + SwRect aPageRect = mPages[aPage-1]->mPageRect; +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 202a96767a39..87a86fbc9dc8 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -280,6 +280,14 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + rRenderContext.Push(PushFlags::NONE); + } + ++vcl::Window* SwSidebarWin::IsHitWindow(const Point& rPointLogic) ++{ ++ Rectangle aRectangleLogic(EditWin().PixelToLogic(GetPosPixel()), EditWin().PixelToLogic(GetSizePixel())); ++ if (aRectangleLogic.IsInside(rPointLogic)) ++ return mpSidebarTextControl; ++ return 0; ++} ++ + void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, sal_uLong nInFlags) + { + if (mpMetadataAuthor->IsVisible() ) +diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx +index f392010fb6b1..b4ed61becbfb 100644 +--- a/sw/source/uibase/docvw/edtwin.cxx ++++ b/sw/source/uibase/docvw/edtwin.cxx +@@ -2756,7 +2756,23 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) + if (m_rView.GetPostItMgr()->IsHit(rMEvt.GetPosPixel())) + return; + +- m_rView.GetPostItMgr()->SetActiveSidebarWin(0); ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel())) ++ { ++ bool bDisableMapMode = pWindow->IsMapModeEnabled(); ++ if (bDisableMapMode) ++ pWindow->EnableMapMode(false); ++ ++ pWindow->MouseButtonDown(rMEvt); ++ ++ if (bDisableMapMode) ++ pWindow->EnableMapMode(); ++ return; ++ } ++ } ++ ++ m_rView.GetPostItMgr()->SetActiveSidebarWin(nullptr); + + GrabFocus(); + +-- +2.12.0 + diff --git a/SOURCES/0308-fix-build.patch b/SOURCES/0308-fix-build.patch new file mode 100644 index 0000000..580defb --- /dev/null +++ b/SOURCES/0308-fix-build.patch @@ -0,0 +1,45 @@ +From ee7c4fb2c32e306342099896c0e367c9f2d33e75 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 20 Mar 2017 17:51:53 +0100 +Subject: [PATCH 308/398] fix build + +Change-Id: I8770c05d39e5574212461d2e48e72ed2fff6a74d +--- + sw/source/uibase/docvw/SidebarWin.cxx | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 87a86fbc9dc8..575be80c0ae0 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -282,7 +282,7 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + + vcl::Window* SwSidebarWin::IsHitWindow(const Point& rPointLogic) + { +- Rectangle aRectangleLogic(EditWin().PixelToLogic(GetPosPixel()), EditWin().PixelToLogic(GetSizePixel())); ++ Rectangle aRectangleLogic(EditWin()->PixelToLogic(GetPosPixel()), EditWin()->PixelToLogic(GetSizePixel())); + if (aRectangleLogic.IsInside(rPointLogic)) + return mpSidebarTextControl; + return 0; +@@ -616,14 +616,14 @@ void SwSidebarWin::SetPosAndSize() + + // LOK has map mode disabled, and we still want to perform pixel -> + // twips conversion for the size of the line above the note. +- if (comphelper::LibreOfficeKit::isActive() && !EditWin().IsMapModeEnabled()) ++ if (comphelper::LibreOfficeKit::isActive() && !EditWin()->IsMapModeEnabled()) + { +- EditWin().EnableMapMode(); ++ EditWin()->EnableMapMode(); + Size aSize(aLineEnd.getX() - aLineStart.getX(), aLineEnd.getY() - aLineStart.getY()); +- aSize = EditWin().PixelToLogic(aSize); ++ aSize = EditWin()->PixelToLogic(aSize); + aLineEnd = aLineStart; + aLineEnd.Move(aSize.getWidth(), aSize.getHeight()); +- EditWin().EnableMapMode(false); ++ EditWin()->EnableMapMode(false); + } + + if (!IsPreview()) +-- +2.12.0 + diff --git a/SOURCES/0309-fix-build.patch b/SOURCES/0309-fix-build.patch new file mode 100644 index 0000000..71fc487 --- /dev/null +++ b/SOURCES/0309-fix-build.patch @@ -0,0 +1,35 @@ +From 32e8771bc155aed821dade81bcf09f3c8d4a76b8 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 20 Mar 2017 18:25:27 +0100 +Subject: [PATCH 309/398] fix build + +Change-Id: I210b8e1b7db8bcf2954d70e9a3cafd51530b1647 +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 83bd5ac620b4..c0ba1599f48b 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -472,7 +472,7 @@ void DesktopLOKTest::testCommandResult() + // the condition var. + m_aCommandResultCondition.reset(); + pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", 0, true); +- m_aCommandResultCondition.wait(aTimeValue); ++ m_aCommandResultCondition.wait(&aTimeValue); + + CPPUNIT_ASSERT(m_aCommandResult.isEmpty()); + +@@ -481,7 +481,7 @@ void DesktopLOKTest::testCommandResult() + + m_aCommandResultCondition.reset(); + pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", 0, true); +- m_aCommandResultCondition.wait(aTimeValue); ++ m_aCommandResultCondition.wait(&aTimeValue); + + boost::property_tree::ptree aTree; + std::stringstream aStream(m_aCommandResult.getStr()); +-- +2.12.0 + diff --git a/SOURCES/0310-lok-send-list-of-commands-instead-of-ClearStyles.patch b/SOURCES/0310-lok-send-list-of-commands-instead-of-ClearStyles.patch new file mode 100644 index 0000000..464ec74 --- /dev/null +++ b/SOURCES/0310-lok-send-list-of-commands-instead-of-ClearStyles.patch @@ -0,0 +1,67 @@ +From 269cad6f5da53600d11157c29f234175bc06e91c Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Thu, 12 Nov 2015 13:50:52 +0100 +Subject: [PATCH 310/398] lok: send list of commands instead of ClearStyles + +We currently send just one command, but this could be expanded +server side in future. + +Change-Id: Id8f14196158f3a7fe9c54595d094603efd5e2ce3 +(cherry picked from commit fbc3965dc117967d2b5f51aa3902823da7c69d12) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 2 +- + desktop/source/lib/init.cxx | 25 +++++++++++++++++++++---- + 2 files changed, 22 insertions(+), 5 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index c0ba1599f48b..7d94daea0fbc 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -192,7 +192,7 @@ void DesktopLOKTest::testGetStyles() + rPair.first != "NumberingStyles" && + rPair.first != "CellStyles" && + rPair.first != "ShapeStyles" && +- rPair.first != "ClearStyle") ++ rPair.first != "Commands") + { + CPPUNIT_FAIL("Unknown style family: " + rPair.first); + } +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index e09ad171678e..dbe30a640ecb 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1301,10 +1301,27 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren); + } + +- boost::property_tree::ptree aChildClearFormat; +- OUString sClearFormat = SVX_RESSTR( RID_SVXSTR_CLEARFORM ); +- aChildClearFormat.put("", sClearFormat.toUtf8()); +- aValues.add_child("ClearStyle", aChildClearFormat); ++ { ++ boost::property_tree::ptree aCommandList; ++ ++ { ++ boost::property_tree::ptree aChild; ++ ++ OUString sClearFormat = SVX_RESSTR( RID_SVXSTR_CLEARFORM ); ++ ++ boost::property_tree::ptree aName; ++ aName.put("", sClearFormat.toUtf8()); ++ aChild.push_back(std::make_pair("text", aName)); ++ ++ boost::property_tree::ptree aCommand; ++ aCommand.put("", ".uno:ResetAttributes"); ++ aChild.push_back(std::make_pair("id", aCommand)); ++ ++ aCommandList.push_back(std::make_pair("", aChild)); ++ } ++ ++ aValues.add_child("Commands", aCommandList); ++ } + + aTree.add_child("commandValues", aValues); + std::stringstream aStream; +-- +2.12.0 + diff --git a/SOURCES/0311-Use-std-vector-instead-of-an-array-of-strings.patch b/SOURCES/0311-Use-std-vector-instead-of-an-array-of-strings.patch new file mode 100644 index 0000000..5780b6c --- /dev/null +++ b/SOURCES/0311-Use-std-vector-instead-of-an-array-of-strings.patch @@ -0,0 +1,51 @@ +From e254c72be43380472dd662d2ec69dfb7eab231b6 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Thu, 12 Nov 2015 14:30:40 +0100 +Subject: [PATCH 311/398] Use std::vector instead of an array of strings + +This makes the code much more readable / sane. + +Change-Id: I1d60f4102b6c619fa2fefac4a3644b7f04c0b9c0 +(cherry picked from commit d5545979fb27e317cce4d374a5a913790d8a2adf) +--- + desktop/source/lib/init.cxx | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index dbe30a640ecb..d724b81f9ac6 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1252,7 +1252,7 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + uno::Reference xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY); + uno::Sequence aStyleFamilies = xStyleFamilies->getElementNames(); + +- static const sal_Char* aWriterStyles[] = ++ static const std::vector aWriterStyles = + { + "Text body", + "Quotations", +@@ -1263,6 +1263,8 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + "Heading 3" + }; + ++ // static const std::vector aList = { "aaaa", "bbb" }; ++ + boost::property_tree::ptree aValues; + for (sal_Int32 nStyleFam = 0; nStyleFam < aStyleFamilies.getLength(); ++nStyleFam) + { +@@ -1276,10 +1278,10 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + if (sStyleFam == "ParagraphStyles" + && doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT) + { +- for( sal_uInt32 nStyle = 0; nStyle < sizeof( aWriterStyles ) / sizeof( sal_Char*); ++nStyle ) ++ for( OUString aStyle: aWriterStyles ) + { + uno::Reference< beans::XPropertySet > xStyle; +- xStyleFamily->getByName( OUString::createFromAscii( aWriterStyles[nStyle] )) >>= xStyle; ++ xStyleFamily->getByName( aStyle ) >>= xStyle; + OUString sName; + xStyle->getPropertyValue("DisplayName") >>= sName; + if( !sName.isEmpty() ) +-- +2.12.0 + diff --git a/SOURCES/0312-More-range-based-for.patch b/SOURCES/0312-More-range-based-for.patch new file mode 100644 index 0000000..c282ea3 --- /dev/null +++ b/SOURCES/0312-More-range-based-for.patch @@ -0,0 +1,27 @@ +From b6f9915a0b3c3dfc687a930dd263c87ccc33315f Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Thu, 12 Nov 2015 14:41:02 +0100 +Subject: [PATCH 312/398] More range based for + +Change-Id: I9cdcd8dca413981389cd4db3059a420131e5f839 +(cherry picked from commit 6e6ae9803796b120e95f6e89575e03c5fd0ed3c2) +--- + desktop/source/lib/init.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index d724b81f9ac6..a51e44591847 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1294,7 +1294,7 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + } + + uno::Sequence aStyles = xStyleFamily->getElementNames(); +- for (sal_Int32 nInd = 0; nInd < aStyles.getLength(); ++nInd) ++ for ( OUString aStyle: aStyles ) + { + boost::property_tree::ptree aChild; + aChild.put("", aStyles[nInd]); +-- +2.12.0 + diff --git a/SOURCES/0313-sw-lok-filter-out-defalt-styles-to-avoid-duplicates.patch b/SOURCES/0313-sw-lok-filter-out-defalt-styles-to-avoid-duplicates.patch new file mode 100644 index 0000000..0d08bb1 --- /dev/null +++ b/SOURCES/0313-sw-lok-filter-out-defalt-styles-to-avoid-duplicates.patch @@ -0,0 +1,57 @@ +From 389a3ba2f6855d22e4802381e6f23d48c9c515bc Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Thu, 12 Nov 2015 14:48:55 +0100 +Subject: [PATCH 313/398] sw lok: filter out defalt styles to avoid duplicates + +Change-Id: Iff84c2f16844a507d30f30c1fd4b23d807ded466 +(cherry picked from commit 0b3fbf8299c51767689b4e7656bbf4c331450b98) +--- + desktop/source/lib/init.cxx | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index a51e44591847..1d56f2e8abae 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1263,7 +1263,10 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + "Heading 3" + }; + +- // static const std::vector aList = { "aaaa", "bbb" }; ++ // We need to keep a list of the default style names ++ // in order to filter these out later when processing ++ // the full list of styles. ++ std::set aDefaultStyleNames; + + boost::property_tree::ptree aValues; + for (sal_Int32 nStyleFam = 0; nStyleFam < aStyleFamilies.getLength(); ++nStyleFam) +@@ -1286,6 +1289,8 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + xStyle->getPropertyValue("DisplayName") >>= sName; + if( !sName.isEmpty() ) + { ++ aDefaultStyleNames.insert( sName ); ++ + boost::property_tree::ptree aChild; + aChild.put("", sName.toUtf8()); + aChildren.push_back(std::make_pair("", aChild)); +@@ -1296,9 +1301,14 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + uno::Sequence aStyles = xStyleFamily->getElementNames(); + for ( OUString aStyle: aStyles ) + { +- boost::property_tree::ptree aChild; +- aChild.put("", aStyles[nInd]); +- aChildren.push_back(std::make_pair("", aChild)); ++ // Filter out the default styles - they are already at the top ++ // of the list ++ if (aDefaultStyleNames.find(aStyle) == aDefaultStyleNames.end()) ++ { ++ boost::property_tree::ptree aChild; ++ aChild.put("", aStyle); ++ aChildren.push_back(std::make_pair("", aChild)); ++ } + } + aValues.add_child(sStyleFam.toUtf8().getStr(), aChildren); + } +-- +2.12.0 + diff --git a/SOURCES/0314-sw-lok-forward-key-events-to-annotation-window-if-ne.patch b/SOURCES/0314-sw-lok-forward-key-events-to-annotation-window-if-ne.patch new file mode 100644 index 0000000..902dfc0 --- /dev/null +++ b/SOURCES/0314-sw-lok-forward-key-events-to-annotation-window-if-ne.patch @@ -0,0 +1,166 @@ +From f9fdb4feeaa51ef9c1e9a87209d4643cb98fa76a Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 12 Nov 2015 16:56:45 +0100 +Subject: [PATCH 314/398] sw lok: forward key events to annotation window if + necessary + +And to allow proper reaction by the annotation windows, inform them when +a LOK callback is registered. + +With this, it's possible to modify the contents of annotations via LOK. + +(cherry picked from commit 1ba9d7fd2a7a3e2b4f52ed0f5efdf7df867b9db3) + +Change-Id: I4489941512197880940e20cbaeb0b47a7a6f26fc +--- + sw/inc/PostItMgr.hxx | 4 ++++ + sw/inc/SidebarWin.hxx | 1 + + sw/source/core/view/viewsh.cxx | 2 ++ + sw/source/uibase/docvw/PostItMgr.cxx | 13 +++++++++++++ + sw/source/uibase/docvw/SidebarTxtControl.hxx | 4 ++-- + sw/source/uibase/docvw/SidebarWin.cxx | 6 ++++++ + sw/source/uibase/docvw/edtwin.cxx | 11 +++++++++++ + 7 files changed, 39 insertions(+), 2 deletions(-) + +diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx +index 4356f6daa416..06f7cc1f1925 100644 +--- a/sw/inc/PostItMgr.hxx ++++ b/sw/inc/PostItMgr.hxx +@@ -34,6 +34,8 @@ + #include + #include + #include ++#define LOK_USE_UNSTABLE_API ++#include + + class OutputDevice; + class SwWrtShell; +@@ -291,6 +293,8 @@ class SwPostItMgr: public SfxListener + + void DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage); + void PaintTile(OutputDevice& rRenderContext, const Rectangle& rRect); ++ /// Informs already created annotations about a newly registered LOK callback. ++ void registerLibreOfficeKitCallback(LibreOfficeKitCallback pCallback, void* pData); + }; + + #endif +diff --git a/sw/inc/SidebarWin.hxx b/sw/inc/SidebarWin.hxx +index 1eaf982ebf07..c41352749c28 100644 +--- a/sw/inc/SidebarWin.hxx ++++ b/sw/inc/SidebarWin.hxx +@@ -178,6 +178,7 @@ class SwSidebarWin : public vcl::Window + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE; + + virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) override; ++ virtual void KeyInput(const KeyEvent& rKeyEvt) override; + void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); + /// Get the matching sub-widget inside this sidebar widget for rPointLogic, if any. + vcl::Window* IsHitWindow(const Point& rPointLogic); +diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx +index fad9dc3552db..963577fb1bd8 100644 +--- a/sw/source/core/view/viewsh.cxx ++++ b/sw/source/core/view/viewsh.cxx +@@ -120,6 +120,8 @@ void SwViewShell::ToggleHeaderFooterEdit() + void SwViewShell::registerLibreOfficeKitCallback(LibreOfficeKitCallback pCallback, void* pData) + { + getIDocumentDrawModelAccess()->GetDrawModel()->registerLibreOfficeKitCallback(pCallback, pData); ++ if (SwPostItMgr* pPostItMgr = GetPostItMgr()) ++ pPostItMgr->registerLibreOfficeKitCallback(pCallback, pData); + } + + void SwViewShell::libreOfficeKitCallback(int nType, const char* pPayload) const +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index eb5755e20cf9..703a433a44ee 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -881,6 +881,19 @@ void SwPostItMgr::PaintTile(OutputDevice& rRenderContext, const Rectangle& /*rRe + } + } + ++void SwPostItMgr::registerLibreOfficeKitCallback(LibreOfficeKitCallback pCallback, void* pData) ++{ ++ for (SwSidebarItem* pItem : mvPostItFields) ++ { ++ SwSidebarWin* pPostIt = pItem->pPostIt; ++ if (!pPostIt) ++ continue; ++ ++ pPostIt->GetOutlinerView()->setTiledRendering(mpWrtShell->isTiledRendering()); ++ pPostIt->GetOutlinerView()->registerLibreOfficeKitCallback(pCallback, pData); ++ } ++} ++ + void SwPostItMgr::Scroll(const long lScroll,const unsigned long aPage) + { + OSL_ENSURE((lScroll % GetScrollSize() )==0,"SwPostItMgr::Scroll: scrolling by wrong value"); +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.hxx b/sw/source/uibase/docvw/SidebarTxtControl.hxx +index 1be8ab3b8b4a..4f47ef4a2177 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.hxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.hxx +@@ -40,7 +40,6 @@ class SidebarTextControl : public Control + + protected: + virtual void Paint( vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE; +- virtual void KeyInput( const KeyEvent& rKeyEvt ) SAL_OVERRIDE; + virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE; + virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE; + virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE; +@@ -60,7 +59,8 @@ class SidebarTextControl : public Control + virtual ~SidebarTextControl(); + virtual void dispose() SAL_OVERRIDE; + +- virtual void GetFocus() SAL_OVERRIDE; ++ virtual void GetFocus() override; ++ virtual void KeyInput( const KeyEvent& rKeyEvt ) override; + + OutlinerView* GetTextView() const; + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 575be80c0ae0..a40c82de5470 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -356,6 +356,12 @@ void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, s + } + } + ++void SwSidebarWin::KeyInput(const KeyEvent& rKeyEvent) ++{ ++ if (mpSidebarTextControl) ++ mpSidebarTextControl->KeyInput(rKeyEvent); ++} ++ + void SwSidebarWin::SetPosSizePixelRect(long nX, long nY, long nWidth, long nHeight, + const SwRect& aAnchorRect, const long aPageBorder) + { +diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx +index b4ed61becbfb..10cdc0dca561 100644 +--- a/sw/source/uibase/docvw/edtwin.cxx ++++ b/sw/source/uibase/docvw/edtwin.cxx +@@ -145,6 +145,8 @@ + #include + + #include ++#include ++#include + + #include + #include +@@ -1324,6 +1326,15 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt) + { + SwWrtShell &rSh = m_rView.GetWrtShell(); + ++ if (comphelper::LibreOfficeKit::isActive() && m_rView.GetPostItMgr()) ++ { ++ if (vcl::Window* pWindow = m_rView.GetPostItMgr()->GetActiveSidebarWin()) ++ { ++ pWindow->KeyInput(rKEvt); ++ return; ++ } ++ } ++ + if( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE && + m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard ) + { +-- +2.12.0 + diff --git a/SOURCES/0315-lok-Use-reference-instead-of-copy-constructing-in-ra.patch b/SOURCES/0315-lok-Use-reference-instead-of-copy-constructing-in-ra.patch new file mode 100644 index 0000000..3410be9 --- /dev/null +++ b/SOURCES/0315-lok-Use-reference-instead-of-copy-constructing-in-ra.patch @@ -0,0 +1,50 @@ +From 5b7391b183885ce1d85b76d2d6ddc46a771abc35 Mon Sep 17 00:00:00 2001 +From: Jan Holesovsky +Date: Thu, 12 Nov 2015 18:22:06 +0100 +Subject: [PATCH 315/398] lok: Use reference instead of copy constructing in + range-based for. + +Change-Id: Ie5bf5d4ab139f22e67f3654b0bb31e10b8c9f337 +(cherry picked from commit addd884799b88213df813fd8501c3ab8306593e1) +--- + desktop/source/lib/init.cxx | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 1d56f2e8abae..04a902780e6c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -1281,10 +1281,10 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + if (sStyleFam == "ParagraphStyles" + && doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT) + { +- for( OUString aStyle: aWriterStyles ) ++ for (const OUString& rStyle: aWriterStyles) + { + uno::Reference< beans::XPropertySet > xStyle; +- xStyleFamily->getByName( aStyle ) >>= xStyle; ++ xStyleFamily->getByName(rStyle) >>= xStyle; + OUString sName; + xStyle->getPropertyValue("DisplayName") >>= sName; + if( !sName.isEmpty() ) +@@ -1299,14 +1299,14 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand) + } + + uno::Sequence aStyles = xStyleFamily->getElementNames(); +- for ( OUString aStyle: aStyles ) ++ for (const OUString& rStyle: aStyles ) + { + // Filter out the default styles - they are already at the top + // of the list +- if (aDefaultStyleNames.find(aStyle) == aDefaultStyleNames.end()) ++ if (aDefaultStyleNames.find(rStyle) == aDefaultStyleNames.end()) + { + boost::property_tree::ptree aChild; +- aChild.put("", aStyle); ++ aChild.put("", rStyle); + aChildren.push_back(std::make_pair("", aChild)); + } + } +-- +2.12.0 + diff --git a/SOURCES/0316-LOK-setClientZoom-sets-the-client-zoom-level.patch b/SOURCES/0316-LOK-setClientZoom-sets-the-client-zoom-level.patch new file mode 100644 index 0000000..ca976ee --- /dev/null +++ b/SOURCES/0316-LOK-setClientZoom-sets-the-client-zoom-level.patch @@ -0,0 +1,313 @@ +From 4918619e165b7869731e594bf514932cdec10d8e Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Fri, 6 Nov 2015 14:34:28 +0200 +Subject: [PATCH 316/398] LOK: setClientZoom() - sets the client zoom level + +We need to know the client's view level to correctly handle the mouse +events in calc. PaintTile() set a zoom level that corresponds to the +requested tiles and previously postMouseEvent would call SetZoom(1,1). +Now we can make use of knowing the client's view level and call +SetZoom() with the correct parameters + +Conflicts: + sc/source/ui/unoobj/docuno.cxx +(cherry picked from commit 96cd2abd748ed24e5aba50cc4c300cf06e512db3) + +Change-Id: I34b5afcdcc06a671a8ac92c03e87404e42adf4cd +--- + desktop/source/lib/init.cxx | 20 +++++++++++++++- + include/LibreOfficeKit/LibreOfficeKit.h | 7 ++++++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 17 ++++++++++++++ + include/vcl/ITiledRenderable.hxx | 18 +++++++++++++++ + libreofficekit/source/gtk/lokdocview.cxx | 38 +++++++++++++++++++++++++++++++ + libreofficekit/source/gtk/tilebuffer.hxx | 11 ++++++++- + sc/inc/docuno.hxx | 3 +++ + sc/source/ui/unoobj/docuno.cxx | 18 ++++++++++++++- + 8 files changed, 129 insertions(+), 3 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 04a902780e6c..4ee862d21cd0 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -317,7 +317,11 @@ static void doc_setGraphicSelection (LibreOfficeKitDocument* pThis, + int nY); + static void doc_resetSelection (LibreOfficeKitDocument* pThis); + static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand); +- ++static void doc_setClientZoom(LibreOfficeKitDocument* pThis, ++ int nTilePixelWidth, ++ int nTilePixelHeight, ++ int nTileTwipWidth, ++ int nTileTwipHeight); + static int doc_createView(LibreOfficeKitDocument* pThis); + static void doc_destroyView(LibreOfficeKitDocument* pThis, int nId); + static void doc_setView(LibreOfficeKitDocument* pThis, int nId); +@@ -357,6 +361,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference setGraphicSelection = doc_setGraphicSelection; + m_pDocumentClass->resetSelection = doc_resetSelection; + m_pDocumentClass->getCommandValues = doc_getCommandValues; ++ m_pDocumentClass->setClientZoom = doc_setClientZoom; + + m_pDocumentClass->createView = doc_createView; + m_pDocumentClass->destroyView = doc_destroyView; +@@ -1470,6 +1475,19 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo + } + } + ++static void doc_setClientZoom(LibreOfficeKitDocument* pThis, int nTilePixelWidth, int nTilePixelHeight, ++ int nTileTwipWidth, int nTileTwipHeight) ++{ ++ ITiledRenderable* pDoc = getTiledRenderable(pThis); ++ if (!pDoc) ++ { ++ gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering"; ++ return; ++ } ++ ++ pDoc->setClientZoom(nTilePixelWidth, nTilePixelHeight, nTileTwipWidth, nTileTwipHeight); ++} ++ + static int doc_createView(LibreOfficeKitDocument* /*pThis*/) + { + SolarMutexGuard aGuard; +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index c887f5f64b8a..03210376c61e 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -181,6 +181,13 @@ struct _LibreOfficeKitDocumentClass + /// @see lok::Document::getCommandValues(). + char* (*getCommandValues) (LibreOfficeKitDocument* pThis, const char* pCommand); + ++ /// @see lok::Document::setClientZoom(). ++ void (*setClientZoom) (LibreOfficeKitDocument* pThis, ++ int nTilePixelWidth, ++ int nTilePixelHeight, ++ int nTileTwipWidth, ++ int nTileTwipHeight); ++ + /// @see lok::Document::createView(). + int (*createView) (LibreOfficeKitDocument* pThis); + /// @see lok::Document::destroyView(). +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 601d3bc147a5..c474195de213 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -294,6 +294,23 @@ public: + } + + /** ++ * Save the client's view so that we can compute the right zoom level ++ * for the mouse events. This only affects CALC. ++ * @param nTilePixelWidth - tile width in pixels ++ * @param nTilePixelHeight - tile height in pixels ++ * @param nTileTwipWidth - tile width in twips ++ * @param nTileTwipHeight - tile height in twips ++ */ ++ inline void setClientZoom( ++ int nTilePixelWidth, ++ int nTilePixelHeight, ++ int nTileTwipWidth, ++ int nTileTwipHeight) ++ { ++ mpDoc->pClass->setClientZoom(mpDoc, nTilePixelWidth, nTilePixelHeight, nTileTwipWidth, nTileTwipHeight); ++ } ++ ++ /** + * Create a new view for an existing document. + * By default a loaded document has 1 view. + * @return the ID of the new view. +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index bf0aa55e32a6..fa85b39399b3 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -22,6 +22,9 @@ namespace vcl + + class VCL_DLLPUBLIC ITiledRenderable + { ++protected: ++ int nTilePixelWidth, nTilePixelHeight; ++ int nTileTwipWidth, nTileTwipHeight; + public: + virtual ~ITiledRenderable(); + +@@ -179,6 +182,21 @@ public: + + /// If the current contents of the clipboard is something we can paste. + virtual bool isMimeTypeSupported() = 0; ++ ++ /** ++ * Save the client's view so that we can compute the right zoom level ++ * for the mouse events. ++ * @param nTilePixelWidth - tile width in pixels ++ * @param nTilePixelHeight - tile height in pixels ++ * @param nTileTwipWidth - tile width in twips ++ * @param nTileTwipHeight - tile height in twips ++ */ ++ virtual void setClientZoom(int /*nTilePixelWidth*/, ++ int /*nTilePixelHeight*/, ++ int /*nTileTwipWidth*/, ++ int /*nTileTwipHeight*/) ++ { ++ } + }; + + } // namespace vcl +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 687323d6ca11..db71f80e39c8 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1506,6 +1506,23 @@ setGraphicSelectionInThread(gpointer data) + } + + static void ++setClientZoomInThread(gpointer data) ++{ ++ GTask* task = G_TASK(data); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ ++ if (!priv->m_pDocument) ++ return; ++ priv->m_pDocument->pClass->setClientZoom(priv->m_pDocument, ++ pLOEvent->m_nTilePixelWidth, ++ pLOEvent->m_nTilePixelHeight, ++ pLOEvent->m_nTileTwipWidth, ++ pLOEvent->m_nTileTwipHeight); ++} ++ ++static void + postMouseEventInThread(gpointer data) + { + GTask* task = G_TASK(data); +@@ -1721,6 +1738,9 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + case LOK_SET_GRAPHIC_SELECTION: + setGraphicSelectionInThread(task); + break; ++ case LOK_SET_CLIENT_ZOOM: ++ setClientZoomInThread(task); ++ break; + } + + g_object_unref(task); +@@ -2301,6 +2321,7 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ GError* error = NULL; + + priv->m_fZoom = fZoom; + long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, fZoom); +@@ -2313,6 +2334,23 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + gtk_widget_set_size_request(GTK_WIDGET(pDocView), + nDocumentWidthPixels, + nDocumentHeightPixels); ++ ++ // Update the client's view size ++ GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_CLIENT_ZOOM); ++ pLOEvent->m_nTilePixelWidth = nTileSizePixels; ++ pLOEvent->m_nTilePixelHeight = nTileSizePixels; ++ pLOEvent->m_nTileTwipWidth = pixelToTwip(nTileSizePixels, fZoom); ++ pLOEvent->m_nTileTwipHeight = pixelToTwip(nTileSizePixels, fZoom); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); ++ ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != NULL) ++ { ++ g_warning("Unable to call LOK_SET_CLIENT_ZOOM: %s", error->message); ++ g_clear_error(&error); ++ } ++ g_object_unref(task); + } + + SAL_DLLPUBLIC_EXPORT float +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 5482ea2b2825..244ca882d051 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -159,7 +159,8 @@ enum + LOK_POST_KEY, + LOK_PAINT_TILE, + LOK_POST_MOUSE_EVENT, +- LOK_SET_GRAPHIC_SELECTION ++ LOK_SET_GRAPHIC_SELECTION, ++ LOK_SET_CLIENT_ZOOM + }; + + enum +@@ -233,6 +234,14 @@ struct LOEvent + int m_nSetGraphicSelectionY; + ///@} + ++ /// @name setClientView parameters ++ ///@{ ++ int m_nTilePixelWidth; ++ int m_nTilePixelHeight; ++ int m_nTileTwipWidth; ++ int m_nTileTwipHeight; ++ ///@} ++ + /// Constructor to instantiate an object of type `type`. + LOEvent(int type) + : m_nType(type) +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index b73eb12704be..7e00b7549733 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -422,6 +422,9 @@ public: + /// @see vcl::ITiledRenderable::isMimeTypeSupported(). + virtual bool isMimeTypeSupported() override; + ++ /// @see vcl::ITiledRenderable::setClientZoom(). ++ virtual void setClientZoom(int nTilePixelWidth, int nTilePixelHeight, int nTileTwipWidth, int nTileTwipHeight) override; ++ + /// @see vcl::ITiledRenderable::getRowColumnHeaders(). + virtual OUString getRowColumnHeaders(const Rectangle& rRectangle) override; + +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index 0e5396e5910e..c5a96e1e8255 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -604,7 +604,8 @@ void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButt + return; + + // update the aLogicMode in ScViewData to something predictable +- pViewData->SetZoom(Fraction(1, 1), Fraction(1, 1), true); ++ pViewData->SetZoom(Fraction(nTilePixelWidth * TWIPS_PER_PIXEL, nTileTwipWidth), ++ Fraction(nTilePixelHeight * TWIPS_PER_PIXEL, nTileTwipHeight), true); + + // Calc operates in pixels... + MouseEvent aEvent(Point(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY()), nCount, +@@ -873,6 +874,14 @@ bool ScModelObj::isMimeTypeSupported() + return EditEngine::HasValidData(aDataHelper.GetTransferable()); + } + ++void ScModelObj::setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int nTileTwipWidth_, int nTileTwipHeight_) ++{ ++ nTilePixelWidth = nTilePixelWidth_; ++ nTilePixelHeight = nTilePixelHeight_; ++ nTileTwipWidth = nTileTwipWidth_; ++ nTileTwipHeight = nTileTwipHeight_; ++} ++ + OUString ScModelObj::getRowColumnHeaders(const Rectangle& rRectangle) + { + ScViewData* pViewData = ScDocShell::GetViewData(); +@@ -931,6 +940,13 @@ void ScModelObj::initializeForTiledRendering() + // tdf#93154: in tiled rendering LO doesn't always detect changes + SvtMiscOptions aMiscOpt; + aMiscOpt.SetSaveAlwaysAllowed(true); ++ ++ // default tile size in pixels ++ nTilePixelWidth = 256; ++ nTilePixelHeight = 256; ++ // the default zoom level will be 1 ++ nTileTwipWidth = nTilePixelWidth * TWIPS_PER_PIXEL; ++ nTileTwipHeight = nTilePixelHeight * TWIPS_PER_PIXEL; + } + + uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType ) +-- +2.12.0 + diff --git a/SOURCES/0317-LOK-calc-formula-callback-formula-bar-implementation.patch b/SOURCES/0317-LOK-calc-formula-callback-formula-bar-implementation.patch new file mode 100644 index 0000000..f4dddc6 --- /dev/null +++ b/SOURCES/0317-LOK-calc-formula-callback-formula-bar-implementation.patch @@ -0,0 +1,202 @@ +From d57909684dd464e1e7b8616ac1cbd43a8f5817c2 Mon Sep 17 00:00:00 2001 +From: Mihai Varga +Date: Fri, 13 Nov 2015 09:48:14 +0200 +Subject: [PATCH 317/398] LOK: calc formula callback + formula bar + implementation in gtk + +We need the callback to be able implement the formula bar + +Change-Id: I1c78ab0b9ed9304c0465a9993a7101f8efb91052 + +Conflicts: + include/LibreOfficeKit/LibreOfficeKitEnums.h + libreofficekit/source/gtk/lokdocview.cxx +(cherry picked from commit 5b1e22e9ba941305a7f138adcef75a464161a145) +--- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 7 +++++- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 24 +++++++++++++++++++++ + libreofficekit/source/gtk/lokdocview.cxx | 25 ++++++++++++++++++++++ + sc/source/ui/app/inputhdl.cxx | 8 +++++++ + 4 files changed, 63 insertions(+), 1 deletion(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 37837ea49b86..7b23fcbab1c3 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -209,7 +209,12 @@ typedef enum + * + * Payload is a css mouse pointer style. + */ +- LOK_CALLBACK_MOUSE_POINTER ++ LOK_CALLBACK_MOUSE_POINTER, ++ ++ /** ++ * The text content of the formula bar in Calc. ++ */ ++ LOK_CALLBACK_CELL_FORMULA + } + LibreOfficeKitCallbackType; + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index c96ba95e7d99..cd5b23c12bc4 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -101,6 +101,7 @@ public: + GtkToolItem* m_pCenterpara; + GtkToolItem* m_pRightpara; + GtkToolItem* m_pJustifypara; ++ GtkWidget* m_pFormulabarEntry; + GtkWidget* m_pScrolledWindow; + std::map m_aToolItemCommandNames; + std::map m_aCommandNameToolItems; +@@ -135,6 +136,7 @@ public: + m_pCenterpara(nullptr), + m_pRightpara(nullptr), + m_pJustifypara(nullptr), ++ m_pFormulabarEntry(nullptr), + m_pScrolledWindow(nullptr), + m_bToolItemBroadcast(true), + m_pVBox(nullptr), +@@ -631,6 +633,14 @@ static gboolean signalFindbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer + return FALSE; + } + ++/// Handles the key-press-event of the formula entry widget. ++static gboolean signalFormulabar(GtkWidget* /*pWidget*/, GdkEventKey* /*pEvent*/, gpointer /*pData*/) ++{ ++ // for now it just displays the callback ++ // TODO - submit the edited formula ++ return TRUE; ++} ++ + /// LOKDocView changed edit state -> inform the tool button. + static void signalEdit(LOKDocView* pLOKDocView, gboolean bWasEdit, gpointer /*pData*/) + { +@@ -767,6 +777,13 @@ static void cursorChanged(LOKDocView* pDocView, gint nX, gint nY, + gtk_adjustment_set_value(hadj, lok_doc_view_twip_to_pixel(LOK_DOC_VIEW(pDocView), x)); + } + ++/// LOKDocView the formula has changed ++static void formulaChanged(LOKDocView* pLOKDocView, char* pPayload, gpointer /*pData*/) ++{ ++ TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); ++ gtk_entry_set_text((GtkEntry*)rWindow.m_pFormulabarEntry, pPayload); ++} ++ + static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pWidget); +@@ -1075,6 +1092,12 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pJustifypara, -1); + g_signal_connect(G_OBJECT(rWindow.m_pJustifypara), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(rWindow, rWindow.m_pJustifypara, ".uno:JustifyPara"); ++ // Formula bar ++ GtkToolItem* pFormulaEntryContainer = gtk_tool_item_new(); ++ rWindow.m_pFormulabarEntry = gtk_entry_new(); ++ gtk_container_add(GTK_CONTAINER(pFormulaEntryContainer), rWindow.m_pFormulabarEntry); ++ g_signal_connect(rWindow.m_pFormulabarEntry, "key-press-event", G_CALLBACK(signalFormulabar), 0); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), pFormulaEntryContainer, -1); + gtk_box_pack_start(GTK_BOX(rWindow.m_pVBox), pLowerToolbar, FALSE, FALSE, 0 ); // Adds to top. + + // Findbar +@@ -1188,6 +1211,7 @@ static void setupDocView(GtkWidget* pDocView) + g_signal_connect(pDocView, "size-changed", G_CALLBACK(signalSize), NULL); + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); + g_signal_connect(pDocView, "cursor-changed", G_CALLBACK(cursorChanged), NULL); ++ g_signal_connect(pDocView, "formula-changed", G_CALLBACK(formulaChanged), NULL); + } + + int main( int argc, char* argv[] ) +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index db71f80e39c8..9d852351262e 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -184,6 +184,7 @@ enum + CURSOR_CHANGED, + SEARCH_RESULT_COUNT, + COMMAND_RESULT, ++ FORMULA_CHANGED, + + LAST_SIGNAL + }; +@@ -495,6 +496,11 @@ static void commandResult(LOKDocView* pDocView, const std::string& rString) + g_signal_emit(pDocView, doc_view_signals[COMMAND_RESULT], 0, rString.c_str()); + } + ++static void formulaChanged(LOKDocView* pDocView, const std::string& rString) ++{ ++ g_signal_emit(pDocView, doc_view_signals[FORMULA_CHANGED], 0, rString.c_str()); ++} ++ + static void + setPart(LOKDocView* pDocView, const std::string& rString) + { +@@ -809,6 +815,11 @@ callback (gpointer pData) + commandResult(pDocView, pCallback->m_aPayload); + } + break; ++ case LOK_CALLBACK_CELL_FORMULA: ++ { ++ formulaChanged(pDocView, pCallback->m_aPayload); ++ } ++ break; + default: + g_assert(false); + break; +@@ -2248,6 +2259,20 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_NONE, 1, + G_TYPE_STRING); + ++ /** ++ * LOKDocView::formula-changed: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @aCommand: formula text content ++ */ ++ doc_view_signals[FORMULA_CHANGED] = ++ g_signal_new("formula-changed", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ NULL, NULL, ++ g_cclosure_marshal_VOID__STRING, ++ G_TYPE_NONE, 1, ++ G_TYPE_STRING); + } + + SAL_DLLPUBLIC_EXPORT GtkWidget* +diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx +index 09bc73d336cd..c656ca75b9b7 100644 +--- a/sc/source/ui/app/inputhdl.cxx ++++ b/sc/source/ui/app/inputhdl.cxx +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + #include "inputwin.hxx" + #include "tabvwsh.hxx" +@@ -2139,6 +2140,11 @@ void ScInputHandler::DataChanged( bool bFromTopNotify, bool bSetModified ) + + if ( pInputWin ) + pInputWin->SetTextString( aText ); ++ ++ ScDocShell* pDocSh = pActiveViewSh->GetViewData().GetDocShell(); ++ ScDocument& rDoc = pDocSh->GetDocument(); ++ if ( rDoc.GetDrawLayer()->isTiledRendering() ) ++ rDoc.GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_CELL_FORMULA, aText.toUtf8().getStr()); + } + + // If the cursor is before the end of a paragraph, parts are being pushed to +@@ -3475,6 +3481,8 @@ void ScInputHandler::NotifyChange( const ScInputHdlState* pState, + + if ( pInputWin ) + pInputWin->SetTextString(aString); ++ else if ( rDoc.GetDrawLayer()->isTiledRendering() ) ++ rDoc.GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_CELL_FORMULA, aString.toUtf8().getStr()); + } + + if ( pInputWin ) // Named range input +-- +2.12.0 + diff --git a/SOURCES/0318-libreofficekit-loplugin-cstylecast.patch b/SOURCES/0318-libreofficekit-loplugin-cstylecast.patch new file mode 100644 index 0000000..296938f --- /dev/null +++ b/SOURCES/0318-libreofficekit-loplugin-cstylecast.patch @@ -0,0 +1,27 @@ +From 3a915ae6d285545311c27e6d85a4b789ae5c7a2f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 13 Nov 2015 09:45:03 +0100 +Subject: [PATCH 318/398] libreofficekit: loplugin:cstylecast + +Change-Id: Iea7ba258b661c09744191933fc23a06ed57fdf3b +(cherry picked from commit 0bf24b19c7618ee83f88aa9364f68a4db1d2c04d) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index cd5b23c12bc4..45ccef792905 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -781,7 +781,7 @@ static void cursorChanged(LOKDocView* pDocView, gint nX, gint nY, + static void formulaChanged(LOKDocView* pLOKDocView, char* pPayload, gpointer /*pData*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(GTK_WIDGET(pLOKDocView)); +- gtk_entry_set_text((GtkEntry*)rWindow.m_pFormulabarEntry, pPayload); ++ gtk_entry_set_text(GTK_ENTRY(rWindow.m_pFormulabarEntry), pPayload); + } + + static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) +-- +2.12.0 + diff --git a/SOURCES/0319-sw-don-t-show-main-cursor-when-editing-a-postit.patch b/SOURCES/0319-sw-don-t-show-main-cursor-when-editing-a-postit.patch new file mode 100644 index 0000000..f502763 --- /dev/null +++ b/SOURCES/0319-sw-don-t-show-main-cursor-when-editing-a-postit.patch @@ -0,0 +1,55 @@ +From e24ce4fa62084b8fb8634da280450c054f797052 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 13 Nov 2015 10:03:10 +0100 +Subject: [PATCH 319/398] sw: don't show main cursor when editing a postit + +This is primarily for tiled editing that doesn't know about multiple +cursors, so if both the postit cursor and the main cursor is shown for a +short period of time, then the main one is hidden, then gtktiledviewer +still shows the main one. + +OTOH if we can avoid showing the cursor in general just to hide it a bit +later in general, let's not do that. + +With this, the "cursor is shown at the comment anchor, not inside the +anchor when clicking on the postit" bug disappears. + +(cherry picked from commit 1c482cb54b4dab4c5b549ecd2395104f042e4101) + +Change-Id: I2383292c5f84604dc8b126510b0797b8426920ae +--- + sw/source/core/crsr/crsrsh.cxx | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx +index ffff6a6b2a93..626a2a75e47a 100644 +--- a/sw/source/core/crsr/crsrsh.cxx ++++ b/sw/source/core/crsr/crsrsh.cxx +@@ -65,6 +65,8 @@ + #include + #include + #include ++#include ++#include + + using namespace com::sun::star; + using namespace util; +@@ -1286,6 +1288,15 @@ void SwCrsrShell::Paint(vcl::RenderContext& rRenderContext, const Rectangle &rRe + pAktCrsr->Invalidate( aRect ); + + } ++ ++ if (SwPostItMgr* pPostItMgr = GetPostItMgr()) ++ { ++ // No point in showing the cursor for Writer text when there is an ++ // active annotation edit. ++ if (bVis) ++ bVis = !pPostItMgr->HasActiveSidebarWin(); ++ } ++ + if( m_bSVCrsrVis && bVis ) // also show SV cursor again + m_pVisCrsr->Show(); + } +-- +2.12.0 + diff --git a/SOURCES/0320-loplugin-nullptr.patch b/SOURCES/0320-loplugin-nullptr.patch new file mode 100644 index 0000000..281092d --- /dev/null +++ b/SOURCES/0320-loplugin-nullptr.patch @@ -0,0 +1,54 @@ +From 19770dc907fb14c29c954aba399f906ee0c44914 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Fri, 13 Nov 2015 10:41:32 +0100 +Subject: [PATCH 320/398] loplugin:nullptr + +Change-Id: Iaf779157b97e4d3a3a449cc7f17e4d5c533955f0 +(cherry picked from commit c6c8af5ef46e2178e4b9abcd95f76c8df2db2732) +--- + libreofficekit/source/gtk/lokdocview.cxx | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 9d852351262e..47ada280dde3 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2269,7 +2269,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_TYPE_FROM_CLASS(pGObjectClass), + G_SIGNAL_RUN_FIRST, + 0, +- NULL, NULL, ++ nullptr, nullptr, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +@@ -2346,7 +2346,7 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GError* error = NULL; ++ GError* error = nullptr; + + priv->m_fZoom = fZoom; + long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, fZoom); +@@ -2361,7 +2361,7 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + nDocumentHeightPixels); + + // Update the client's view size +- GTask* task = g_task_new(pDocView, NULL, NULL, NULL); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_CLIENT_ZOOM); + pLOEvent->m_nTilePixelWidth = nTileSizePixels; + pLOEvent->m_nTilePixelHeight = nTileSizePixels; +@@ -2370,7 +2370,7 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != NULL) ++ if (error != nullptr) + { + g_warning("Unable to call LOK_SET_CLIENT_ZOOM: %s", error->message); + g_clear_error(&error); +-- +2.12.0 + diff --git a/SOURCES/0321-sc-lok-during-tiled-rendering-the-cell-cursor-is-alw.patch b/SOURCES/0321-sc-lok-during-tiled-rendering-the-cell-cursor-is-alw.patch new file mode 100644 index 0000000..4083fbe --- /dev/null +++ b/SOURCES/0321-sc-lok-during-tiled-rendering-the-cell-cursor-is-alw.patch @@ -0,0 +1,63 @@ +From 9cb5bab53bf2211762f3470cba824ce1ecdc9391 Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Fri, 13 Nov 2015 11:17:43 +0100 +Subject: [PATCH 321/398] sc lok: during tiled rendering the cell-cursor is + always visible + +Change-Id: Ia802c19f5bfd2fe2e9909e3c611047c529a64200 +(cherry picked from commit e77668eb1e7abe522493235dadfca08ca451ad99) +--- + sc/source/ui/view/gridwin.cxx | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx +index c2d391d038ef..96f10568b797 100644 +--- a/sc/source/ui/view/gridwin.cxx ++++ b/sc/source/ui/view/gridwin.cxx +@@ -6019,7 +6019,9 @@ void ScGridWindow::UpdateCursorOverlay() + + const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab); + +- if (!maVisibleRange.isInside(nX, nY)) ++ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); ++ ++ if (!pDrawLayer->isTiledRendering() && !maVisibleRange.isInside(nX, nY)) + { + if (maVisibleRange.mnCol2 < nX || maVisibleRange.mnRow2 < nY) + return; // no further check needed, nothing visible +@@ -6038,13 +6040,11 @@ void ScGridWindow::UpdateCursorOverlay() + } + + // don't show the cursor in overlapped cells +- + const ScMergeFlagAttr& rMergeFlag = static_cast( pPattern->GetItem(ATTR_MERGE_FLAG) ); + bool bOverlapped = rMergeFlag.IsOverlapped(); + + // left or above of the screen? +- +- bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) ); ++ bool bVis = pDrawLayer->isTiledRendering() || ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) ); + if (!bVis) + { + SCCOL nEndX = nX; +@@ -6074,7 +6074,7 @@ void ScGridWindow::UpdateCursorOverlay() + } + + // in the tiled rendering case, don't limit to the screen size +- if (bMaybeVisible) ++ if (bMaybeVisible || pDrawLayer->isTiledRendering()) + { + long nSizeXPix; + long nSizeYPix; +@@ -6117,8 +6117,6 @@ void ScGridWindow::UpdateCursorOverlay() + } + } + +- ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); +- + if ( !aPixelRects.empty() ) + { + if (pDrawLayer->isTiledRendering()) { +-- +2.12.0 + diff --git a/SOURCES/0322-editeng-lok-respect-origin-of-map-mode-for-INVALIDAT.patch b/SOURCES/0322-editeng-lok-respect-origin-of-map-mode-for-INVALIDAT.patch new file mode 100644 index 0000000..bb15bef --- /dev/null +++ b/SOURCES/0322-editeng-lok-respect-origin-of-map-mode-for-INVALIDAT.patch @@ -0,0 +1,39 @@ +From 81c5808af3987e81f571e0436d04a6a96ccf19ca Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 13 Nov 2015 11:33:43 +0100 +Subject: [PATCH 322/398] editeng lok: respect origin of map mode for + INVALIDATE_VISIBLE_CURSOR + +Writer comments are separate widgets, but we want to have coordinates in +absolutes twips, so give Writer a chance to inform us about the delta. + +For now only do this in case the map unit is twips, as Impress sets the +origin already. + +Change-Id: Idf340944165e44b0888c00965d6be7798712ff76 +(cherry picked from commit e988ab84f1c32519bfca758086c749ba98a5a85f) +--- + editeng/source/editeng/impedit.cxx | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx +index f7e2886c0524..8038ac6d3d41 100644 +--- a/editeng/source/editeng/impedit.cxx ++++ b/editeng/source/editeng/impedit.cxx +@@ -947,6 +947,13 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor, sal_uInt16 + // LOK output is always in twips, convert from mm100 if necessary. + if (pOutWin->GetMapMode().GetMapUnit() == MAP_100TH_MM) + aRect = OutputDevice::LogicToLogic(aRect, MAP_100TH_MM, MAP_TWIP); ++ else if (pOutWin->GetMapMode().GetMapUnit() == MAP_TWIP) ++ { ++ // Writer comments: they use editeng, but are separate widgets. ++ Point aOrigin = pOutWin->GetMapMode().GetOrigin(); ++ // Move the rectangle, so that we output absolute twips. ++ aRect.Move(aOrigin.getX(), aOrigin.getY()); ++ } + // Let the LOK client decide the cursor width. + aRect.setWidth(0); + +-- +2.12.0 + diff --git a/SOURCES/0323-sw-lok-fix-blinking-cursor-position-of-comments.patch b/SOURCES/0323-sw-lok-fix-blinking-cursor-position-of-comments.patch new file mode 100644 index 0000000..3ea0171 --- /dev/null +++ b/SOURCES/0323-sw-lok-fix-blinking-cursor-position-of-comments.patch @@ -0,0 +1,155 @@ +From 0964ec395a33e8299a5caebb122c73687d1b428e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 13 Nov 2015 13:33:32 +0100 +Subject: [PATCH 323/398] sw lok: fix blinking cursor position of comments + +With this, it is possible to click inside a comment (and get a blinking +cursor inside a comment), and also possible to use the arrow keys to +native around and still get correct blinking cursor position. + +(cherry picked from commit 5fb91dfd804cd6f3d585bb4113b9a68083ac71ee) + +Change-Id: I29eb1e60e4e571151f0b18bec8cf765ea09af09f +--- + sw/inc/SidebarWin.hxx | 5 ++-- + sw/source/uibase/docvw/PostItMgr.cxx | 4 ++-- + sw/source/uibase/docvw/SidebarTxtControl.hxx | 2 +- + sw/source/uibase/docvw/SidebarWin.cxx | 36 ++++++++++++++++++++++++---- + sw/source/uibase/docvw/edtwin.cxx | 7 ------ + 5 files changed, 38 insertions(+), 16 deletions(-) + +diff --git a/sw/inc/SidebarWin.hxx b/sw/inc/SidebarWin.hxx +index c41352749c28..e3899d5a1a8b 100644 +--- a/sw/inc/SidebarWin.hxx ++++ b/sw/inc/SidebarWin.hxx +@@ -179,9 +179,10 @@ class SwSidebarWin : public vcl::Window + + virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) override; + virtual void KeyInput(const KeyEvent& rKeyEvt) override; ++ virtual void MouseButtonDown(const MouseEvent& rMouseEvent) override; + void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); +- /// Get the matching sub-widget inside this sidebar widget for rPointLogic, if any. +- vcl::Window* IsHitWindow(const Point& rPointLogic); ++ /// Is there a matching sub-widget inside this sidebar widget for rPointLogic? ++ bool IsHitWindow(const Point& rPointLogic); + + protected: + virtual void DataChanged( const DataChangedEvent& aEvent) SAL_OVERRIDE; +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index 703a433a44ee..871a642d24da 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -1736,9 +1736,9 @@ vcl::Window* SwPostItMgr::IsHitSidebarWindow(const Point& rPointLogic) + if (!pPostIt) + continue; + +- if (vcl::Window* pWindow = pPostIt->IsHitWindow(rPointLogic)) ++ if (pPostIt->IsHitWindow(rPointLogic)) + { +- pRet = pWindow; ++ pRet = pPostIt; + break; + } + } +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.hxx b/sw/source/uibase/docvw/SidebarTxtControl.hxx +index 4f47ef4a2177..43d6b98d82c1 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.hxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.hxx +@@ -41,7 +41,6 @@ class SidebarTextControl : public Control + protected: + virtual void Paint( vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE; + virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE; +- virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE; + virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE; + virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE; + virtual void LoseFocus() SAL_OVERRIDE; +@@ -61,6 +60,7 @@ class SidebarTextControl : public Control + + virtual void GetFocus() override; + virtual void KeyInput( const KeyEvent& rKeyEvt ) override; ++ virtual void MouseButtonDown(const MouseEvent& rMouseEvent) override; + + OutlinerView* GetTextView() const; + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index a40c82de5470..dd8d2a6003b9 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -280,12 +280,10 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + rRenderContext.Push(PushFlags::NONE); + } + +-vcl::Window* SwSidebarWin::IsHitWindow(const Point& rPointLogic) ++bool SwSidebarWin::IsHitWindow(const Point& rPointLogic) + { + Rectangle aRectangleLogic(EditWin()->PixelToLogic(GetPosPixel()), EditWin()->PixelToLogic(GetSizePixel())); +- if (aRectangleLogic.IsInside(rPointLogic)) +- return mpSidebarTextControl; +- return 0; ++ return aRectangleLogic.IsInside(rPointLogic); + } + + void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, sal_uLong nInFlags) +@@ -356,10 +354,40 @@ void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, s + } + } + ++/// We want to work in absolute twips: so set delta between rChild and rParent as origin on rChild, then disable map mode on rChild. ++static void lcl_setAbsoluteTwips(vcl::Window& rParent, vcl::Window& rChild) ++{ ++ Point aOffset(rChild.GetOutOffXPixel() - rParent.GetOutOffXPixel(), rChild.GetOutOffYPixel() - rParent.GetOutOffYPixel()); ++ MapMode aMapMode(rChild.GetMapMode()); ++ aMapMode.SetOrigin(rChild.PixelToLogic(aOffset)); ++ rChild.SetMapMode(aMapMode); ++ rChild.EnableMapMode(false); ++} ++ + void SwSidebarWin::KeyInput(const KeyEvent& rKeyEvent) + { + if (mpSidebarTextControl) ++ { ++ mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ lcl_setAbsoluteTwips(*EditWin(), *mpSidebarTextControl); ++ + mpSidebarTextControl->KeyInput(rKeyEvent); ++ ++ mpSidebarTextControl->Pop(); ++ } ++} ++ ++void SwSidebarWin::MouseButtonDown(const MouseEvent& rMouseEvent) ++{ ++ if (mpSidebarTextControl) ++ { ++ mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ lcl_setAbsoluteTwips(*EditWin(), *mpSidebarTextControl); ++ ++ mpSidebarTextControl->MouseButtonDown(rMouseEvent); ++ ++ mpSidebarTextControl->Pop(); ++ } + } + + void SwSidebarWin::SetPosSizePixelRect(long nX, long nY, long nWidth, long nHeight, +diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx +index 10cdc0dca561..53d0afd38f94 100644 +--- a/sw/source/uibase/docvw/edtwin.cxx ++++ b/sw/source/uibase/docvw/edtwin.cxx +@@ -2771,14 +2771,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) + { + if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel())) + { +- bool bDisableMapMode = pWindow->IsMapModeEnabled(); +- if (bDisableMapMode) +- pWindow->EnableMapMode(false); +- + pWindow->MouseButtonDown(rMEvt); +- +- if (bDisableMapMode) +- pWindow->EnableMapMode(); + return; + } + } +-- +2.12.0 + diff --git a/SOURCES/0324-editeng-lok-respect-origin-of-map-mode-for-TEXT_SELE.patch b/SOURCES/0324-editeng-lok-respect-origin-of-map-mode-for-TEXT_SELE.patch new file mode 100644 index 0000000..6995a41 --- /dev/null +++ b/SOURCES/0324-editeng-lok-respect-origin-of-map-mode-for-TEXT_SELE.patch @@ -0,0 +1,77 @@ +From 72385a1ddf68d7c30813b7ca964850c96850a8de Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 13 Nov 2015 14:42:35 +0100 +Subject: [PATCH 324/398] editeng lok: respect origin of map mode for + TEXT_SELECTION + +With this, selections of Writer comment text show up at the correct +position, not at the top left corner of the window. + +(cherry picked from commit 22e97c130868fe7d7529cfcfb2a240f775bd8916) + +Change-Id: If865503d9a02a27730e382d65c42c706dd533a93 +--- + editeng/source/editeng/impedit.cxx | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx +index 8038ac6d3d41..0207155e4d75 100644 +--- a/editeng/source/editeng/impedit.cxx ++++ b/editeng/source/editeng/impedit.cxx +@@ -24,6 +24,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -327,6 +328,12 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou + if (isTiledRendering() && !pOldRegion) + { + bool bMm100ToTwip = pOutWin->GetMapMode().GetMapUnit() == MAP_100TH_MM; ++ ++ Point aOrigin; ++ if (pOutWin->GetMapMode().GetMapUnit() == MAP_TWIP) ++ // Writer comments: they use editeng, but are separate widgets. ++ aOrigin = pOutWin->GetMapMode().GetOrigin(); ++ + OString sRectangle; + // If we are not in selection mode, then the exported selection should be empty. + if (pEditEngine->pImpEditEngine->IsInSelectionMode()) +@@ -340,26 +347,27 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou + Rectangle aStart = Rectangle(rStart.Left(), rStart.Top(), rStart.Left() + 1, rStart.Bottom()); + if (bMm100ToTwip) + aStart = OutputDevice::LogicToLogic(aStart, MAP_100TH_MM, MAP_TWIP); ++ aStart.Move(aOrigin.getX(), aOrigin.getY()); + libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_START, aStart.toString().getStr()); + + Rectangle& rEnd = aRectangles.back(); + Rectangle aEnd = Rectangle(rEnd.Right() - 1, rEnd.Top(), rEnd.Right(), rEnd.Bottom()); + if (bMm100ToTwip) + aEnd = OutputDevice::LogicToLogic(aEnd, MAP_100TH_MM, MAP_TWIP); ++ aEnd.Move(aOrigin.getX(), aOrigin.getY()); + libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION_END, aEnd.toString().getStr()); + } + +- std::stringstream ss; ++ std::vector v; + for (size_t i = 0; i < aRectangles.size(); ++i) + { + Rectangle& rRectangle = aRectangles[i]; +- if (i) +- ss << "; "; + if (bMm100ToTwip) + rRectangle = OutputDevice::LogicToLogic(rRectangle, MAP_100TH_MM, MAP_TWIP); +- ss << rRectangle.toString().getStr(); ++ rRectangle.Move(aOrigin.getX(), aOrigin.getY()); ++ v.push_back(rRectangle.toString().getStr()); + } +- sRectangle = ss.str().c_str(); ++ sRectangle = comphelper::string::join("; ", v); + } + libreOfficeKitCallback(LOK_CALLBACK_TEXT_SELECTION, sRectangle.getStr()); + } +-- +2.12.0 + diff --git a/SOURCES/0325-sw-lok-disable-comment-menu-button-for-now.patch b/SOURCES/0325-sw-lok-disable-comment-menu-button-for-now.patch new file mode 100644 index 0000000..360c74c --- /dev/null +++ b/SOURCES/0325-sw-lok-disable-comment-menu-button-for-now.patch @@ -0,0 +1,29 @@ +From 4973a1ce9a3ee710f840fb39fb5e3a08f2f54005 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 13 Nov 2015 14:51:13 +0100 +Subject: [PATCH 325/398] sw lok: disable comment menu button for now + +Change-Id: Ic052544b2835181652732b8de9eaf79572a9db6e +(cherry picked from commit 022c716fc89c7315a7c454c01e2fe70d5aece289) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index dd8d2a6003b9..47f5022e8044 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -253,6 +253,10 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + if (pChild == mpVScrollbar.get()) + continue; + ++ // No point in showing this button till click on it are not handled. ++ if (pChild == mpMenuButton.get()) ++ continue; ++ + rRenderContext.Push(PushFlags::MAPMODE); + Point aOffset(PixelToLogic(pChild->GetPosPixel())); + MapMode aMapMode(rRenderContext.GetMapMode()); +-- +2.12.0 + diff --git a/SOURCES/0326-sw-lok-comments-fix-position-of-blinking-cursor-afte.patch b/SOURCES/0326-sw-lok-comments-fix-position-of-blinking-cursor-afte.patch new file mode 100644 index 0000000..e2e478c --- /dev/null +++ b/SOURCES/0326-sw-lok-comments-fix-position-of-blinking-cursor-afte.patch @@ -0,0 +1,79 @@ +From 4bd7e435c3476b7d267755b9e53ed7d35ce78220 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 13 Nov 2015 17:30:22 +0100 +Subject: [PATCH 326/398] sw lok comments: fix position of blinking cursor + after mouse click + +LOK always works in absolute twips (origo being the top left corner of +SwEditWin), so not only the callbacks have to translate relative twips +to absolute ones, but the opposite have to be done for mouse event +coordinates. + +With this, clicking at a random position inside a comment places the +blinking cursor at a reasonable position, not always at 0,0. + +(cherry picked from commit 57972554b58a680f47a05f4d6711c99106f80523) + +Change-Id: Ic8d20f177acd9e1908acf17698c53a1470bd4aec +--- + sw/source/uibase/docvw/SidebarWin.cxx | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 47f5022e8044..71b763b84224 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -358,14 +358,25 @@ void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, s + } + } + +-/// We want to work in absolute twips: so set delta between rChild and rParent as origin on rChild, then disable map mode on rChild. +-static void lcl_setAbsoluteTwips(vcl::Window& rParent, vcl::Window& rChild) ++/// Translate absolute <-> relative twips: LOK wants absolute coordinates as output and gives absolute coordinates as input. ++static void lcl_translateTwips(vcl::Window& rParent, vcl::Window& rChild, MouseEvent* pMouseEvent) + { ++ // Set map mode, so that callback payloads will contain absolute coordinates instead of relative ones. + Point aOffset(rChild.GetOutOffXPixel() - rParent.GetOutOffXPixel(), rChild.GetOutOffYPixel() - rParent.GetOutOffYPixel()); ++ aOffset = rChild.PixelToLogic(aOffset); + MapMode aMapMode(rChild.GetMapMode()); +- aMapMode.SetOrigin(rChild.PixelToLogic(aOffset)); ++ aMapMode.SetOrigin(aOffset); + rChild.SetMapMode(aMapMode); + rChild.EnableMapMode(false); ++ ++ if (pMouseEvent) ++ { ++ // Set event coordinates, so they contain relative coordinates instead of absolute ones. ++ Point aPos = pMouseEvent->GetPosPixel(); ++ aPos.Move(-aOffset.getX(), -aOffset.getY()); ++ MouseEvent aMouseEvent(aPos, pMouseEvent->GetClicks(), pMouseEvent->GetMode(), pMouseEvent->GetButtons(), pMouseEvent->GetModifier()); ++ *pMouseEvent = aMouseEvent; ++ } + } + + void SwSidebarWin::KeyInput(const KeyEvent& rKeyEvent) +@@ -373,7 +384,7 @@ void SwSidebarWin::KeyInput(const KeyEvent& rKeyEvent) + if (mpSidebarTextControl) + { + mpSidebarTextControl->Push(PushFlags::MAPMODE); +- lcl_setAbsoluteTwips(*EditWin(), *mpSidebarTextControl); ++ lcl_translateTwips(*EditWin(), *mpSidebarTextControl, nullptr); + + mpSidebarTextControl->KeyInput(rKeyEvent); + +@@ -386,9 +397,10 @@ void SwSidebarWin::MouseButtonDown(const MouseEvent& rMouseEvent) + if (mpSidebarTextControl) + { + mpSidebarTextControl->Push(PushFlags::MAPMODE); +- lcl_setAbsoluteTwips(*EditWin(), *mpSidebarTextControl); ++ MouseEvent aMouseEvent(rMouseEvent); ++ lcl_translateTwips(*EditWin(), *mpSidebarTextControl, &aMouseEvent); + +- mpSidebarTextControl->MouseButtonDown(rMouseEvent); ++ mpSidebarTextControl->MouseButtonDown(aMouseEvent); + + mpSidebarTextControl->Pop(); + } +-- +2.12.0 + diff --git a/SOURCES/0327-sw-lok-comments-emit-invalidation-events-in-SidebarT.patch b/SOURCES/0327-sw-lok-comments-emit-invalidation-events-in-SidebarT.patch new file mode 100644 index 0000000..0d4cbff --- /dev/null +++ b/SOURCES/0327-sw-lok-comments-emit-invalidation-events-in-SidebarT.patch @@ -0,0 +1,84 @@ +From 08ca67b7742364ecdc8bf7928ce2ef058da0e37e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 10:04:38 +0100 +Subject: [PATCH 327/398] sw lok comments: emit invalidation events in + SidebarTextControl + +With this, newly typed characters show up instantly in comments, not +only after changing the zoom level. + +(cherry picked from commit 4cbbaf571d3982eccd7f7267df3185b3d321d0da) + +Change-Id: I1470db1ec03cc415917375f1f95434cf0944e559 +--- + sw/source/uibase/docvw/SidebarTxtControl.cxx | 26 ++++++++++++++++++++++++++ + sw/source/uibase/docvw/SidebarTxtControl.hxx | 2 ++ + 2 files changed, 28 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.cxx b/sw/source/uibase/docvw/SidebarTxtControl.cxx +index afda8b1952ad..d6887a475312 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.cxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.cxx +@@ -23,6 +23,7 @@ + + #include + #include ++#include + + #include + #include +@@ -46,6 +47,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -186,6 +188,30 @@ void SidebarTextControl::Paint(vcl::RenderContext& rRenderContext, const Rectang + } + } + ++void SidebarTextControl::LogicInvalidate(const Rectangle* pRectangle) ++{ ++ OString sRectangle; ++ if (!pRectangle) ++ sRectangle = "EMPTY"; ++ else ++ { ++ // Convert from relative twips to absolute ones. ++ Rectangle aRectangle(*pRectangle); ++ vcl::Window& rParent = *mrSidebarWin.EditWin(); ++ Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel()); ++ rParent.Push(PushFlags::MAPMODE); ++ rParent.EnableMapMode(); ++ aOffset = rParent.PixelToLogic(aOffset); ++ rParent.Pop(); ++ aRectangle.Move(aOffset.getX(), aOffset.getY()); ++ ++ sRectangle = aRectangle.toString(); ++ } ++ ++ SwWrtShell& rWrtShell = mrDocView.GetWrtShell(); ++ rWrtShell.libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); ++} ++ + void SidebarTextControl::KeyInput( const KeyEvent& rKeyEvt ) + { + const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode(); +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.hxx b/sw/source/uibase/docvw/SidebarTxtControl.hxx +index 43d6b98d82c1..f73b68c950ae 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.hxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.hxx +@@ -40,6 +40,8 @@ class SidebarTextControl : public Control + + protected: + virtual void Paint( vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE; ++ /// @see OutputDevice::LogicInvalidate(). ++ void LogicInvalidate(const Rectangle* pRectangle) override; + virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE; + virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE; + virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE; +-- +2.12.0 + diff --git a/SOURCES/0328-sw-lok-comments-implement-setTextSelection-API.patch b/SOURCES/0328-sw-lok-comments-implement-setTextSelection-API.patch new file mode 100644 index 0000000..ef501e3 --- /dev/null +++ b/SOURCES/0328-sw-lok-comments-implement-setTextSelection-API.patch @@ -0,0 +1,139 @@ +From 03db067b74739dabe787dbce6af1f4b776ce888a Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 10:37:45 +0100 +Subject: [PATCH 328/398] sw lok comments: implement setTextSelection() API + +So that it's possible to drag the text selection start/end handles in +comment text when there is an existing selection. + +(cherry picked from commit e320d070bb0d4dd0ceb696f2c7cc5afb7c4273c3) + +Change-Id: I3acc4770928d4f385f0ca09a2484a9e112409907 +--- + sw/inc/SidebarWin.hxx | 2 ++ + sw/source/uibase/docvw/SidebarWin.cxx | 60 +++++++++++++++++++++++------------ + sw/source/uibase/docvw/edtwin.cxx | 10 ++++++ + 3 files changed, 51 insertions(+), 21 deletions(-) + +diff --git a/sw/inc/SidebarWin.hxx b/sw/inc/SidebarWin.hxx +index e3899d5a1a8b..503f8f8a9771 100644 +--- a/sw/inc/SidebarWin.hxx ++++ b/sw/inc/SidebarWin.hxx +@@ -183,6 +183,8 @@ class SwSidebarWin : public vcl::Window + void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); + /// Is there a matching sub-widget inside this sidebar widget for rPointLogic? + bool IsHitWindow(const Point& rPointLogic); ++ /// Allows adjusting the point or mark of the selection to a document coordinate. ++ void SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark); + + protected: + virtual void DataChanged( const DataChangedEvent& aEvent) SAL_OVERRIDE; +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 71b763b84224..721ef95e4acf 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -83,6 +83,32 @@ + #include + #include + ++namespace ++{ ++ ++/// Translate absolute <-> relative twips: LOK wants absolute coordinates as output and gives absolute coordinates as input. ++void lcl_translateTwips(vcl::Window& rParent, vcl::Window& rChild, MouseEvent* pMouseEvent) ++{ ++ // Set map mode, so that callback payloads will contain absolute coordinates instead of relative ones. ++ Point aOffset(rChild.GetOutOffXPixel() - rParent.GetOutOffXPixel(), rChild.GetOutOffYPixel() - rParent.GetOutOffYPixel()); ++ aOffset = rChild.PixelToLogic(aOffset); ++ MapMode aMapMode(rChild.GetMapMode()); ++ aMapMode.SetOrigin(aOffset); ++ rChild.SetMapMode(aMapMode); ++ rChild.EnableMapMode(false); ++ ++ if (pMouseEvent) ++ { ++ // Set event coordinates, so they contain relative coordinates instead of absolute ones. ++ Point aPos = pMouseEvent->GetPosPixel(); ++ aPos.Move(-aOffset.getX(), -aOffset.getY()); ++ MouseEvent aMouseEvent(aPos, pMouseEvent->GetClicks(), pMouseEvent->GetMode(), pMouseEvent->GetButtons(), pMouseEvent->GetModifier()); ++ *pMouseEvent = aMouseEvent; ++ } ++} ++ ++} ++ + namespace sw { namespace sidebarwindows { + + #define METABUTTON_WIDTH 16 +@@ -290,6 +316,19 @@ bool SwSidebarWin::IsHitWindow(const Point& rPointLogic) + return aRectangleLogic.IsInside(rPointLogic); + } + ++void SwSidebarWin::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark) ++{ ++ mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ MouseEvent aMouseEvent(rPosition); ++ lcl_translateTwips(*EditWin(), *mpSidebarTextControl, &aMouseEvent); ++ Point aPosition(aMouseEvent.GetPosPixel()); ++ ++ EditView& rEditView = GetOutlinerView()->GetEditView(); ++ rEditView.SetCursorLogicPosition(aPosition, bPoint, bClearMark); ++ ++ mpSidebarTextControl->Pop(); ++} ++ + void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, sal_uLong nInFlags) + { + if (mpMetadataAuthor->IsVisible() ) +@@ -358,27 +397,6 @@ void SwSidebarWin::Draw(OutputDevice* pDev, const Point& rPt, const Size& rSz, s + } + } + +-/// Translate absolute <-> relative twips: LOK wants absolute coordinates as output and gives absolute coordinates as input. +-static void lcl_translateTwips(vcl::Window& rParent, vcl::Window& rChild, MouseEvent* pMouseEvent) +-{ +- // Set map mode, so that callback payloads will contain absolute coordinates instead of relative ones. +- Point aOffset(rChild.GetOutOffXPixel() - rParent.GetOutOffXPixel(), rChild.GetOutOffYPixel() - rParent.GetOutOffYPixel()); +- aOffset = rChild.PixelToLogic(aOffset); +- MapMode aMapMode(rChild.GetMapMode()); +- aMapMode.SetOrigin(aOffset); +- rChild.SetMapMode(aMapMode); +- rChild.EnableMapMode(false); +- +- if (pMouseEvent) +- { +- // Set event coordinates, so they contain relative coordinates instead of absolute ones. +- Point aPos = pMouseEvent->GetPosPixel(); +- aPos.Move(-aOffset.getX(), -aOffset.getY()); +- MouseEvent aMouseEvent(aPos, pMouseEvent->GetClicks(), pMouseEvent->GetMode(), pMouseEvent->GetButtons(), pMouseEvent->GetModifier()); +- *pMouseEvent = aMouseEvent; +- } +-} +- + void SwSidebarWin::KeyInput(const KeyEvent& rKeyEvent) + { + if (mpSidebarTextControl) +diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx +index 53d0afd38f94..b9777914c5b4 100644 +--- a/sw/source/uibase/docvw/edtwin.cxx ++++ b/sw/source/uibase/docvw/edtwin.cxx +@@ -6299,6 +6299,16 @@ void SwEditWin::SetCursorTwipPosition(const Point& rPosition, bool bPoint, bool + } + } + ++ if (m_rView.GetPostItMgr()) ++ { ++ if (sw::sidebarwindows::SwSidebarWin* pWin = m_rView.GetPostItMgr()->GetActiveSidebarWin()) ++ { ++ // Editing postit text. ++ pWin->SetCursorLogicPosition(rPosition, bPoint, bClearMark); ++ return; ++ } ++ } ++ + // Not an SwWrtShell, as that would make SwCrsrShell::GetCrsr() inaccessible. + SwEditShell& rShell = m_rView.GetWrtShell(); + +-- +2.12.0 + diff --git a/SOURCES/0329-sw-lok-comments-fix-callback-of-newly-created-outlin.patch b/SOURCES/0329-sw-lok-comments-fix-callback-of-newly-created-outlin.patch new file mode 100644 index 0000000..d222239 --- /dev/null +++ b/SOURCES/0329-sw-lok-comments-fix-callback-of-newly-created-outlin.patch @@ -0,0 +1,83 @@ +From d82649ea6f8232d52e1fe4e48ad6ccf1668418a8 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 11:06:08 +0100 +Subject: [PATCH 329/398] sw lok comments: fix callback of newly created + outliner views + +SwPostItMgr::registerLibreOfficeKitCallback() already took care of +informing existing outliners, this commit gives a callback to newly +registered ones as well. + +(cherry picked from commit dacc616f7020d045a1cfdb3806436e06046dae10) + +Change-Id: I660dcb54231a9d404bf80b4284003d119dae6a5c +--- + sw/inc/drawdoc.hxx | 2 ++ + sw/source/core/draw/drawdoc.cxx | 6 ++++++ + sw/source/uibase/docvw/SidebarWin.cxx | 13 +++++++++++++ + 3 files changed, 21 insertions(+) + +diff --git a/sw/inc/drawdoc.hxx b/sw/inc/drawdoc.hxx +index bad9c0ca41a1..bbf079911656 100644 +--- a/sw/inc/drawdoc.hxx ++++ b/sw/inc/drawdoc.hxx +@@ -42,6 +42,8 @@ public: + + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::embed::XStorage> GetDocumentStorage() const SAL_OVERRIDE; ++ /// Get the callback and callback data, previously given to registerLibreOfficeKitCallback(). ++ void getLibreOfficeKitCallback(LibreOfficeKitCallback& rCallback, void*& rLibreOfficeKitData); + + /// For saving of rectangles as control-replacement for versions < 5.0. + virtual SdrLayerID GetControlExportLayerId( const SdrObject & ) const SAL_OVERRIDE; +diff --git a/sw/source/core/draw/drawdoc.cxx b/sw/source/core/draw/drawdoc.cxx +index efd0bb1f163d..7f352c981890 100644 +--- a/sw/source/core/draw/drawdoc.cxx ++++ b/sw/source/core/draw/drawdoc.cxx +@@ -126,6 +126,12 @@ uno::Reference SwDrawModel::GetDocumentStorage() const + return m_pDoc->GetDocStorage(); + } + ++void SwDrawModel::getLibreOfficeKitCallback(LibreOfficeKitCallback& rCallback, void*& rLibreOfficeKitData) ++{ ++ rCallback = mpLibreOfficeKitCallback; ++ rLibreOfficeKitData = mpLibreOfficeKitData; ++} ++ + SdrLayerID SwDrawModel::GetControlExportLayerId( const SdrObject & ) const + { + //for versions < 5.0, there was only Hell and Heaven +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 721ef95e4acf..32d8b78815ae 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -82,6 +82,8 @@ + #include + #include + #include ++#include ++#include + + namespace + { +@@ -532,6 +534,17 @@ void SwSidebarWin::InitControls() + + mpOutlinerView->SetAttribs(DefaultItem()); + ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ // If there is a callback already registered, inform the new outliner view about it. ++ SwDrawModel* pDrawModel = mrView.GetWrtShellPtr()->getIDocumentDrawModelAccess()->GetDrawModel(); ++ LibreOfficeKitCallback pCallback = 0; ++ void* pData = 0; ++ pDrawModel->getLibreOfficeKitCallback(pCallback, pData); ++ mpOutlinerView->setTiledRendering(mrView.GetWrtShellPtr()->isTiledRendering()); ++ mpOutlinerView->registerLibreOfficeKitCallback(pCallback, pData); ++ } ++ + //create Scrollbars + mpVScrollbar = VclPtr::Create(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG); + mpVScrollbar->EnableNativeWidget(false); +-- +2.12.0 + diff --git a/SOURCES/0330-sw-lok-comments-fix-cursor-position-of-a-newly-creat.patch b/SOURCES/0330-sw-lok-comments-fix-cursor-position-of-a-newly-creat.patch new file mode 100644 index 0000000..509c6fa --- /dev/null +++ b/SOURCES/0330-sw-lok-comments-fix-cursor-position-of-a-newly-creat.patch @@ -0,0 +1,47 @@ +From bade9dc2b36b7ee92fa9ada8e033639a8c49a593 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 13:39:02 +0100 +Subject: [PATCH 330/398] sw lok comments: fix cursor position of a newly + created sidebar window + +With this, pressing ctrl-alt-c to create a new comment has the correct +cursor position. + +Change-Id: Icb8d708dab015d8ffa9bcfe28de66238a75b50bc +(cherry picked from commit d78432e9a077725046419902c542ce4e5f515705) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 32d8b78815ae..cf803b618263 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -666,7 +666,24 @@ void SwSidebarWin::SetPosAndSize() + { + bChange = true; + SetSizePixel(mPosSize.GetSize()); ++ ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ // Position is not yet set at VCL level, but the map mode should ++ // contain the right origin to emit the correct cursor position. ++ mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ Point aOffset(mPosSize.Left(), mPosSize.Top()); ++ aOffset = PixelToLogic(aOffset); ++ MapMode aMapMode(mpSidebarTextControl->GetMapMode()); ++ aMapMode.SetOrigin(aOffset); ++ mpSidebarTextControl->SetMapMode(aMapMode); ++ mpSidebarTextControl->EnableMapMode(false); ++ } ++ + DoResize(); ++ ++ if (comphelper::LibreOfficeKit::isActive()) ++ mpSidebarTextControl->Pop(); + } + + if (GetPosPixel().X() != mPosSize.TopLeft().X() || (std::abs(GetPosPixel().Y() - mPosSize.TopLeft().Y()) > 5) ) +-- +2.12.0 + diff --git a/SOURCES/0331-sw-lok-comments-implement-mouse-move-and-mouse-up.patch b/SOURCES/0331-sw-lok-comments-implement-mouse-move-and-mouse-up.patch new file mode 100644 index 0000000..c4ab333 --- /dev/null +++ b/SOURCES/0331-sw-lok-comments-implement-mouse-move-and-mouse-up.patch @@ -0,0 +1,164 @@ +From 21874265eac2c8f10f560941079fe651e097b9d4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 14:42:26 +0100 +Subject: [PATCH 331/398] sw lok comments: implement mouse move and mouse up + +As long as we don't tweak the map mode of the comment widgets +permanently we also have to disable the selection engine's timer, as +that would emit events without the correct map mode: so disable that for +the LOK case for now. + +(cherry picked from commit b3dc0d7c72c2bb997bfceaeaf25dc9153ceca244) + +Change-Id: If377ff2f064c30feb473f153f9d5b29b8ace7113 +--- + sw/inc/SidebarWin.hxx | 2 ++ + sw/source/uibase/docvw/SidebarTxtControl.hxx | 4 ++-- + sw/source/uibase/docvw/SidebarWin.cxx | 28 ++++++++++++++++++++++++++++ + sw/source/uibase/docvw/edtwin.cxx | 18 ++++++++++++++++++ + vcl/source/window/seleng.cxx | 5 ++++- + 5 files changed, 54 insertions(+), 3 deletions(-) + +diff --git a/sw/inc/SidebarWin.hxx b/sw/inc/SidebarWin.hxx +index 503f8f8a9771..e647c7aca820 100644 +--- a/sw/inc/SidebarWin.hxx ++++ b/sw/inc/SidebarWin.hxx +@@ -180,6 +180,8 @@ class SwSidebarWin : public vcl::Window + virtual void Draw(OutputDevice* pDev, const Point&, const Size&, sal_uLong) override; + virtual void KeyInput(const KeyEvent& rKeyEvt) override; + virtual void MouseButtonDown(const MouseEvent& rMouseEvent) override; ++ virtual void MouseButtonUp(const MouseEvent& rMouseEvent) override; ++ virtual void MouseMove(const MouseEvent& rMouseEvent) override; + void PaintTile(vcl::RenderContext& rRenderContext, const Rectangle& rRect); + /// Is there a matching sub-widget inside this sidebar widget for rPointLogic? + bool IsHitWindow(const Point& rPointLogic); +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.hxx b/sw/source/uibase/docvw/SidebarTxtControl.hxx +index f73b68c950ae..ab2f7406bce2 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.hxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.hxx +@@ -42,8 +42,6 @@ class SidebarTextControl : public Control + virtual void Paint( vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE; + /// @see OutputDevice::LogicInvalidate(). + void LogicInvalidate(const Rectangle* pRectangle) override; +- virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE; +- virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE; + virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE; + virtual void LoseFocus() SAL_OVERRIDE; + virtual void RequestHelp(const HelpEvent &rEvt) SAL_OVERRIDE; +@@ -63,6 +61,8 @@ class SidebarTextControl : public Control + virtual void GetFocus() override; + virtual void KeyInput( const KeyEvent& rKeyEvt ) override; + virtual void MouseButtonDown(const MouseEvent& rMouseEvent) override; ++ virtual void MouseButtonUp(const MouseEvent& rMEvt) override; ++ virtual void MouseMove(const MouseEvent& rMEvt) override; + + OutlinerView* GetTextView() const; + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index cf803b618263..f9163a80f44b 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -412,6 +412,20 @@ void SwSidebarWin::KeyInput(const KeyEvent& rKeyEvent) + } + } + ++void SwSidebarWin::MouseMove(const MouseEvent& rMouseEvent) ++{ ++ if (mpSidebarTextControl) ++ { ++ mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ MouseEvent aMouseEvent(rMouseEvent); ++ lcl_translateTwips(*EditWin(), *mpSidebarTextControl, &aMouseEvent); ++ ++ mpSidebarTextControl->MouseMove(aMouseEvent); ++ ++ mpSidebarTextControl->Pop(); ++ } ++} ++ + void SwSidebarWin::MouseButtonDown(const MouseEvent& rMouseEvent) + { + if (mpSidebarTextControl) +@@ -426,6 +440,20 @@ void SwSidebarWin::MouseButtonDown(const MouseEvent& rMouseEvent) + } + } + ++void SwSidebarWin::MouseButtonUp(const MouseEvent& rMouseEvent) ++{ ++ if (mpSidebarTextControl) ++ { ++ mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ MouseEvent aMouseEvent(rMouseEvent); ++ lcl_translateTwips(*EditWin(), *mpSidebarTextControl, &aMouseEvent); ++ ++ mpSidebarTextControl->MouseButtonUp(aMouseEvent); ++ ++ mpSidebarTextControl->Pop(); ++ } ++} ++ + void SwSidebarWin::SetPosSizePixelRect(long nX, long nY, long nWidth, long nHeight, + const SwRect& aAnchorRect, const long aPageBorder) + { +diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx +index b9777914c5b4..cfb054a645fb 100644 +--- a/sw/source/uibase/docvw/edtwin.cxx ++++ b/sw/source/uibase/docvw/edtwin.cxx +@@ -3706,6 +3706,15 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt) + { + MouseEvent rMEvt(_rMEvt); + ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel())) ++ { ++ pWindow->MouseMove(rMEvt); ++ return; ++ } ++ } ++ + //ignore key modifiers for format paintbrush + { + bool bExecFormatPaintbrush = m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard +@@ -4211,6 +4220,15 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt) + */ + void SwEditWin::MouseButtonUp(const MouseEvent& rMEvt) + { ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ if (vcl::Window* pWindow = m_rView.GetPostItMgr()->IsHitSidebarWindow(rMEvt.GetPosPixel())) ++ { ++ pWindow->MouseButtonUp(rMEvt); ++ return; ++ } ++ } ++ + bool bCallBase = true; + + bool bCallShadowCrsr = m_bWasShdwCrsr; +diff --git a/vcl/source/window/seleng.cxx b/vcl/source/window/seleng.cxx +index 7999818b509c..69b220bedfcc 100644 +--- a/vcl/source/window/seleng.cxx ++++ b/vcl/source/window/seleng.cxx +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + FunctionSet::~FunctionSet() + { +@@ -301,7 +302,9 @@ bool SelectionEngine::SelMouseMove( const MouseEvent& rMEvt ) + return true; + + aWTimer.SetTimeout( nUpdateInterval ); +- aWTimer.Start(); ++ if (!comphelper::LibreOfficeKit::isActive()) ++ // Generating fake mouse moves does not work with LOK. ++ aWTimer.Start(); + if ( eSelMode != SINGLE_SELECTION ) + { + if ( !(nFlags & SelectionEngineFlags::HAS_ANCH) ) +-- +2.12.0 + diff --git a/SOURCES/0332-gtktiledviewer-the-formula-bar-is-calc-only.patch b/SOURCES/0332-gtktiledviewer-the-formula-bar-is-calc-only.patch new file mode 100644 index 0000000..f7e3c9a --- /dev/null +++ b/SOURCES/0332-gtktiledviewer-the-formula-bar-is-calc-only.patch @@ -0,0 +1,34 @@ +From 7ab3c2c56b294cb71e09fbbb1dfb7cb9a8c55504 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 15:05:33 +0100 +Subject: [PATCH 332/398] gtktiledviewer: the formula bar is calc-only + +Change-Id: Ib989a23e5ece49b6eb16b25bb1fb6f635df25829 +(cherry picked from commit 9caca9fe23ac8e193f89a11503d92b058669a660) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 45ccef792905..7f3d94be5959 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -303,6 +303,7 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi + } + gtk_widget_show(rWindow.m_pColumnBar->m_pDrawingArea); + gtk_widget_queue_draw(rWindow.m_pColumnBar->m_pDrawingArea); ++ gtk_widget_show(rWindow.m_pFormulabarEntry); + } + + return TRUE; +@@ -1187,6 +1188,7 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_widget_hide(rWindow.m_pCornerButton->m_pDrawingArea); + gtk_widget_hide(rWindow.m_pRowBar->m_pDrawingArea); + gtk_widget_hide(rWindow.m_pColumnBar->m_pDrawingArea); ++ gtk_widget_hide(rWindow.m_pFormulabarEntry); + // Hide the non-progressbar children of the status bar by default. + gtk_widget_hide(rWindow.m_pStatusbarLabel); + gtk_widget_hide(rWindow.m_pZoomLabel); +-- +2.12.0 + diff --git a/SOURCES/0333-gtktiledviewer-add-toolbar-buttons-to-insert-delete-.patch b/SOURCES/0333-gtktiledviewer-add-toolbar-buttons-to-insert-delete-.patch new file mode 100644 index 0000000..ef2e27b --- /dev/null +++ b/SOURCES/0333-gtktiledviewer-add-toolbar-buttons-to-insert-delete-.patch @@ -0,0 +1,43 @@ +From dbf9e629020d9b37a0dcec09dbb2e6dfd159519e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 15:10:18 +0100 +Subject: [PATCH 333/398] gtktiledviewer: add toolbar buttons to insert / + delete comments + +Change-Id: Ia566e983548a89d974c133823da2f07d5c2e35e4 +(cherry picked from commit bd05cc9a5093bbf5d2e136a6589be612df81d27e) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 7f3d94be5959..86fc9e539b39 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -1093,6 +1093,23 @@ static GtkWidget* createWindow(TiledWindow& rWindow) + gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), rWindow.m_pJustifypara, -1); + g_signal_connect(G_OBJECT(rWindow.m_pJustifypara), "toggled", G_CALLBACK(toggleToolItem), NULL); + lcl_registerToolItem(rWindow, rWindow.m_pJustifypara, ".uno:JustifyPara"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), gtk_separator_tool_item_new(), -1); ++ ++ // Insert/delete comments. ++ GtkToolItem* pInsertAnnotation = gtk_tool_button_new(nullptr, nullptr); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pInsertAnnotation), "changes-allow-symbolic"); ++ gtk_tool_item_set_tooltip_text(pInsertAnnotation, "Insert Comment"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), pInsertAnnotation, -1); ++ g_signal_connect(G_OBJECT(pInsertAnnotation), "clicked", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, pInsertAnnotation, ".uno:InsertAnnotation"); ++ ++ GtkToolItem* pDeleteComment = gtk_tool_button_new(nullptr, nullptr); ++ gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(pDeleteComment), "changes-prevent-symbolic"); ++ gtk_tool_item_set_tooltip_text(pDeleteComment, "Delete Comment"); ++ gtk_toolbar_insert(GTK_TOOLBAR(pLowerToolbar), pDeleteComment, -1); ++ g_signal_connect(G_OBJECT(pDeleteComment), "clicked", G_CALLBACK(toggleToolItem), NULL); ++ lcl_registerToolItem(rWindow, pDeleteComment, ".uno:DeleteComment"); ++ + // Formula bar + GtkToolItem* pFormulaEntryContainer = gtk_tool_item_new(); + rWindow.m_pFormulabarEntry = gtk_entry_new(); +-- +2.12.0 + diff --git a/SOURCES/0334-CppunitTest_sw_tiledrendering-replace-various-ifdefs.patch b/SOURCES/0334-CppunitTest_sw_tiledrendering-replace-various-ifdefs.patch new file mode 100644 index 0000000..d8f35c6 --- /dev/null +++ b/SOURCES/0334-CppunitTest_sw_tiledrendering-replace-various-ifdefs.patch @@ -0,0 +1,183 @@ +From 2a75ef1ce370310a06b30de34799c0cb39f6bfea Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 15:35:18 +0100 +Subject: [PATCH 334/398] CppunitTest_sw_tiledrendering: replace various ifdefs + with a single condition + +LOK is Linux-only at the moment, don't bother with disabling each and +every unit test on Mac/Windows for now. + +Change-Id: I2ff1ed47251c16ec6a8d43138789480d95ea720e +(cherry picked from commit 18dfcbb11a05b7e702dc2161df9db8386a7ca34b) +--- + sw/Module_sw.mk | 7 +++++- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 34 +------------------------- + 2 files changed, 7 insertions(+), 34 deletions(-) + +diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk +index 13453b5beb10..80b1ffb85e14 100644 +--- a/sw/Module_sw.mk ++++ b/sw/Module_sw.mk +@@ -68,11 +68,16 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\ + CppunitTest_sw_odfexport \ + CppunitTest_sw_odfimport \ + CppunitTest_sw_uiwriter \ +- CppunitTest_sw_tiledrendering \ + CppunitTest_sw_mailmerge \ + CppunitTest_sw_globalfilter \ + )) + ++ifeq ($(OS),LINUX) ++$(eval $(call gb_Module_add_slowcheck_targets,sw,\ ++ CppunitTest_sw_tiledrendering \ ++)) ++endif ++ + ifneq ($(DISABLE_CVE_TESTS),TRUE) + $(eval $(call gb_Module_add_slowcheck_targets,sw,\ + CppunitTest_sw_filters_test \ +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index 4598c50e5842..9f85fe8e1290 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -150,18 +150,6 @@ void SwTiledRenderingTest::callbackImpl(int nType, const char* pPayload) + + void SwTiledRenderingTest::testRegisterCallback() + { +-#ifdef MACOSX +- // For some reason this particular test requires window system access on OS X. +- +- // Without window system access, we do get a number of "<<>> +- // AquaSalGraphics::CheckContext() FAILED!!!!" [sic] and " : CGSConnectionByID: 0 is +- // not a valid connection ID" warnings while running the other tests, too, but they still +- // succeed. +- +- if (!vcl::IsWindowSystemAvailable()) +- return; +-#endif +- + SwXTextDocument* pXTextDocument = createDoc("dummy.fodt"); + pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this); + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); +@@ -170,13 +158,8 @@ void SwTiledRenderingTest::testRegisterCallback() + + // Check that the top left 256x256px tile would be invalidated. + CPPUNIT_ASSERT(!m_aInvalidation.IsEmpty()); +-#if !defined(WNT) && !defined(MACOSX) + Rectangle aTopLeft(0, 0, 256*15, 256*15); // 1 px = 15 twips, assuming 96 DPI. +- // FIXME - fails on Windows since about cbd48230bb3a90c4c485fa33123c6653234e02e9 +- // [plus minus few commits maybe] +- // Also on OS X. But is tiled rendering even supposed to work on Windows and OS X? + CPPUNIT_ASSERT(m_aInvalidation.IsOver(aTopLeft)); +-#endif + } + + void SwTiledRenderingTest::testPostKeyEvent() +@@ -290,9 +273,7 @@ void SwTiledRenderingTest::testSetGraphicSelection() + Rectangle aShapeAfter = pObject->GetSnapRect(); + // Check that a resize happened, but aspect ratio is not kept. + CPPUNIT_ASSERT_EQUAL(aShapeBefore.getWidth(), aShapeAfter.getWidth()); +-#if !defined(MACOSX) // FIXME + CPPUNIT_ASSERT_EQUAL(aShapeBefore.getHeight() + 1000, aShapeAfter.getHeight()); +-#endif + } + + void SwTiledRenderingTest::testResetSelection() +@@ -322,7 +303,6 @@ void SwTiledRenderingTest::testResetSelection() + CPPUNIT_ASSERT(!pWrtShell->IsSelFrmMode()); + } + +-#if !(defined WNT || defined MACOSX) + void lcl_search(bool bBackward) + { + uno::Sequence aPropertyValues(comphelper::InitPropertySequence( +@@ -332,11 +312,9 @@ void lcl_search(bool bBackward) + })); + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + } +-#endif + + void SwTiledRenderingTest::testSearch() + { +-#if !defined(WNT) && !defined(MACOSX) + comphelper::LibreOfficeKit::setActive(); + + SwXTextDocument* pXTextDocument = createDoc("search.odt"); +@@ -377,12 +355,10 @@ void SwTiledRenderingTest::testSearch() + CPPUNIT_ASSERT_EQUAL(nNode + 1, nActual); + + comphelper::LibreOfficeKit::setActive(false); +-#endif + } + + void SwTiledRenderingTest::testSearchViewArea() + { +-#if !defined(WNT) && !defined(MACOSX) + SwXTextDocument* pXTextDocument = createDoc("search.odt"); + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); + // Go to the second page, 1-based. +@@ -404,12 +380,10 @@ void SwTiledRenderingTest::testSearchViewArea() + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + // This was just "Heading", i.e. SwView::SearchAndWrap() did not search from only the top of the second page. + CPPUNIT_ASSERT_EQUAL(OUString("Heading on second page"), pShellCrsr->GetPoint()->nNode.GetNode().GetTextNode()->GetText()); +-#endif + } + + void SwTiledRenderingTest::testSearchTextFrame() + { +-#if !defined(WNT) && !defined(MACOSX) + comphelper::LibreOfficeKit::setActive(); + + SwXTextDocument* pXTextDocument = createDoc("search.odt"); +@@ -424,12 +398,10 @@ void SwTiledRenderingTest::testSearchTextFrame() + CPPUNIT_ASSERT(!m_aTextSelection.isEmpty()); + + comphelper::LibreOfficeKit::setActive(false); +-#endif + } + + void SwTiledRenderingTest::testSearchTextFrameWrapAround() + { +-#if !defined(WNT) && !defined(MACOSX) + SwXTextDocument* pXTextDocument = createDoc("search.odt"); + pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this); + uno::Sequence aPropertyValues(comphelper::InitPropertySequence( +@@ -442,12 +414,10 @@ void SwTiledRenderingTest::testSearchTextFrameWrapAround() + comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues); + // This failed, i.e. the second time 'not found' was reported, instead of wrapping around. + CPPUNIT_ASSERT(m_bFound); +-#endif + } + + void SwTiledRenderingTest::testDocumentSizeChanged() + { +-#if !defined(WNT) && !defined(MACOSX) + // Get the current document size. + SwXTextDocument* pXTextDocument = createDoc("2-pages.odt"); + pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this); +@@ -462,12 +432,10 @@ void SwTiledRenderingTest::testDocumentSizeChanged() + CPPUNIT_ASSERT_EQUAL(aSize.getWidth(), m_aDocumentSize.getWidth()); + // Document height should be smaller now. + CPPUNIT_ASSERT(aSize.getHeight() > m_aDocumentSize.getHeight()); +-#endif + } + + void SwTiledRenderingTest::testSearchAll() + { +-#if !defined(WNT) && !defined(MACOSX) + comphelper::LibreOfficeKit::setActive(); + + SwXTextDocument* pXTextDocument = createDoc("search.odt"); +@@ -485,8 +453,8 @@ void SwTiledRenderingTest::testSearchAll() + CPPUNIT_ASSERT_EQUAL(0, m_aSearchResultPart[0]); + + comphelper::LibreOfficeKit::setActive(false); +-#endif + } ++ + CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +-- +2.12.0 + diff --git a/SOURCES/0335-CppunitTest_desktop_lib-add-Writer-comments-textcase.patch b/SOURCES/0335-CppunitTest_desktop_lib-add-Writer-comments-textcase.patch new file mode 100644 index 0000000..155d5e0 --- /dev/null +++ b/SOURCES/0335-CppunitTest_desktop_lib-add-Writer-comments-textcase.patch @@ -0,0 +1,109 @@ +From a779115ee56769b7691b02e4b8739c5c8f81258e Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Sat, 14 Nov 2015 16:59:01 +0100 +Subject: [PATCH 335/398] CppunitTest_desktop_lib: add Writer comments textcase + +Fails without e.g. the last hunk of commit +1ba9d7fd2a7a3e2b4f52ed0f5efdf7df867b9db3 (sw lok: forward key events to +annotation window if necessary, 2015-11-12). + +Change-Id: I7f39530881f6141fea956b751aa57eb2bdcadcb2 +(cherry picked from commit 1118689e70ed49604ded6e1ae83a22bdc995b2fb) +--- + desktop/CppunitTest_desktop_lib.mk | 1 + + desktop/qa/desktop_lib/test_desktop_lib.cxx | 46 +++++++++++++++++++++++++++++ + 2 files changed, 47 insertions(+) + +diff --git a/desktop/CppunitTest_desktop_lib.mk b/desktop/CppunitTest_desktop_lib.mk +index ca9d8db32c9f..bbedfdc8348e 100644 +--- a/desktop/CppunitTest_desktop_lib.mk ++++ b/desktop/CppunitTest_desktop_lib.mk +@@ -67,6 +67,7 @@ $(eval $(call gb_CppunitTest_use_components,desktop_lib,\ + xmloff/util/xo \ + i18npool/source/search/i18nsearch \ + filter/source/graphic/graphicfilter \ ++ linguistic/source/lng \ + )) + + $(eval $(call gb_CppunitTest_use_configuration,desktop_lib)) +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 7d94daea0fbc..930dd21ec081 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -10,6 +10,10 @@ + #include + #include + #include ++#include ++#include ++#include ++#include + + #include + #include +@@ -70,6 +74,7 @@ public: + void testRowColumnHeaders(); + void testCellCursor(); + void testCommandResult(); ++ void testWriterComments(); + + CPPUNIT_TEST_SUITE(DesktopLOKTest); + CPPUNIT_TEST(testGetStyles); +@@ -85,6 +90,7 @@ public: + CPPUNIT_TEST(testRowColumnHeaders); + CPPUNIT_TEST(testCellCursor); + CPPUNIT_TEST(testCommandResult); ++ CPPUNIT_TEST(testWriterComments); + CPPUNIT_TEST_SUITE_END(); + + uno::Reference mxComponent; +@@ -491,6 +497,46 @@ void DesktopLOKTest::testCommandResult() + CPPUNIT_ASSERT_EQUAL(aTree.get_child("success").get_value(), true); + } + ++void DesktopLOKTest::testWriterComments() ++{ ++ comphelper::LibreOfficeKit::setActive(); ++ LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); ++ pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); ++ uno::Reference xToolkit(com::sun::star::awt::Toolkit::create(comphelper::getProcessComponentContext()), uno::UNO_QUERY); ++ ++ // Insert a comment at the beginning of the document and wait till the main ++ // loop grabs the focus, so characters end up in the annotation window. ++ TimeValue aTimeValue = {2 , 0}; // 2 seconds max ++ m_aCommandResultCondition.reset(); ++ pDocument->pClass->postUnoCommand(pDocument, ".uno:InsertAnnotation", nullptr, true); ++ m_aCommandResultCondition.wait(aTimeValue); ++ CPPUNIT_ASSERT(!m_aCommandResult.isEmpty()); ++ xToolkit->reschedule(); ++ ++ // Test that we have a comment. ++ uno::Reference xTextDocument(mxComponent, uno::UNO_QUERY); ++ uno::Reference xParagraphEnumerationAccess(xTextDocument->getText(), uno::UNO_QUERY); ++ uno::Reference xParagraphEnumeration = xParagraphEnumerationAccess->createEnumeration(); ++ uno::Reference xParagraph(xParagraphEnumeration->nextElement(), uno::UNO_QUERY); ++ uno::Reference xTextPortionEnumeration = xParagraph->createEnumeration(); ++ uno::Reference xTextPortion(xTextPortionEnumeration->nextElement(), uno::UNO_QUERY); ++ CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), xTextPortion->getPropertyValue("TextPortionType").get()); ++ ++ // Type "test" and finish editing. ++ pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0); ++ pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 'e', 0); ++ pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 's', 0); ++ pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0); ++ pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 0, com::sun::star::awt::Key::ESCAPE); ++ ++ // Test that the typed characters ended up in the right window. ++ auto xTextField = xTextPortion->getPropertyValue("TextField").get< uno::Reference >(); ++ // This was empty, typed characters ended up in the body text. ++ CPPUNIT_ASSERT_EQUAL(OUString("test"), xTextField->getPropertyValue("Content").get()); ++ ++ comphelper::LibreOfficeKit::setActive(false); ++} ++ + CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest); + + CPPUNIT_PLUGIN_IMPLEMENT(); +-- +2.12.0 + diff --git a/SOURCES/0336-sc-lok-use-client-zoom-for-ViewRowColumnHeaders.patch b/SOURCES/0336-sc-lok-use-client-zoom-for-ViewRowColumnHeaders.patch new file mode 100644 index 0000000..360ee8d --- /dev/null +++ b/SOURCES/0336-sc-lok-use-client-zoom-for-ViewRowColumnHeaders.patch @@ -0,0 +1,48 @@ +From 381c84511f6adf660189af85ff615e841e00977a Mon Sep 17 00:00:00 2001 +From: Andrzej Hunt +Date: Mon, 16 Nov 2015 15:30:53 +0100 +Subject: [PATCH 336/398] sc lok: use client zoom for ViewRowColumnHeaders + +Change-Id: I85000851f82ea7cdc4b536683adbc8570de9af7e +(cherry picked from commit 396b5f411f7ecc7d600efdc0bb2381a7d1ed6d88) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 3 +++ + sc/source/ui/unoobj/docuno.cxx | 5 +++++ + 2 files changed, 8 insertions(+) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 930dd21ec081..1edf8d722d2f 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -405,6 +405,9 @@ void DesktopLOKTest::testRowColumnHeaders() + * "text" has the header label in UTF-8 + */ + LibLODocument_Impl* pDocument = loadDoc("search.ods"); ++ ++ pDocument->pClass->initializeForRendering(pDocument); ++ + boost::property_tree::ptree aTree; + char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); + std::stringstream aStream(pJSON); +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index c5a96e1e8255..c0f504d770c6 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -885,9 +885,14 @@ void ScModelObj::setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int + OUString ScModelObj::getRowColumnHeaders(const Rectangle& rRectangle) + { + ScViewData* pViewData = ScDocShell::GetViewData(); ++ + if (!pViewData) + return OUString(); + ++ // update the aLogicMode in ScViewData to something predictable ++ pViewData->SetZoom(Fraction(nTilePixelWidth * TWIPS_PER_PIXEL, nTileTwipWidth), ++ Fraction(nTilePixelHeight * TWIPS_PER_PIXEL, nTileTwipHeight), true); ++ + ScTabView* pTabView = pViewData->GetView(); + if (!pTabView) + return OUString(); +-- +2.12.0 + diff --git a/SOURCES/0337-sw-lok-comments-fix-sidebar-width-with-custom-zoom.patch b/SOURCES/0337-sw-lok-comments-fix-sidebar-width-with-custom-zoom.patch new file mode 100644 index 0000000..ca465c1 --- /dev/null +++ b/SOURCES/0337-sw-lok-comments-fix-sidebar-width-with-custom-zoom.patch @@ -0,0 +1,57 @@ +From a1641176c666645a2c61b3b9ebcba05f01350c12 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 16 Nov 2015 16:30:21 +0100 +Subject: [PATCH 337/398] sw lok comments: fix sidebar width with custom zoom + +Change-Id: I6772cce10d157421d983d6b93efb52bf8b95f5b8 +(cherry picked from commit dc65f048fd1b08d17e71e4d3a3a3c114aae871e6) +--- + sw/source/uibase/docvw/PostItMgr.cxx | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index 871a642d24da..fa82556554d1 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -1865,19 +1865,19 @@ bool SwPostItMgr::HasNotes() const + + unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const + { +- unsigned long aWidth = (unsigned long)(mpWrtShell->GetViewOptions()->GetZoom() * 1.8); ++ sal_uInt16 nZoom = mpWrtShell->GetViewOptions()->GetZoom(); ++ if (comphelper::LibreOfficeKit::isActive()) ++ { ++ // The output device contains the real wanted scale factor. ++ double fScaleX = mpWrtShell->GetOut()->GetMapMode().GetScaleX(); ++ nZoom = fScaleX * 100; ++ } ++ unsigned long aWidth = (unsigned long)(nZoom * 1.8); ++ + if (bPx) + return aWidth; + else +- { +- bool bEnableMapMode = comphelper::LibreOfficeKit::isActive() && !mpEditWin->IsMapModeEnabled(); +- if (bEnableMapMode) +- mpEditWin->EnableMapMode(); +- long nRet = mpEditWin->PixelToLogic(Size(aWidth, 0)).Width(); +- if (bEnableMapMode) +- mpEditWin->EnableMapMode(false); +- return nRet; +- } ++ return mpWrtShell->GetOut()->PixelToLogic(Size(aWidth, 0)).Width(); + } + + unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const +@@ -1885,7 +1885,7 @@ unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const + if (bPx) + return 2; + else +- return mpEditWin->PixelToLogic(Size(2,0)).Width(); ++ return mpWrtShell->GetOut()->PixelToLogic(Size(2,0)).Width(); + } + + unsigned long SwPostItMgr::GetNoteWidth() +-- +2.12.0 + diff --git a/SOURCES/0338-sw-lok-comments-fix-text-selection-with-custom-zoom.patch b/SOURCES/0338-sw-lok-comments-fix-text-selection-with-custom-zoom.patch new file mode 100644 index 0000000..ff6bb86 --- /dev/null +++ b/SOURCES/0338-sw-lok-comments-fix-text-selection-with-custom-zoom.patch @@ -0,0 +1,57 @@ +From 3fb5c82343761f02a956653d7afcdb96d509daf5 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 17 Nov 2015 12:21:42 +0100 +Subject: [PATCH 338/398] sw lok comments: fix text selection with custom zoom + +SwPostItMgr::GetSidebarWidth() can be called in two scenarios: + +- inside PaintTile() the output device contains the zoom level and has + the map mode enabled (and its scale factor is the zoom level) +- outisde PaintTile() the output device is SwEditWin and has the map + mode disabled (and the zoom level is to be taken from the view + options) + +Change-Id: I6cf19f3241a2e972ae711e0efa7b0205aae1a3f2 +(cherry picked from commit 0fd381b773cb7c15c4773affd4a3b298ad38fe92) +--- + sw/source/uibase/docvw/PostItMgr.cxx | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index fa82556554d1..40e2bda8f6b7 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -1865,10 +1865,11 @@ bool SwPostItMgr::HasNotes() const + + unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const + { ++ bool bEnableMapMode = !mpWrtShell->GetOut()->IsMapModeEnabled(); + sal_uInt16 nZoom = mpWrtShell->GetViewOptions()->GetZoom(); +- if (comphelper::LibreOfficeKit::isActive()) ++ if (comphelper::LibreOfficeKit::isActive() && !bEnableMapMode) + { +- // The output device contains the real wanted scale factor. ++ // The output device is the tile and contains the real wanted scale factor. + double fScaleX = mpWrtShell->GetOut()->GetMapMode().GetScaleX(); + nZoom = fScaleX * 100; + } +@@ -1877,7 +1878,15 @@ unsigned long SwPostItMgr::GetSidebarWidth(bool bPx) const + if (bPx) + return aWidth; + else +- return mpWrtShell->GetOut()->PixelToLogic(Size(aWidth, 0)).Width(); ++ { ++ if (bEnableMapMode) ++ // The output device is the window. ++ mpWrtShell->GetOut()->EnableMapMode(); ++ long nRet = mpWrtShell->GetOut()->PixelToLogic(Size(aWidth, 0)).Width(); ++ if (bEnableMapMode) ++ mpWrtShell->GetOut()->EnableMapMode(false); ++ return nRet; ++ } + } + + unsigned long SwPostItMgr::GetSidebarBorderWidth(bool bPx) const +-- +2.12.0 + diff --git a/SOURCES/0339-sw-lok-comments-fix-comment-widget-width-with-custom.patch b/SOURCES/0339-sw-lok-comments-fix-comment-widget-width-with-custom.patch new file mode 100644 index 0000000..6fdd495 --- /dev/null +++ b/SOURCES/0339-sw-lok-comments-fix-comment-widget-width-with-custom.patch @@ -0,0 +1,65 @@ +From f3edb775652b288ac0c4c38186b4d23bfa603a6c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 17 Nov 2015 17:07:47 +0100 +Subject: [PATCH 339/398] sw lok comments: fix comment widget width with custom + zoom + +When tiled rendering, then only the render context (or failing that, +SwViewShell::GetOut()) has the correct zoom level, so use that when +doing pixel-to-logic conversion or scaling pixel values. + +Change-Id: I265a642b8253c6eced42da2a0e06a2de25c36ca8 +(cherry picked from commit c9db32de2deeaa705e3da4945f62a94b75a7e4c5) +--- + sw/source/uibase/docvw/PostItMgr.cxx | 2 +- + sw/source/uibase/docvw/SidebarWin.cxx | 7 ++++--- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx +index 40e2bda8f6b7..e0ea88fd86b4 100644 +--- a/sw/source/uibase/docvw/PostItMgr.cxx ++++ b/sw/source/uibase/docvw/PostItMgr.cxx +@@ -870,7 +870,7 @@ void SwPostItMgr::PaintTile(OutputDevice& rRenderContext, const Rectangle& /*rRe + MapMode aMapMode(rRenderContext.GetMapMode()); + aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset); + rRenderContext.SetMapMode(aMapMode); +- Size aSize(pPostIt->PixelToLogic(pPostIt->GetSizePixel())); ++ Size aSize(rRenderContext.PixelToLogic(pPostIt->GetSizePixel())); + Rectangle aRectangle(Point(0, 0), aSize); + + pPostIt->PaintTile(rRenderContext, aRectangle); +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index f9163a80f44b..693bcdf5b09a 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -286,7 +286,8 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + continue; + + rRenderContext.Push(PushFlags::MAPMODE); +- Point aOffset(PixelToLogic(pChild->GetPosPixel())); ++ const Fraction& rFraction(mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY()); ++ Point aOffset(PixelToLogic(pChild->GetPosPixel() * rFraction.GetDenominator() / rFraction.GetNumerator())); + MapMode aMapMode(rRenderContext.GetMapMode()); + aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset); + rRenderContext.SetMapMode(aMapMode); +@@ -1411,7 +1412,7 @@ sal_Int32 SwSidebarWin::GetMetaButtonAreaWidth() + + sal_Int32 SwSidebarWin::GetMetaHeight() + { +- const Fraction& f( GetMapMode().GetScaleY() ); ++ const Fraction& f(mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY()); + return POSTIT_META_HEIGHT * f.GetNumerator() / f.GetDenominator(); + } + +@@ -1422,7 +1423,7 @@ sal_Int32 SwSidebarWin::GetMinimumSizeWithMeta() + + sal_Int32 SwSidebarWin::GetMinimumSizeWithoutMeta() + { +- const Fraction& f( GetMapMode().GetScaleY() ); ++ const Fraction& f(mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY()); + return POSTIT_MINIMUMSIZE_WITHOUT_META * f.GetNumerator() / f.GetDenominator(); + } + +-- +2.12.0 + diff --git a/SOURCES/0340-sw-lok-comments-fix-meta-author-data-size-with-custo.patch b/SOURCES/0340-sw-lok-comments-fix-meta-author-data-size-with-custo.patch new file mode 100644 index 0000000..4bc662c --- /dev/null +++ b/SOURCES/0340-sw-lok-comments-fix-meta-author-data-size-with-custo.patch @@ -0,0 +1,42 @@ +From 8e392047f43791e6876e21f4e4a9deccc92f734a Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 17 Nov 2015 17:14:58 +0100 +Subject: [PATCH 340/398] sw lok comments: fix meta author/data size with + custom zoom + +Change-Id: I3310813c971aa7abffccc0b7f462e05caa83482e +(cherry picked from commit 6d00110674452c66ca6192fbf46b41331b2c7066) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 693bcdf5b09a..9d12a12eae35 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -669,11 +669,12 @@ void SwSidebarWin::Rescale() + mpOutliner->SetRefMapMode( aMode ); + SetMapMode( aMode ); + mpSidebarTextControl->SetMapMode( aMode ); ++ const Fraction& rFraction = mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY(); + if ( mpMetadataAuthor ) + { + vcl::Font aFont( mpMetadataAuthor->GetSettings().GetStyleSettings().GetFieldFont() ); + sal_Int32 nHeight = aFont.GetHeight(); +- nHeight = nHeight * aMode.GetScaleY().GetNumerator() / aMode.GetScaleY().GetDenominator(); ++ nHeight = nHeight * rFraction.GetNumerator() / rFraction.GetDenominator(); + aFont.SetHeight( nHeight ); + mpMetadataAuthor->SetControlFont( aFont ); + } +@@ -681,7 +682,7 @@ void SwSidebarWin::Rescale() + { + vcl::Font aFont( mpMetadataDate->GetSettings().GetStyleSettings().GetFieldFont() ); + sal_Int32 nHeight = aFont.GetHeight(); +- nHeight = nHeight * aMode.GetScaleY().GetNumerator() / aMode.GetScaleY().GetDenominator(); ++ nHeight = nHeight * rFraction.GetNumerator() / rFraction.GetDenominator(); + aFont.SetHeight( nHeight ); + mpMetadataDate->SetControlFont( aFont ); + } +-- +2.12.0 + diff --git a/SOURCES/0341-sw-lok-comments-implement-clipboard-copy.patch b/SOURCES/0341-sw-lok-comments-implement-clipboard-copy.patch new file mode 100644 index 0000000..36b35e7 --- /dev/null +++ b/SOURCES/0341-sw-lok-comments-implement-clipboard-copy.patch @@ -0,0 +1,44 @@ +From 7bcb6ab4daf9e166cbc8677dd7aa370253203d0f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 17 Nov 2015 18:28:57 +0100 +Subject: [PATCH 341/398] sw lok comments: implement clipboard copy + +Change-Id: I0f45b1a6ab198a8403073eea05497e76f758250c +(cherry picked from commit 7b69161302bd12bf383671749e67b7d04ac4f41e) +--- + sw/source/uibase/uno/unotxdoc.cxx | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 53bb2506928b..7f94eb037861 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -134,6 +134,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -3382,6 +3384,16 @@ OString SwXTextDocument::getTextSelection(const char* pMimeType, OString& rUsedM + } + } + ++ if (SwPostItMgr* pPostItMgr = pDocShell->GetView()->GetPostItMgr()) ++ { ++ if (sw::sidebarwindows::SwSidebarWin* pWin = pPostItMgr->GetActiveSidebarWin()) ++ { ++ // Editing postit text. ++ EditView& rEditView = pWin->GetOutlinerView()->GetEditView(); ++ xTransferable = rEditView.GetEditEngine()->CreateTransferable(rEditView.GetSelection()); ++ } ++ } ++ + if (!xTransferable.is()) + xTransferable = new SwTransferable(*pWrtShell); + +-- +2.12.0 + diff --git a/SOURCES/0342-gtktiledviewer-set-author-name-when-inserting-a-comm.patch b/SOURCES/0342-gtktiledviewer-set-author-name-when-inserting-a-comm.patch new file mode 100644 index 0000000..7a3d2f5 --- /dev/null +++ b/SOURCES/0342-gtktiledviewer-set-author-name-when-inserting-a-comm.patch @@ -0,0 +1,64 @@ +From addf504efd94119f08ba227e39c04819925af608 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 17 Nov 2015 20:57:49 +0100 +Subject: [PATCH 342/398] gtktiledviewer: set author name when inserting a + comment + +Change-Id: Iee66687ce813ff801f29e4568329ed2a39f905ba +(cherry picked from commit e0080a60ac2fb0a57cbf1ecbeda250e37d8b402e) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 86fc9e539b39..7dcd52446344 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -118,6 +119,7 @@ public: + std::shared_ptr m_pRowBar; + std::shared_ptr m_pColumnBar; + std::shared_ptr m_pCornerButton; ++ std::string m_aAuthor; + + TiledWindow() + : m_pDocView(nullptr), +@@ -148,6 +150,8 @@ public: + m_pFindbarLabel(nullptr), + m_bFindAll(false) + { ++ struct passwd* pPasswd = getpwuid(getuid()); ++ m_aAuthor = std::string(pPasswd->pw_gecos); + } + }; + +@@ -799,7 +803,18 @@ static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + // notify about the finished Save + gboolean bNotify = (rString == ".uno:Save"); + +- lok_doc_view_post_command(pLOKDocView, rString.c_str(), nullptr, bNotify); ++ std::string aArguments; ++ if (rString == ".uno:InsertAnnotation" && !rWindow.m_aAuthor.empty()) ++ { ++ boost::property_tree::ptree aTree; ++ aTree.put(boost::property_tree::ptree::path_type("Author/type", '/'), "string"); ++ aTree.put(boost::property_tree::ptree::path_type("Author/value", '/'), rWindow.m_aAuthor); ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ aArguments = aStream.str(); ++ } ++ ++ lok_doc_view_post_command(pLOKDocView, rString.c_str(), (aArguments.empty() ? nullptr : aArguments.c_str()), bNotify); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0343-lok-Document-initializeForRendering-support-init.-ar.patch b/SOURCES/0343-lok-Document-initializeForRendering-support-init.-ar.patch new file mode 100644 index 0000000..678c81e --- /dev/null +++ b/SOURCES/0343-lok-Document-initializeForRendering-support-init.-ar.patch @@ -0,0 +1,224 @@ +From 7c206a9cb06d70fb95f7f7eae137865bb68f5b1b Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 18 Nov 2015 14:59:51 +0100 +Subject: [PATCH 343/398] lok::Document::initializeForRendering: support init. + arguments + +Change-Id: I8aaf19a50f25f495cb87fba7ff6a4b0f56ed7d80 +(cherry picked from commit 4bddfc00d25a42917db79ceaf0547c2e792132c4) +--- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 4 +- + desktop/source/lib/init.cxx | 76 +++++++++++++++-------------- + desktop/source/lib/lokandroid.cxx | 2 +- + include/LibreOfficeKit/LibreOfficeKit.h | 3 +- + include/LibreOfficeKit/LibreOfficeKit.hxx | 16 +++++- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 6 files changed, 60 insertions(+), 43 deletions(-) + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 1edf8d722d2f..4b08f9448f61 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -283,7 +283,7 @@ void DesktopLOKTest::testSearchCalc() + LibLibreOffice_Impl aOffice; + comphelper::LibreOfficeKit::setActive(); + LibLODocument_Impl* pDocument = loadDoc("search.ods"); +- pDocument->pClass->initializeForRendering(pDocument); ++ pDocument->pClass->initializeForRendering(pDocument, nullptr); + pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this); + + uno::Sequence aPropertyValues(comphelper::InitPropertySequence( +@@ -406,7 +406,7 @@ void DesktopLOKTest::testRowColumnHeaders() + */ + LibLODocument_Impl* pDocument = loadDoc("search.ods"); + +- pDocument->pClass->initializeForRendering(pDocument); ++ pDocument->pClass->initializeForRendering(pDocument, nullptr); + + boost::property_tree::ptree aTree; + char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders"); +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 4ee862d21cd0..2ff0a9d02853 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -260,6 +260,40 @@ static OUString getAbsoluteURL(const char* pURL) + return OUString(); + } + ++static void jsonToPropertyValues(const char* pJSON, uno::Sequence& rPropertyValues) ++{ ++ std::vector aArguments; ++ if (pJSON) ++ { ++ boost::property_tree::ptree aTree; ++ std::stringstream aStream(pJSON); ++ boost::property_tree::read_json(aStream, aTree); ++ ++ for (const std::pair& rPair : aTree) ++ { ++ const std::string& rType = rPair.second.get("type"); ++ const std::string& rValue = rPair.second.get("value"); ++ ++ beans::PropertyValue aValue; ++ aValue.Name = OUString::fromUtf8(rPair.first.c_str()); ++ if (rType == "string") ++ aValue.Value <<= OUString::fromUtf8(rValue.c_str()); ++ else if (rType == "boolean") ++ aValue.Value <<= OString(rValue.c_str()).toBoolean(); ++ else if (rType == "float") ++ aValue.Value <<= OString(rValue.c_str()).toFloat(); ++ else if (rType == "long") ++ aValue.Value <<= OString(rValue.c_str()).toInt32(); ++ else if (rType == "unsigned short") ++ aValue.Value <<= static_cast(OString(rValue.c_str()).toUInt32()); ++ else ++ SAL_WARN("desktop.lib", "jsonToPropertyValues: unhandled type '"< aPropertyValues; ++ jsonToPropertyValues(pArguments, aPropertyValues); + pDoc->initializeForTiledRendering(); + } + } +@@ -987,40 +1025,6 @@ static void doc_postKeyEvent(LibreOfficeKitDocument* pThis, int nType, int nChar + pDoc->postKeyEvent(nType, nCharCode, nKeyCode); + } + +-static void jsonToPropertyValues(const char* pJSON, uno::Sequence& rPropertyValues) +-{ +- std::vector aArguments; +- if (pJSON) +- { +- boost::property_tree::ptree aTree; +- std::stringstream aStream(pJSON); +- boost::property_tree::read_json(aStream, aTree); +- +- for (const std::pair& rPair : aTree) +- { +- const std::string& rType = rPair.second.get("type"); +- const std::string& rValue = rPair.second.get("value"); +- +- beans::PropertyValue aValue; +- aValue.Name = OUString::fromUtf8(rPair.first.c_str()); +- if (rType == "string") +- aValue.Value <<= OUString::fromUtf8(rValue.c_str()); +- else if (rType == "boolean") +- aValue.Value <<= OString(rValue.c_str()).toBoolean(); +- else if (rType == "float") +- aValue.Value <<= OString(rValue.c_str()).toFloat(); +- else if (rType == "long") +- aValue.Value <<= OString(rValue.c_str()).toInt32(); +- else if (rType == "unsigned short") +- aValue.Value <<= static_cast(OString(rValue.c_str()).toUInt32()); +- else +- SAL_WARN("desktop.lib", "jsonToPropertyValues: unhandled type '"<(pEnv, aObject); +- pDocument->pClass->initializeForRendering(pDocument); ++ pDocument->pClass->initializeForRendering(pDocument, NULL); + } + + extern "C" SAL_JNI_EXPORT jint JNICALL Java_org_libreoffice_kit_Office_saveAs +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 03210376c61e..93f7dca6d455 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -124,7 +124,8 @@ struct _LibreOfficeKitDocumentClass + long* pHeight); + + /// @see lok::Document::initializeForRendering(). +- void (*initializeForRendering) (LibreOfficeKitDocument* pThis); ++ void (*initializeForRendering) (LibreOfficeKitDocument* pThis, ++ const char* pArguments); + + /// @see lok::Document::registerCallback(). + void (*registerCallback) (LibreOfficeKitDocument* pThis, +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index c474195de213..152d0f415f17 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -156,10 +156,22 @@ public: + * needed to render the document correctly using tiled rendering. This + * method has to be called right after documentLoad() in case any of the + * tiled rendering methods are to be used later. ++ * ++ * Example argument string for text documents: ++ * ++ * { ++ * ".uno:HideWhitespace": ++ * { ++ * "type": "boolean", ++ * "value": "true" ++ * } ++ * } ++ * ++ * @param pArguments arguments of the rendering + */ +- inline void initializeForRendering() ++ inline void initializeForRendering(const char* pArguments = NULL) + { +- mpDoc->pClass->initializeForRendering(mpDoc); ++ mpDoc->pClass->initializeForRendering(mpDoc, pArguments); + } + + /** +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 47ada280dde3..802d85dea553 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -530,7 +530,7 @@ static gboolean postDocumentLoad(gpointer pData) + LOKDocViewPrivate& priv = getPrivate(pLOKDocView); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); +- priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument); ++ priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument, nullptr); + priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pLOKDocView); + priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); + g_timeout_add(600, handleTimeout, pLOKDocView); +-- +2.12.0 + diff --git a/SOURCES/0344-vcl-ITiledRenderable-initializeForTiledRendering-sup.patch b/SOURCES/0344-vcl-ITiledRenderable-initializeForTiledRendering-sup.patch new file mode 100644 index 0000000..762bc70 --- /dev/null +++ b/SOURCES/0344-vcl-ITiledRenderable-initializeForTiledRendering-sup.patch @@ -0,0 +1,163 @@ +From 1acbb9bcb348f8dd0c6fb38a435945888b703837 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 18 Nov 2015 15:20:30 +0100 +Subject: [PATCH 344/398] vcl::ITiledRenderable::initializeForTiledRendering: + support init. arguments + +(cherry picked from commit 479325dec83ea2747f3ce27ca7e817695b15e1bb) + +Change-Id: I9a6a75457078dc6383673f4c1a2012b69b5cefdd +--- + desktop/source/lib/init.cxx | 2 +- + include/vcl/ITiledRenderable.hxx | 2 +- + sc/inc/docuno.hxx | 2 +- + sc/source/ui/unoobj/docuno.cxx | 2 +- + sd/qa/unit/tiledrendering/tiledrendering.cxx | 2 +- + sd/source/ui/inc/unomodel.hxx | 2 +- + sd/source/ui/unoidl/unomodel.cxx | 2 +- + sw/inc/unotxdoc.hxx | 2 +- + sw/qa/extras/tiledrendering/tiledrendering.cxx | 3 +-- + sw/source/uibase/uno/unotxdoc.cxx | 2 +- + 10 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 2ff0a9d02853..3c6be03a7132 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -982,7 +982,7 @@ static void doc_initializeForRendering(LibreOfficeKitDocument* pThis, + doc_iniUnoCommands(); + uno::Sequence aPropertyValues; + jsonToPropertyValues(pArguments, aPropertyValues); +- pDoc->initializeForTiledRendering(); ++ pDoc->initializeForTiledRendering(aPropertyValues); + } + } + +diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx +index fa85b39399b3..786adb76f8e6 100644 +--- a/include/vcl/ITiledRenderable.hxx ++++ b/include/vcl/ITiledRenderable.hxx +@@ -93,7 +93,7 @@ public: + * Setup various document properties that are needed for the document to + * be renderable via tiled rendering. + */ +- virtual void initializeForTiledRendering() = 0; ++ virtual void initializeForTiledRendering(const css::uno::Sequence& rArguments) = 0; + + /** + * Registers a callback that will be invoked whenever the tiled renderer +diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx +index 7e00b7549733..803d7afd334d 100644 +--- a/sc/inc/docuno.hxx ++++ b/sc/inc/docuno.hxx +@@ -393,7 +393,7 @@ public: + virtual OUString getPartName(int nPart) SAL_OVERRIDE; + + /// @see vcl::ITiledRenderable::initializeForTiledRendering(). +- virtual void initializeForTiledRendering() SAL_OVERRIDE; ++ virtual void initializeForTiledRendering(const css::uno::Sequence& rArguments) override; + + /// @see vcl::ITiledRenderable::registerCallback(). + virtual void registerCallback(LibreOfficeKitCallback pCallback, void* pData) SAL_OVERRIDE; +diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx +index c0f504d770c6..b0de3197dab4 100644 +--- a/sc/source/ui/unoobj/docuno.cxx ++++ b/sc/source/ui/unoobj/docuno.cxx +@@ -932,7 +932,7 @@ Pointer ScModelObj::getPointer() + return pGridWindow->GetPointer(); + } + +-void ScModelObj::initializeForTiledRendering() ++void ScModelObj::initializeForTiledRendering(const css::uno::Sequence& /*rArguments*/) + { + SolarMutexGuard aGuard; + pDocShell->GetDocument().GetDrawLayer()->setTiledRendering(true); +diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx +index 306a76217ca0..8c9f8aa46dfa 100644 +--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx ++++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx +@@ -120,7 +120,7 @@ SdXImpressDocument* SdTiledRenderingTest::createDoc(const char* pName) + mxComponent = loadFromDesktop(getURLFromSrc(DATA_DIRECTORY) + OUString::createFromAscii(pName), "com.sun.star.presentation.PresentationDocument"); + SdXImpressDocument* pImpressDocument = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pImpressDocument); +- pImpressDocument->initializeForTiledRendering(); ++ pImpressDocument->initializeForTiledRendering(uno::Sequence()); + return pImpressDocument; + } + +diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx +index 1c444dd478bf..70478b450571 100644 +--- a/sd/source/ui/inc/unomodel.hxx ++++ b/sd/source/ui/inc/unomodel.hxx +@@ -243,7 +243,7 @@ public: + virtual void setPartMode( int nPartMode ) SAL_OVERRIDE; + + /// @see vcl::ITiledRenderable::initializeForTiledRendering(). +- virtual void initializeForTiledRendering() SAL_OVERRIDE; ++ virtual void initializeForTiledRendering(const css::uno::Sequence& rArguments) override; + /// @see vcl::ITiledRenderable::registerCallback(). + virtual void registerCallback(LibreOfficeKitCallback pCallback, void* pData) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::postKeyEvent(). +diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx +index 28ca11878044..d5e9490f6936 100644 +--- a/sd/source/ui/unoidl/unomodel.cxx ++++ b/sd/source/ui/unoidl/unomodel.cxx +@@ -2370,7 +2370,7 @@ Size SdXImpressDocument::getDocumentSize() + return Size(convertMm100ToTwip(aSize.getWidth()), convertMm100ToTwip(aSize.getHeight())); + } + +-void SdXImpressDocument::initializeForTiledRendering() ++void SdXImpressDocument::initializeForTiledRendering(const css::uno::Sequence& /*rArguments*/) + { + SolarMutexGuard aGuard; + +diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx +index e8cb116bb671..842d6299e801 100644 +--- a/sw/inc/unotxdoc.hxx ++++ b/sw/inc/unotxdoc.hxx +@@ -417,7 +417,7 @@ public: + /// @see vcl::ITiledRenderable::getPartName(). + virtual OUString getPartName(int nPart) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::initializeForTiledRendering(). +- virtual void initializeForTiledRendering() SAL_OVERRIDE; ++ virtual void initializeForTiledRendering(const css::uno::Sequence& rArguments) override; + /// @see vcl::ITiledRenderable::registerCallback(). + virtual void registerCallback(LibreOfficeKitCallback pCallback, void* pData) SAL_OVERRIDE; + /// @see vcl::ITiledRenderable::postKeyEvent(). +diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx +index 9f85fe8e1290..045f0d2676b0 100644 +--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx ++++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx +@@ -86,7 +86,7 @@ SwXTextDocument* SwTiledRenderingTest::createDoc(const char* pName) + + SwXTextDocument* pTextDocument = dynamic_cast(mxComponent.get()); + CPPUNIT_ASSERT(pTextDocument); +- pTextDocument->initializeForTiledRendering(); ++ pTextDocument->initializeForTiledRendering(uno::Sequence()); + return pTextDocument; + } + +@@ -422,7 +422,6 @@ void SwTiledRenderingTest::testDocumentSizeChanged() + SwXTextDocument* pXTextDocument = createDoc("2-pages.odt"); + pXTextDocument->registerCallback(&SwTiledRenderingTest::callback, this); + SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell(); +- pXTextDocument->initializeForTiledRendering(); + Size aSize = pXTextDocument->getDocumentSize(); + + // Delete the second page and see how the size changes. +diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx +index 7f94eb037861..e8508efd18f1 100644 +--- a/sw/source/uibase/uno/unotxdoc.cxx ++++ b/sw/source/uibase/uno/unotxdoc.cxx +@@ -3249,7 +3249,7 @@ OUString SwXTextDocument::getPartName(int nPart) + return OUString(SW_RES(STR_PAGE)) + OUString::number(nPart + 1); + } + +-void SwXTextDocument::initializeForTiledRendering() ++void SwXTextDocument::initializeForTiledRendering(const css::uno::Sequence& /*rArguments*/) + { + SolarMutexGuard aGuard; + +-- +2.12.0 + diff --git a/SOURCES/0345-gtktiledviewer-allow-passing-initializeForRendering-.patch b/SOURCES/0345-gtktiledviewer-allow-passing-initializeForRendering-.patch new file mode 100644 index 0000000..36f050e --- /dev/null +++ b/SOURCES/0345-gtktiledviewer-allow-passing-initializeForRendering-.patch @@ -0,0 +1,129 @@ +From 5192c15c3382caea037991cdbeca55c596fe042f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 18 Nov 2015 15:57:36 +0100 +Subject: [PATCH 345/398] gtktiledviewer: allow passing + initializeForRendering() arguments + +Change-Id: Ic7b52764cf2fedbf73d4dcaaf36d1055b8ee22f2 +(cherry picked from commit 0ea68eecddf0211f842645c4d257899531692770) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 2 ++ + .../qa/gtktiledviewer/gtktiledviewer.cxx | 25 ++++++++++++++++++---- + libreofficekit/source/gtk/lokdocview.cxx | 5 ++++- + 3 files changed, 27 insertions(+), 5 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 32cb66963220..c947ce3f8369 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -65,6 +65,7 @@ GtkWidget* lok_doc_view_new_from_widget (LOKDocView* + * lok_doc_view_open_document: + * @pDocView: The #LOKDocView instance + * @pPath: (transfer full): The path of the document that #LOKDocView widget should try to open ++ * @pRenderingArguments: lok::Document::initializeForRendering() arguments. + * @cancellable: + * @callback: + * @userdata: +@@ -73,6 +74,7 @@ GtkWidget* lok_doc_view_new_from_widget (LOKDocView* + */ + void lok_doc_view_open_document (LOKDocView* pDocView, + const gchar* pPath, ++ const gchar* pRenderingArguments, + GCancellable* cancellable, + GAsyncReadyCallback callback, + gpointer userdata); +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 7dcd52446344..f9034298e65c 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -29,7 +29,9 @@ + + static int help() + { +- fprintf( stderr, "Usage: gtktiledviewer \n" ); ++ fprintf(stderr, "Usage: gtktiledviewer [ ... ]\n\n"); ++ fprintf(stderr, "Options:\n\n"); ++ fprintf(stderr, "--hide-whitespace: Hide whitespace between pages in text documents.\n"); + return 1; + } + +@@ -475,13 +477,25 @@ static void createView(GtkWidget* pButton, gpointer /*pItem*/) + } + + /// Creates a new model, i.e. LOK init and document load, one view implicitly. +-static void createModelAndView(const char* pLOPath, const char* pDocPath) ++static void createModelAndView(const char* pLOPath, const char* pDocPath, const std::vector& rArguments) + { + GtkWidget* pDocView = lok_doc_view_new(pLOPath, nullptr, nullptr); + + setupWidgetAndCreateWindow(pDocView); + +- lok_doc_view_open_document(LOK_DOC_VIEW(pDocView), pDocPath, nullptr, openDocumentCallback, pDocView); ++ boost::property_tree::ptree aTree; ++ for (const std::string& rArgument : rArguments) ++ { ++ if (rArgument == "--hide-whitespace") ++ { ++ aTree.put(boost::property_tree::ptree::path_type(".uno:HideWhitespace/type", '/'), "boolean"); ++ aTree.put(boost::property_tree::ptree::path_type(".uno:HideWhitespace/value", '/'), true); ++ } ++ } ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ std::string aArguments = aStream.str(); ++ lok_doc_view_open_document(LOK_DOC_VIEW(pDocView), pDocPath, aArguments.c_str(), nullptr, openDocumentCallback, pDocView); + } + + /// Our GtkClipboardGetFunc implementation for HTML. +@@ -1262,7 +1276,10 @@ int main( int argc, char* argv[] ) + + gtk_init( &argc, &argv ); + +- createModelAndView(argv[1], argv[2]); ++ std::vector aArguments; ++ for (int i = 3; i < argc; ++i) ++ aArguments.push_back(argv[i]); ++ createModelAndView(argv[1], argv[2], aArguments); + + gtk_main(); + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 802d85dea553..464348d95f1c 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -44,6 +44,7 @@ struct LOKDocViewPrivateImpl + { + const gchar* m_aLOPath; + const gchar* m_aDocPath; ++ std::string m_aRenderingArguments; + gdouble m_nLoadProgress; + gboolean m_bIsLoading; + gboolean m_bCanZoomIn; +@@ -530,7 +531,7 @@ static gboolean postDocumentLoad(gpointer pData) + LOKDocViewPrivate& priv = getPrivate(pLOKDocView); + + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); +- priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument, nullptr); ++ priv->m_pDocument->pClass->initializeForRendering(priv->m_pDocument, priv->m_aRenderingArguments.c_str()); + priv->m_pDocument->pClass->registerCallback(priv->m_pDocument, callbackWorker, pLOKDocView); + priv->m_pDocument->pClass->getDocumentSize(priv->m_pDocument, &priv->m_nDocumentWidthTwips, &priv->m_nDocumentHeightTwips); + g_timeout_add(600, handleTimeout, pLOKDocView); +@@ -2312,6 +2313,7 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_open_document (LOKDocView* pDocView, + const gchar* pPath, ++ const gchar* pRenderingArguments, + GCancellable* cancellable, + GAsyncReadyCallback callback, + gpointer userdata) +@@ -2324,6 +2326,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + pLOEvent->m_pPath = pPath; + + priv->m_aDocPath = pPath; ++ priv->m_aRenderingArguments = pRenderingArguments; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +-- +2.12.0 + diff --git a/SOURCES/0346-sw-lok-comments-don-t-paint-hidden-comment-sub-widge.patch b/SOURCES/0346-sw-lok-comments-don-t-paint-hidden-comment-sub-widge.patch new file mode 100644 index 0000000..5284131 --- /dev/null +++ b/SOURCES/0346-sw-lok-comments-don-t-paint-hidden-comment-sub-widge.patch @@ -0,0 +1,38 @@ +From 8891a0194cf213d05dd5bc96d24c20f5b224ca4f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 19 Nov 2015 14:57:38 +0100 +Subject: [PATCH 346/398] sw lok comments: don't paint hidden comment + sub-widgets + +Change-Id: Ia513821b43729951c7b097fea498f0e22b9d10ea +(cherry picked from commit 8a1b9ac592c026de6c764277a6ad1f8db9a4a679) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 9d12a12eae35..5f6cfa7c4ae0 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -276,15 +276,13 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + { + vcl::Window* pChild = GetChild(i); + +- // This would at the moment just draw a gray rectangle at the top right +- // corner, need to sort out later. +- if (pChild == mpVScrollbar.get()) +- continue; +- + // No point in showing this button till click on it are not handled. + if (pChild == mpMenuButton.get()) + continue; + ++ if (!pChild->IsVisible()) ++ continue; ++ + rRenderContext.Push(PushFlags::MAPMODE); + const Fraction& rFraction(mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY()); + Point aOffset(PixelToLogic(pChild->GetPosPixel() * rFraction.GetDenominator() / rFraction.GetNumerator())); +-- +2.12.0 + diff --git a/SOURCES/0347-editeng-lok-invalidate-on-scroll.patch b/SOURCES/0347-editeng-lok-invalidate-on-scroll.patch new file mode 100644 index 0000000..2b899f7 --- /dev/null +++ b/SOURCES/0347-editeng-lok-invalidate-on-scroll.patch @@ -0,0 +1,51 @@ +From c5aac6c349e0d227f5594005948012088045bf3f Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 19 Nov 2015 15:09:05 +0100 +Subject: [PATCH 347/398] editeng lok: invalidate on scroll + +E.g. when a Witer comment has long enough contents to get scrolled, the +desktop case repaints its contents by vcl::Window::Scroll(), followed by +a vcl::Window::Update(), i.e. vcl::Window::Invalidate() is not called. + +The result of this in case of tiled rendering is that no tile is +repainted, so call vcl::Window::Invalidate() after scrolling manually. + +A generic VCL-level invalidate-after-scroll is not wanted, as the +scrolling of the document contents and the main document window is not +in sync when tiled rendering. + +(cherry picked from commit 162ae47a046b0c501e09d611a9834e875db884b8) + +Change-Id: I74296a0f0e52c92cf3db6aefa73f28bb2b202871 +--- + editeng/source/editeng/impedit.cxx | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx +index 0207155e4d75..54ce4b06188f 100644 +--- a/editeng/source/editeng/impedit.cxx ++++ b/editeng/source/editeng/impedit.cxx +@@ -47,6 +47,8 @@ + #include + #include + #include ++#include ++#include + + using namespace ::com::sun::star; + using namespace ::com::sun::star::uno; +@@ -1085,6 +1087,11 @@ Pair ImpEditView::Scroll( long ndX, long ndY, sal_uInt8 nRangeCheck ) + aVisDocStartPos = pOutWin->PixelToLogic( aVisDocStartPos ); + Rectangle aRect( aOutArea ); + pOutWin->Scroll( nRealDiffX, nRealDiffY, aRect, SCROLL_CLIP ); ++ ++ if (comphelper::LibreOfficeKit::isActive()) ++ // Need to invalidate the window, otherwise no tile will be re-painted. ++ pOutWin->Invalidate(); ++ + pOutWin->Update(); + pCrsr->SetPos( pCrsr->GetPos() + Point( nRealDiffX, nRealDiffY ) ); + if ( bVisCursor ) +-- +2.12.0 + diff --git a/SOURCES/0348-sw-lok-comments-optimize-sidebar-text-control-invali.patch b/SOURCES/0348-sw-lok-comments-optimize-sidebar-text-control-invali.patch new file mode 100644 index 0000000..54eb456 --- /dev/null +++ b/SOURCES/0348-sw-lok-comments-optimize-sidebar-text-control-invali.patch @@ -0,0 +1,70 @@ +From eea254dd5eb834b846ff9c55662d5704c266f438 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 19 Nov 2015 16:11:43 +0100 +Subject: [PATCH 348/398] sw lok comments: optimize sidebar text control + invalidation + +Instead of invalidating the whole area, invalidate the sub-widget when +the whole area of the sub-widget would be invalidated. + +With this, a test comment with enough comment to have a scrollbar +results in 3 paintTile() calls instead of 11 ones (70% save). + +(cherry picked from commit 9ece5c870a0ce39690109777bb8f76c1463a10c2) + +Change-Id: I2fe317549eefac9a63aaf50f5a9a242e15c4dc86 +--- + sw/source/uibase/docvw/SidebarTxtControl.cxx | 34 ++++++++++++++++------------ + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarTxtControl.cxx b/sw/source/uibase/docvw/SidebarTxtControl.cxx +index d6887a475312..4558c4071bfd 100644 +--- a/sw/source/uibase/docvw/SidebarTxtControl.cxx ++++ b/sw/source/uibase/docvw/SidebarTxtControl.cxx +@@ -190,24 +190,28 @@ void SidebarTextControl::Paint(vcl::RenderContext& rRenderContext, const Rectang + + void SidebarTextControl::LogicInvalidate(const Rectangle* pRectangle) + { +- OString sRectangle; ++ Rectangle aRectangle; ++ + if (!pRectangle) +- sRectangle = "EMPTY"; +- else + { +- // Convert from relative twips to absolute ones. +- Rectangle aRectangle(*pRectangle); +- vcl::Window& rParent = *mrSidebarWin.EditWin(); +- Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel()); +- rParent.Push(PushFlags::MAPMODE); +- rParent.EnableMapMode(); +- aOffset = rParent.PixelToLogic(aOffset); +- rParent.Pop(); +- aRectangle.Move(aOffset.getX(), aOffset.getY()); +- +- sRectangle = aRectangle.toString(); ++ Push(PushFlags::MAPMODE); ++ EnableMapMode(); ++ aRectangle = Rectangle(Point(0, 0), PixelToLogic(GetSizePixel())); ++ Pop(); + } +- ++ else ++ aRectangle = *pRectangle; ++ ++ // Convert from relative twips to absolute ones. ++ vcl::Window& rParent = *mrSidebarWin.EditWin(); ++ Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel()); ++ rParent.Push(PushFlags::MAPMODE); ++ rParent.EnableMapMode(); ++ aOffset = rParent.PixelToLogic(aOffset); ++ rParent.Pop(); ++ aRectangle.Move(aOffset.getX(), aOffset.getY()); ++ ++ OString sRectangle = aRectangle.toString(); + SwWrtShell& rWrtShell = mrDocView.GetWrtShell(); + rWrtShell.libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); + } +-- +2.12.0 + diff --git a/SOURCES/0349-gtktiledviewer-allow-setting-custom-background-color.patch b/SOURCES/0349-gtktiledviewer-allow-setting-custom-background-color.patch new file mode 100644 index 0000000..923979d --- /dev/null +++ b/SOURCES/0349-gtktiledviewer-allow-setting-custom-background-color.patch @@ -0,0 +1,51 @@ +From 57101e7a5600ceffc78c92414bba545cf6c1c513 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Thu, 19 Nov 2015 17:29:31 +0100 +Subject: [PATCH 349/398] gtktiledviewer: allow setting custom background color + +E.g. it helps testing the semi-transparent shadow around Writer pages to +append "--background-color yellow" to the commandline arguments. + +Change-Id: Ib94750e936abe3f41e4982534431fd5115e2c543 +(cherry picked from commit 9dea0a9775c1ab8c6ce8bbf00df83757cba34fb0) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index f9034298e65c..aeccab11b3b2 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -32,6 +32,7 @@ static int help() + fprintf(stderr, "Usage: gtktiledviewer [ ... ]\n\n"); + fprintf(stderr, "Options:\n\n"); + fprintf(stderr, "--hide-whitespace: Hide whitespace between pages in text documents.\n"); ++ fprintf(stderr, "--background-color : Set custom background color, e.g. 'yellow'.\n"); + return 1; + } + +@@ -484,13 +485,20 @@ static void createModelAndView(const char* pLOPath, const char* pDocPath, const + setupWidgetAndCreateWindow(pDocView); + + boost::property_tree::ptree aTree; +- for (const std::string& rArgument : rArguments) ++ for (size_t i = 0; i < rArguments.size(); ++i) + { ++ const std::string& rArgument = rArguments[i]; + if (rArgument == "--hide-whitespace") + { + aTree.put(boost::property_tree::ptree::path_type(".uno:HideWhitespace/type", '/'), "boolean"); + aTree.put(boost::property_tree::ptree::path_type(".uno:HideWhitespace/value", '/'), true); + } ++ else if (rArgument == "--background-color" && i + 1 < rArguments.size()) ++ { ++ GdkRGBA color; ++ gdk_rgba_parse(&color, rArguments[i + 1].c_str()); ++ gtk_widget_override_background_color(gtk_widget_get_toplevel(pDocView), GTK_STATE_FLAG_NORMAL, &color); ++ } + } + std::stringstream aStream; + boost::property_tree::write_json(aStream, aTree); +-- +2.12.0 + diff --git a/SOURCES/0350-Werror-Wdeprecated-declarations.patch b/SOURCES/0350-Werror-Wdeprecated-declarations.patch new file mode 100644 index 0000000..f3cc8d4 --- /dev/null +++ b/SOURCES/0350-Werror-Wdeprecated-declarations.patch @@ -0,0 +1,37 @@ +From 01d4962ea8624a5f2a020a26020f725cd652b923 Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Fri, 20 Nov 2015 08:55:58 +0100 +Subject: [PATCH 350/398] -Werror,-Wdeprecated-declarations + +Change-Id: I7c7d3dda02a3745128a5a125b4b6952e087cdcda +(cherry picked from commit 9a29e2f539fe3ca21229d6073455a736c64cc4e8) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index aeccab11b3b2..e44a92a3f3de 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -19,6 +19,8 @@ + #include + #include + ++#include ++ + #define LOK_USE_UNSTABLE_API + #include + #include +@@ -497,7 +499,9 @@ static void createModelAndView(const char* pLOPath, const char* pDocPath, const + { + GdkRGBA color; + gdk_rgba_parse(&color, rArguments[i + 1].c_str()); ++ SAL_WNODEPRECATED_DECLARATIONS_PUSH + gtk_widget_override_background_color(gtk_widget_get_toplevel(pDocView), GTK_STATE_FLAG_NORMAL, &color); ++ SAL_WNODEPRECATED_DECLARATIONS_POP + } + } + std::stringstream aStream; +-- +2.12.0 + diff --git a/SOURCES/0351-sw-lok-comments-implement-painting-of-the-vertical-s.patch b/SOURCES/0351-sw-lok-comments-implement-painting-of-the-vertical-s.patch new file mode 100644 index 0000000..0368193 --- /dev/null +++ b/SOURCES/0351-sw-lok-comments-implement-painting-of-the-vertical-s.patch @@ -0,0 +1,50 @@ +From 10e3ea1d50a225b92a56c83ccf881807fbc7b0eb Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Fri, 20 Nov 2015 10:24:29 +0100 +Subject: [PATCH 351/398] sw lok comments: implement painting of the vertical + scrollbar + +This one is special, as normally its map mode is in pixels, but we need +all sub-widgets to work in twips when tiled rendering. + +With this, the scrollbar widget (both the buttons and the +button/background area of the scrollbar itself) is painted at the +correct location when Writer comments have enough content so the +scrollbar is visible. + +Change-Id: I4ee9ef8618974b965339078d2262364ec19732ef +(cherry picked from commit f411ef1b8065d3ae03d1a820812e64b250de0932) +--- + sw/source/uibase/docvw/SidebarWin.cxx | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 5f6cfa7c4ae0..6acbc1da7077 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -290,8 +290,22 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset); + rRenderContext.SetMapMode(aMapMode); + ++ bool bPopChild = false; ++ if (pChild->GetMapMode().GetMapUnit() != rRenderContext.GetMapMode().GetMapUnit()) ++ { ++ // This is needed for the scrollbar that has its map unit in pixels. ++ pChild->Push(PushFlags::MAPMODE); ++ bPopChild = true; ++ pChild->EnableMapMode(); ++ aMapMode = pChild->GetMapMode(); ++ aMapMode.SetMapUnit(rRenderContext.GetMapMode().GetMapUnit()); ++ pChild->SetMapMode(aMapMode); ++ } ++ + pChild->Paint(rRenderContext, rRect); + ++ if (bPopChild) ++ pChild->Pop(); + rRenderContext.Pop(); + } + +-- +2.12.0 + diff --git a/SOURCES/0352-LOK-add-Document-getTileMode.patch b/SOURCES/0352-LOK-add-Document-getTileMode.patch new file mode 100644 index 0000000..5706434 --- /dev/null +++ b/SOURCES/0352-LOK-add-Document-getTileMode.patch @@ -0,0 +1,105 @@ +From 12553d62d3738a51b1021c9a5d37a70cb2bc1e45 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 23 Nov 2015 09:32:37 +0100 +Subject: [PATCH 352/398] LOK: add Document::getTileMode() + +So that clients can know if they get old-style RGBA or new-style ARGB +output in paintTile(). + +Change-Id: Icfde4b3259444b3524e64478ccd976664a3fe0ed +(cherry picked from commit fc06f801ee79fd49d54c27121ae9b2904d99f09c) +--- + desktop/source/lib/init.cxx | 7 +++++++ + include/LibreOfficeKit/LibreOfficeKit.h | 3 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 10 ++++++++++ + include/LibreOfficeKit/LibreOfficeKitEnums.h | 7 +++++++ + 4 files changed, 27 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 3c6be03a7132..00c1f63ddf4c 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -311,6 +311,7 @@ void doc_paintTile(LibreOfficeKitDocument* pThis, + const int nCanvasWidth, const int nCanvasHeight, + const int nTilePosX, const int nTilePosY, + const int nTileWidth, const int nTileHeight); ++static int doc_getTileMode(LibreOfficeKitDocument* pThis); + static void doc_getDocumentSize(LibreOfficeKitDocument* pThis, + long* pWidth, + long* pHeight); +@@ -384,6 +385,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference getPartName = doc_getPartName; + m_pDocumentClass->setPartMode = doc_setPartMode; + m_pDocumentClass->paintTile = doc_paintTile; ++ m_pDocumentClass->getTileMode = doc_getTileMode; + m_pDocumentClass->getDocumentSize = doc_getDocumentSize; + m_pDocumentClass->initializeForRendering = doc_initializeForRendering; + m_pDocumentClass->registerCallback = doc_registerCallback; +@@ -956,6 +958,11 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + #endif + } + ++static int doc_getTileMode(LibreOfficeKitDocument* /*pThis*/) ++{ ++ return LOK_TILEMODE_RGBA; ++} ++ + static void doc_getDocumentSize(LibreOfficeKitDocument* pThis, + long* pWidth, + long* pHeight) +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 93f7dca6d455..5189cca5eb5e 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -118,6 +118,9 @@ struct _LibreOfficeKitDocumentClass + const int nTileWidth, + const int nTileHeight); + ++ /// @see lok::Document::getTileMode(). ++ int (*getTileMode) (LibreOfficeKitDocument* pThis); ++ + /// @see lok::Document::getDocumentSize(). + void (*getDocumentSize) (LibreOfficeKitDocument* pThis, + long* pWidth, +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index 152d0f415f17..e592bbe549ab 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -143,6 +143,16 @@ public: + nTilePosX, nTilePosY, nTileWidth, nTileHeight); + } + ++ /** ++ * Gets the tile mode: the pixel format used for the pBuffer of paintTile(). ++ * ++ * @return an element of the LibreOfficeKitTileMode enum. ++ */ ++ inline int getTileMode() ++ { ++ return mpDoc->pClass->getTileMode(mpDoc); ++ } ++ + /// Get the document sizes in TWIPs. + inline void getDocumentSize(long* pWidth, long* pHeight) + { +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index 7b23fcbab1c3..b713f0ed49b7 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -35,6 +35,13 @@ LibreOfficeKitPartMode; + + typedef enum + { ++ LOK_TILEMODE_RGBA, ++ LOK_TILEMODE_ARGB ++} ++LibreOfficeKitTileMode; ++ ++typedef enum ++{ + /** + * Any tiles which are over the rectangle described in the payload are no + * longer valid. +-- +2.12.0 + diff --git a/SOURCES/0353-sw-lok-comments-fix-vertical-scrollbar-with-custom-z.patch b/SOURCES/0353-sw-lok-comments-fix-vertical-scrollbar-with-custom-z.patch new file mode 100644 index 0000000..1999bb2 --- /dev/null +++ b/SOURCES/0353-sw-lok-comments-fix-vertical-scrollbar-with-custom-z.patch @@ -0,0 +1,63 @@ +From 0fb40ac6ec515ccc3b1db575232aa4e01c46e815 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 23 Nov 2015 13:46:59 +0100 +Subject: [PATCH 353/398] sw lok comments: fix vertical scrollbar with custom + zoom + +With this, if a comment has enough content that it gets a vertical +scrollbar, then tiled rendering output looks OK, even with non-100% +zoom. + +Change-Id: I699aadc11b6c34fb0791e70705719fd61169d972 +(cherry picked from commit 30b511ae38e2870174db91d12f65a9c3320fc172) +--- + sw/source/core/view/viewsh.cxx | 9 +++++++++ + sw/source/uibase/docvw/SidebarWin.cxx | 5 +++-- + 2 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx +index 963577fb1bd8..093d5208fdda 100644 +--- a/sw/source/core/view/viewsh.cxx ++++ b/sw/source/core/view/viewsh.cxx +@@ -1879,6 +1879,15 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex + aMapMode.SetScaleY(scaleY); + rDevice.SetMapMode(aMapMode); + ++ // Update scaling of SwEditWin and its sub-widgets, needed for comments. ++ if (GetWin() && GetWin()->GetMapMode().GetScaleX() != scaleX) ++ { ++ double fScale = scaleX; ++ SwViewOption aOption(*GetViewOptions()); ++ aOption.SetZoom(fScale * 100); ++ ApplyViewOptions(aOption); ++ } ++ + Rectangle aOutRect = Rectangle(Point(tilePosX, tilePosY), + rDevice.PixelToLogic(Size(contextWidth, contextHeight))); + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 6acbc1da7077..47c65c86b06b 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -284,8 +284,7 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + continue; + + rRenderContext.Push(PushFlags::MAPMODE); +- const Fraction& rFraction(mrView.GetWrtShellPtr()->GetOut()->GetMapMode().GetScaleY()); +- Point aOffset(PixelToLogic(pChild->GetPosPixel() * rFraction.GetDenominator() / rFraction.GetNumerator())); ++ Point aOffset(PixelToLogic(pChild->GetPosPixel())); + MapMode aMapMode(rRenderContext.GetMapMode()); + aMapMode.SetOrigin(aMapMode.GetOrigin() + aOffset); + rRenderContext.SetMapMode(aMapMode); +@@ -299,6 +298,8 @@ void SwSidebarWin::PaintTile(vcl::RenderContext& rRenderContext, const Rectangle + pChild->EnableMapMode(); + aMapMode = pChild->GetMapMode(); + aMapMode.SetMapUnit(rRenderContext.GetMapMode().GetMapUnit()); ++ aMapMode.SetScaleX(rRenderContext.GetMapMode().GetScaleX()); ++ aMapMode.SetScaleY(rRenderContext.GetMapMode().GetScaleY()); + pChild->SetMapMode(aMapMode); + } + +-- +2.12.0 + diff --git a/SOURCES/0354-updae-getTileMode.patch b/SOURCES/0354-updae-getTileMode.patch new file mode 100644 index 0000000..d18a66d --- /dev/null +++ b/SOURCES/0354-updae-getTileMode.patch @@ -0,0 +1,41 @@ +From b233cb8b04d35d8f9c9aa8c49940b229acdde0a7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 23 Nov 2015 11:04:26 +0000 +Subject: [PATCH 354/398] updae getTileMode + +Change-Id: Ic8d67f08d40f475020c0534570fe3bea07aa431b +(cherry picked from commit d058765ff3c4f3aaa84c3f9bec774aed8a8b32a3) +--- + desktop/source/lib/init.cxx | 2 +- + include/LibreOfficeKit/LibreOfficeKitEnums.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 00c1f63ddf4c..4630ed0095b4 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -960,7 +960,7 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + + static int doc_getTileMode(LibreOfficeKitDocument* /*pThis*/) + { +- return LOK_TILEMODE_RGBA; ++ return LOK_TILEMODE_BGRA; + } + + static void doc_getDocumentSize(LibreOfficeKitDocument* pThis, +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index b713f0ed49b7..a0f5e886dcac 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -36,7 +36,7 @@ LibreOfficeKitPartMode; + typedef enum + { + LOK_TILEMODE_RGBA, +- LOK_TILEMODE_ARGB ++ LOK_TILEMODE_BGRA + } + LibreOfficeKitTileMode; + +-- +2.12.0 + diff --git a/SOURCES/0355-vcl-lok-fix-scrollbar-to-accept-mouse-events-in-twip.patch b/SOURCES/0355-vcl-lok-fix-scrollbar-to-accept-mouse-events-in-twip.patch new file mode 100644 index 0000000..ed843ca --- /dev/null +++ b/SOURCES/0355-vcl-lok-fix-scrollbar-to-accept-mouse-events-in-twip.patch @@ -0,0 +1,41 @@ +From 65410a3cf918fc17bf92c1ad48574e17e79a62bc Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 23 Nov 2015 16:07:49 +0100 +Subject: [PATCH 355/398] vcl lok: fix scrollbar to accept mouse events in + twips + +(cherry picked from commit 439765480695975e10c92f39aa6a4cb6f2ee7646) + +Change-Id: Ieaedaa525d613f8ba55f336c613da163a09f7a33 +--- + vcl/source/control/scrbar.cxx | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/vcl/source/control/scrbar.cxx b/vcl/source/control/scrbar.cxx +index a60595c2ee0d..e8004d13d177 100644 +--- a/vcl/source/control/scrbar.cxx ++++ b/vcl/source/control/scrbar.cxx +@@ -897,7 +897,19 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt ) + + if (rMEvt.IsLeft() || rMEvt.IsMiddle() || rMEvt.IsRight()) + { +- const Point& rMousePos = rMEvt.GetPosPixel(); ++ Point aPosPixel; ++ if (!IsMapModeEnabled() && GetMapMode().GetMapUnit() == MAP_TWIP) ++ { ++ // rMEvt coordinates are in twips. ++ Push(PushFlags::MAPMODE); ++ EnableMapMode(); ++ MapMode aMapMode = GetMapMode(); ++ aMapMode.SetOrigin(Point(0, 0)); ++ SetMapMode(aMapMode); ++ aPosPixel = LogicToPixel(rMEvt.GetPosPixel()); ++ Pop(); ++ } ++ const Point& rMousePos = (GetMapMode().GetMapUnit() != MAP_TWIP ? rMEvt.GetPosPixel() : aPosPixel); + sal_uInt16 nTrackFlags = 0; + bool bHorizontal = ( GetStyle() & WB_HORZ ) != 0; + bool bIsInside = false; +-- +2.12.0 + diff --git a/SOURCES/0356-sw-lok-comments-handle-mouse-up-down-events-on-the-v.patch b/SOURCES/0356-sw-lok-comments-handle-mouse-up-down-events-on-the-v.patch new file mode 100644 index 0000000..131a3a4 --- /dev/null +++ b/SOURCES/0356-sw-lok-comments-handle-mouse-up-down-events-on-the-v.patch @@ -0,0 +1,112 @@ +From 107c94bbccb8c2607d02bc37096a332c90ba9e83 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 23 Nov 2015 16:21:43 +0100 +Subject: [PATCH 356/398] sw lok comments: handle mouse up/down events on the + vertical scrollbar + +(cherry picked from commit 527190f0c0284a9a4f5a021d0a9163ef9a63a67f) + +Change-Id: Ib1c334825a6629224fe0c8fba564656d53e67410 +--- + sw/source/uibase/docvw/SidebarWin.cxx | 55 ++++++++++++++++++++++++++++------- + 1 file changed, 45 insertions(+), 10 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 47c65c86b06b..c95a8909de54 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -93,9 +93,19 @@ void lcl_translateTwips(vcl::Window& rParent, vcl::Window& rChild, MouseEvent* p + { + // Set map mode, so that callback payloads will contain absolute coordinates instead of relative ones. + Point aOffset(rChild.GetOutOffXPixel() - rParent.GetOutOffXPixel(), rChild.GetOutOffYPixel() - rParent.GetOutOffYPixel()); ++ if (!rChild.IsMapModeEnabled()) ++ { ++ MapMode aMapMode(rChild.GetMapMode()); ++ aMapMode.SetMapUnit(MAP_TWIP); ++ aMapMode.SetScaleX(rParent.GetMapMode().GetScaleX()); ++ aMapMode.SetScaleY(rParent.GetMapMode().GetScaleY()); ++ rChild.SetMapMode(aMapMode); ++ rChild.EnableMapMode(); ++ } + aOffset = rChild.PixelToLogic(aOffset); + MapMode aMapMode(rChild.GetMapMode()); + aMapMode.SetOrigin(aOffset); ++ aMapMode.SetMapUnit(rParent.GetMapMode().GetMapUnit()); + rChild.SetMapMode(aMapMode); + rChild.EnableMapMode(false); + +@@ -109,6 +119,31 @@ void lcl_translateTwips(vcl::Window& rParent, vcl::Window& rChild, MouseEvent* p + } + } + ++/// Decide which one from the children of rParent should get rMouseEvent. ++vcl::Window* lcl_getHitWindow(sw::sidebarwindows::SwSidebarWin& rParent, const MouseEvent& rMouseEvent) ++{ ++ vcl::Window* pRet = 0; ++ ++ rParent.EditWin()->Push(PushFlags::MAPMODE); ++ rParent.EditWin()->EnableMapMode(); ++ for (sal_Int16 i = rParent.GetChildCount() - 1; i >= 0; --i) ++ { ++ vcl::Window* pChild = rParent.GetChild(i); ++ ++ Point aPosition(rParent.GetPosPixel()); ++ aPosition.Move(pChild->GetPosPixel().getX(), pChild->GetPosPixel().getY()); ++ Size aSize(rParent.GetSizePixel()); ++ Rectangle aRectangleLogic(rParent.EditWin()->PixelToLogic(aPosition), rParent.EditWin()->PixelToLogic(aSize)); ++ if (aRectangleLogic.IsInside(rMouseEvent.GetPosPixel())) ++ { ++ pRet = pChild; ++ break; ++ } ++ } ++ rParent.EditWin()->Pop(); ++ return pRet; ++} ++ + } + + namespace sw { namespace sidebarwindows { +@@ -442,29 +477,29 @@ void SwSidebarWin::MouseMove(const MouseEvent& rMouseEvent) + + void SwSidebarWin::MouseButtonDown(const MouseEvent& rMouseEvent) + { +- if (mpSidebarTextControl) ++ if (vcl::Window* pHit = lcl_getHitWindow(*this, rMouseEvent)) + { +- mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ pHit->Push(PushFlags::MAPMODE); + MouseEvent aMouseEvent(rMouseEvent); +- lcl_translateTwips(*EditWin(), *mpSidebarTextControl, &aMouseEvent); ++ lcl_translateTwips(*EditWin(), *pHit, &aMouseEvent); + +- mpSidebarTextControl->MouseButtonDown(aMouseEvent); ++ pHit->MouseButtonDown(aMouseEvent); + +- mpSidebarTextControl->Pop(); ++ pHit->Pop(); + } + } + + void SwSidebarWin::MouseButtonUp(const MouseEvent& rMouseEvent) + { +- if (mpSidebarTextControl) ++ if (vcl::Window* pHit = lcl_getHitWindow(*this, rMouseEvent)) + { +- mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ pHit->Push(PushFlags::MAPMODE); + MouseEvent aMouseEvent(rMouseEvent); +- lcl_translateTwips(*EditWin(), *mpSidebarTextControl, &aMouseEvent); ++ lcl_translateTwips(*EditWin(), *pHit, &aMouseEvent); + +- mpSidebarTextControl->MouseButtonUp(aMouseEvent); ++ pHit->MouseButtonUp(aMouseEvent); + +- mpSidebarTextControl->Pop(); ++ pHit->Pop(); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0357-desktop-fix-LOK_DEBUG-rectangle-painting.patch b/SOURCES/0357-desktop-fix-LOK_DEBUG-rectangle-painting.patch new file mode 100644 index 0000000..eaef140 --- /dev/null +++ b/SOURCES/0357-desktop-fix-LOK_DEBUG-rectangle-painting.patch @@ -0,0 +1,57 @@ +From 7e9002c2a206f0c041e6437fbcfe478bab0664d6 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 24 Nov 2015 11:54:24 +0100 +Subject: [PATCH 357/398] desktop: fix LOK_DEBUG rectangle painting + +(cherry picked from commit fa377a06627bba0c995aae55b346bb9530ecdf7e) + +Change-Id: If023e409fad6fed8c0345a66ea48c1ed9924bff0 +--- + desktop/source/lib/init.cxx | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 4630ed0095b4..57bb177f49db 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -922,18 +922,6 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + pDoc->paintTile(*pDevice.get(), nCanvasWidth, nCanvasHeight, + nTilePosX, nTilePosY, nTileWidth, nTileHeight); + +- // Overwrite pBuffer's alpha channel with the separate alpha buffer. +- for (int nRow = 0; nRow < nCanvasHeight; ++nRow) +- { +- for (int nCol = 0; nCol < nCanvasWidth; ++nCol) +- { +- const int nOffset = (nCanvasWidth * nRow) + nCol; +- // VCL's transparent is 0, RGBA's transparent is 0xff. +- pBuffer[nOffset * 4 +3] = 0xff - aAlpha[nOffset]; +- } +- } +-#endif +- + static bool bDebug = getenv("LOK_DEBUG") != 0; + if (bDebug) + { +@@ -947,6 +935,18 @@ void doc_paintTile (LibreOfficeKitDocument* pThis, + pDevice->Pop(); + } + ++ // Overwrite pBuffer's alpha channel with the separate alpha buffer. ++ for (int nRow = 0; nRow < nCanvasHeight; ++nRow) ++ { ++ for (int nCol = 0; nCol < nCanvasWidth; ++nCol) ++ { ++ const int nOffset = (nCanvasWidth * nRow) + nCol; ++ // VCL's transparent is 0, RGBA's transparent is 0xff. ++ pBuffer[nOffset * 4 +3] = 0xff - aAlpha[nOffset]; ++ } ++ } ++#endif ++ + #else + (void) pBuffer; + (void) nCanvasWidth; +-- +2.12.0 + diff --git a/SOURCES/0358-sw-lok-comments-fix-missing-invalidations-from-the-s.patch b/SOURCES/0358-sw-lok-comments-fix-missing-invalidations-from-the-s.patch new file mode 100644 index 0000000..2a9eedc --- /dev/null +++ b/SOURCES/0358-sw-lok-comments-fix-missing-invalidations-from-the-s.patch @@ -0,0 +1,187 @@ +From 2c28091ad868b3d4f3512600a46b51f4ab57fc03 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 24 Nov 2015 11:58:09 +0100 +Subject: [PATCH 358/398] sw lok comments: fix missing invalidations from the + scrollbar + +If a comment had a scrollbar, and the user clicked on the down arrow of +it, then the button remained in the "pushed" state, as the scrollbar +invalidations were not routed to the LOK client. + +With this, the button gets back to its non-pushed state after the mouse +button is released. + +Change-Id: Ie4ba5d0ec07229b0cfc08532e8e91ae25f7a4c9e +(cherry picked from commit 55040ea13426e337418143dcfe226dd2a395f041) +--- + sw/Library_sw.mk | 1 + + sw/source/uibase/docvw/SidebarScrollBar.cxx | 72 +++++++++++++++++++++++++++++ + sw/source/uibase/docvw/SidebarScrollBar.hxx | 43 +++++++++++++++++ + sw/source/uibase/docvw/SidebarWin.cxx | 3 +- + 4 files changed, 118 insertions(+), 1 deletion(-) + create mode 100644 sw/source/uibase/docvw/SidebarScrollBar.cxx + create mode 100644 sw/source/uibase/docvw/SidebarScrollBar.hxx + +diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk +index ea8368719f7b..1297a85b874d 100644 +--- a/sw/Library_sw.mk ++++ b/sw/Library_sw.mk +@@ -600,6 +600,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ + sw/source/uibase/docvw/OverlayRanges \ + sw/source/uibase/docvw/PostItMgr \ + sw/source/uibase/docvw/ShadowOverlayObject \ ++ sw/source/uibase/docvw/SidebarScrollBar \ + sw/source/uibase/docvw/SidebarTxtControl \ + sw/source/uibase/docvw/SidebarTxtControlAcc \ + sw/source/uibase/docvw/SidebarWin \ +diff --git a/sw/source/uibase/docvw/SidebarScrollBar.cxx b/sw/source/uibase/docvw/SidebarScrollBar.cxx +new file mode 100644 +index 000000000000..909aa763dba1 +--- /dev/null ++++ b/sw/source/uibase/docvw/SidebarScrollBar.cxx +@@ -0,0 +1,72 @@ ++/* -*- 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 ++ ++#define LOK_USE_UNSTABLE_API ++#include ++ ++#include ++#include ++#include ++#include ++ ++namespace sw ++{ ++namespace sidebarwindows ++{ ++ ++SidebarScrollBar::SidebarScrollBar(SwSidebarWin& rSidebarWin, WinBits nStyle, SwView& rView) ++ : ScrollBar(&rSidebarWin, nStyle), ++ m_rSidebarWin(rSidebarWin), ++ m_rView(rView) ++{ ++} ++ ++void SidebarScrollBar::LogicInvalidate(const Rectangle* pRectangle) ++{ ++ Rectangle aRectangle; ++ ++ if (!pRectangle) ++ { ++ Push(PushFlags::MAPMODE); ++ EnableMapMode(); ++ MapMode aMapMode = GetMapMode(); ++ aMapMode.SetMapUnit(MAP_TWIP); ++ SetMapMode(aMapMode); ++ aRectangle = Rectangle(Point(0, 0), PixelToLogic(GetSizePixel())); ++ Pop(); ++ } ++ else ++ aRectangle = *pRectangle; ++ ++ // Convert from relative twips to absolute ones. ++ vcl::Window& rParent = m_rSidebarWin.EditWin(); ++ Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel()); ++ rParent.Push(PushFlags::MAPMODE); ++ rParent.EnableMapMode(); ++ aOffset = rParent.PixelToLogic(aOffset); ++ rParent.Pop(); ++ aRectangle.Move(aOffset.getX(), aOffset.getY()); ++ ++ OString sRectangle = aRectangle.toString(); ++ SwWrtShell& rWrtShell = m_rView.GetWrtShell(); ++ rWrtShell.libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); ++} ++ ++ ++SidebarScrollBar::~SidebarScrollBar() ++{ ++ disposeOnce(); ++} ++ ++} ++} // end of namespace sw::sidebarwindows ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/sw/source/uibase/docvw/SidebarScrollBar.hxx b/sw/source/uibase/docvw/SidebarScrollBar.hxx +new file mode 100644 +index 000000000000..9543205387df +--- /dev/null ++++ b/sw/source/uibase/docvw/SidebarScrollBar.hxx +@@ -0,0 +1,43 @@ ++/* -*- 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/. ++ */ ++ ++#ifndef INCLUDED_SW_SOURCE_UIBASE_DOCVW_SIDEBARSCROLLBAR_HXX ++#define INCLUDED_SW_SOURCE_UIBASE_DOCVW_SIDEBARSCROLLBAR_HXX ++ ++#include ++ ++class SwView; ++ ++namespace sw ++{ ++namespace sidebarwindows ++{ ++ ++class SwSidebarWin; ++ ++/// Similar to the VCL scrollbar, but instrumented with Writer-specific details for LOK. ++class SidebarScrollBar : public ScrollBar ++{ ++ SwSidebarWin& m_rSidebarWin; ++ SwView& m_rView; ++ ++protected: ++ /// @see OutputDevice::LogicInvalidate(). ++ void LogicInvalidate(const Rectangle* pRectangle) override; ++public: ++ SidebarScrollBar(SwSidebarWin& rSidebarWin, WinBits nStyle, SwView& rView); ++ virtual ~SidebarScrollBar(); ++}; ++ ++} ++} ++ ++#endif ++ ++/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index c95a8909de54..1bfab323e833 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -26,6 +26,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -623,7 +624,7 @@ void SwSidebarWin::InitControls() + } + + //create Scrollbars +- mpVScrollbar = VclPtr::Create(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG); ++ mpVScrollbar = VclPtr::Create(*this, WB_3DLOOK |WB_VSCROLL|WB_DRAG, mrView); + mpVScrollbar->EnableNativeWidget(false); + mpVScrollbar->EnableRTL( false ); + mpVScrollbar->SetScrollHdl(LINK(this, SwSidebarWin, ScrollHdl)); +-- +2.12.0 + diff --git a/SOURCES/0359-vcl-lok-handle-tracking-coordinates-which-are-in-twi.patch b/SOURCES/0359-vcl-lok-handle-tracking-coordinates-which-are-in-twi.patch new file mode 100644 index 0000000..7c8a348 --- /dev/null +++ b/SOURCES/0359-vcl-lok-handle-tracking-coordinates-which-are-in-twi.patch @@ -0,0 +1,45 @@ +From 077f463e0fdb16d1bd37154d0cfcb84959c63a66 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 24 Nov 2015 15:01:01 +0100 +Subject: [PATCH 359/398] vcl lok: handle tracking coordinates which are in + twips + +This is similar to the mouse button down handling. When the map mode is +disabled and the map mode is in twips, then in general it's possible to +send mouse coordinates in twips. The scrollbar is usually in pixels, so +add extra code to still make this possible. + +Change-Id: I0c7e404ecd7ac839e000266e396683bb7d15c505 +(cherry picked from commit d7acb44b148893fe0cc48a54c3eb73406c251668) +--- + vcl/source/control/scrbar.cxx | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/vcl/source/control/scrbar.cxx b/vcl/source/control/scrbar.cxx +index e8004d13d177..0679c848b682 100644 +--- a/vcl/source/control/scrbar.cxx ++++ b/vcl/source/control/scrbar.cxx +@@ -1076,7 +1076,19 @@ void ScrollBar::Tracking( const TrackingEvent& rTEvt ) + } + else + { +- const Point rMousePos = rTEvt.GetMouseEvent().GetPosPixel(); ++ Point aPosPixel; ++ if (!IsMapModeEnabled() && GetMapMode().GetMapUnit() == MAP_TWIP) ++ { ++ // rTEvt coordinates are in twips. ++ Push(PushFlags::MAPMODE); ++ EnableMapMode(); ++ MapMode aMapMode = GetMapMode(); ++ aMapMode.SetOrigin(Point(0, 0)); ++ SetMapMode(aMapMode); ++ aPosPixel = LogicToPixel(rTEvt.GetMouseEvent().GetPosPixel()); ++ Pop(); ++ } ++ const Point rMousePos = (GetMapMode().GetMapUnit() != MAP_TWIP ? rTEvt.GetMouseEvent().GetPosPixel() : aPosPixel); + + // Dragging is treated in a special way + if ( meScrollType == SCROLL_DRAG ) +-- +2.12.0 + diff --git a/SOURCES/0360-sw-lok-comments-implement-drag-of-the-scrollbar.patch b/SOURCES/0360-sw-lok-comments-implement-drag-of-the-scrollbar.patch new file mode 100644 index 0000000..88ad3d2 --- /dev/null +++ b/SOURCES/0360-sw-lok-comments-implement-drag-of-the-scrollbar.patch @@ -0,0 +1,83 @@ +From c440339bcd6661fe49ba148317b557d0b2e249b6 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 24 Nov 2015 15:04:33 +0100 +Subject: [PATCH 360/398] sw lok comments: implement drag of the scrollbar + +With this, if a comment has a vertical scrollbar, then not only the +buttons of the scrollbar can be clicked on, but also the slider of the +scrollbar can be dragged. + +(cherry picked from commit d562df03098ecb91a89e91ccf69dd6a1eeb98c89) + +Change-Id: I2e39e18bf60c42a878bb8bfd808f1d47be27eecb +--- + sw/source/uibase/docvw/SidebarScrollBar.cxx | 7 ++++++- + sw/source/uibase/docvw/SidebarScrollBar.hxx | 1 + + sw/source/uibase/docvw/SidebarWin.cxx | 10 +++++----- + 3 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/sw/source/uibase/docvw/SidebarScrollBar.cxx b/sw/source/uibase/docvw/SidebarScrollBar.cxx +index 909aa763dba1..7a80363693d1 100644 +--- a/sw/source/uibase/docvw/SidebarScrollBar.cxx ++++ b/sw/source/uibase/docvw/SidebarScrollBar.cxx +@@ -47,7 +47,7 @@ void SidebarScrollBar::LogicInvalidate(const Rectangle* pRectangle) + aRectangle = *pRectangle; + + // Convert from relative twips to absolute ones. +- vcl::Window& rParent = m_rSidebarWin.EditWin(); ++ vcl::Window& rParent = *m_rSidebarWin.EditWin(); + Point aOffset(GetOutOffXPixel() - rParent.GetOutOffXPixel(), GetOutOffYPixel() - rParent.GetOutOffYPixel()); + rParent.Push(PushFlags::MAPMODE); + rParent.EnableMapMode(); +@@ -60,6 +60,11 @@ void SidebarScrollBar::LogicInvalidate(const Rectangle* pRectangle) + rWrtShell.libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); + } + ++void SidebarScrollBar::MouseMove(const MouseEvent& rMouseEvent) ++{ ++ TrackingEvent aEvent(rMouseEvent); ++ Tracking(aEvent); ++} + + SidebarScrollBar::~SidebarScrollBar() + { +diff --git a/sw/source/uibase/docvw/SidebarScrollBar.hxx b/sw/source/uibase/docvw/SidebarScrollBar.hxx +index 9543205387df..ea5639e42e92 100644 +--- a/sw/source/uibase/docvw/SidebarScrollBar.hxx ++++ b/sw/source/uibase/docvw/SidebarScrollBar.hxx +@@ -30,6 +30,7 @@ class SidebarScrollBar : public ScrollBar + protected: + /// @see OutputDevice::LogicInvalidate(). + void LogicInvalidate(const Rectangle* pRectangle) override; ++ void MouseMove(const MouseEvent& rMouseEvent) override; + public: + SidebarScrollBar(SwSidebarWin& rSidebarWin, WinBits nStyle, SwView& rView); + virtual ~SidebarScrollBar(); +diff --git a/sw/source/uibase/docvw/SidebarWin.cxx b/sw/source/uibase/docvw/SidebarWin.cxx +index 1bfab323e833..d22bdd0c245b 100644 +--- a/sw/source/uibase/docvw/SidebarWin.cxx ++++ b/sw/source/uibase/docvw/SidebarWin.cxx +@@ -464,15 +464,15 @@ void SwSidebarWin::KeyInput(const KeyEvent& rKeyEvent) + + void SwSidebarWin::MouseMove(const MouseEvent& rMouseEvent) + { +- if (mpSidebarTextControl) ++ if (vcl::Window* pHit = lcl_getHitWindow(*this, rMouseEvent)) + { +- mpSidebarTextControl->Push(PushFlags::MAPMODE); ++ pHit->Push(PushFlags::MAPMODE); + MouseEvent aMouseEvent(rMouseEvent); +- lcl_translateTwips(*EditWin(), *mpSidebarTextControl, &aMouseEvent); ++ lcl_translateTwips(*EditWin(), *pHit, &aMouseEvent); + +- mpSidebarTextControl->MouseMove(aMouseEvent); ++ pHit->MouseMove(aMouseEvent); + +- mpSidebarTextControl->Pop(); ++ pHit->Pop(); + } + } + +-- +2.12.0 + diff --git a/SOURCES/0361-sw-lok-comments-avoid-crash-an-exit-after-clicking-t.patch b/SOURCES/0361-sw-lok-comments-avoid-crash-an-exit-after-clicking-t.patch new file mode 100644 index 0000000..dfd4652 --- /dev/null +++ b/SOURCES/0361-sw-lok-comments-avoid-crash-an-exit-after-clicking-t.patch @@ -0,0 +1,51 @@ +From 0410c35ff5f46e51def9a2515d8e5a72f8fd37c4 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 24 Nov 2015 15:20:22 +0100 +Subject: [PATCH 361/398] sw lok comments: avoid crash an exit after clicking + the scrollbar + +Without this, vcl::Window::ImplTrackTimerHdl() will be called on a +deleted vcl::Window. + +Can be reproduced with a comment having a scrollbar in a LOK client, +then clicking on the down button of the scrollbar a number of times -> +crash on exit. + +Change-Id: I5d67f96e8baa199f65ec5cf39cb5d39c8162ff33 +(cherry picked from commit 7c654ee9d51a752e02c0a972de27d699ab5b649a) +--- + sw/source/uibase/docvw/SidebarScrollBar.cxx | 5 +++++ + sw/source/uibase/docvw/SidebarScrollBar.hxx | 1 + + 2 files changed, 6 insertions(+) + +diff --git a/sw/source/uibase/docvw/SidebarScrollBar.cxx b/sw/source/uibase/docvw/SidebarScrollBar.cxx +index 7a80363693d1..b4d70b423eec 100644 +--- a/sw/source/uibase/docvw/SidebarScrollBar.cxx ++++ b/sw/source/uibase/docvw/SidebarScrollBar.cxx +@@ -60,6 +60,11 @@ void SidebarScrollBar::LogicInvalidate(const Rectangle* pRectangle) + rWrtShell.libreOfficeKitCallback(LOK_CALLBACK_INVALIDATE_TILES, sRectangle.getStr()); + } + ++void SidebarScrollBar::MouseButtonUp(const MouseEvent& /*rMouseEvent*/) ++{ ++ EndTracking(); ++} ++ + void SidebarScrollBar::MouseMove(const MouseEvent& rMouseEvent) + { + TrackingEvent aEvent(rMouseEvent); +diff --git a/sw/source/uibase/docvw/SidebarScrollBar.hxx b/sw/source/uibase/docvw/SidebarScrollBar.hxx +index ea5639e42e92..0de225b2a135 100644 +--- a/sw/source/uibase/docvw/SidebarScrollBar.hxx ++++ b/sw/source/uibase/docvw/SidebarScrollBar.hxx +@@ -31,6 +31,7 @@ protected: + /// @see OutputDevice::LogicInvalidate(). + void LogicInvalidate(const Rectangle* pRectangle) override; + void MouseMove(const MouseEvent& rMouseEvent) override; ++ void MouseButtonUp(const MouseEvent& rMouseEvent) override; + public: + SidebarScrollBar(SwSidebarWin& rSidebarWin, WinBits nStyle, SwView& rView); + virtual ~SidebarScrollBar(); +-- +2.12.0 + diff --git a/SOURCES/0362-sw-lok-comments-fix-map-mode-state-after-changing-zo.patch b/SOURCES/0362-sw-lok-comments-fix-map-mode-state-after-changing-zo.patch new file mode 100644 index 0000000..1581b3a --- /dev/null +++ b/SOURCES/0362-sw-lok-comments-fix-map-mode-state-after-changing-zo.patch @@ -0,0 +1,35 @@ +From 2ab4afba1e464e0a581fd9200ed0c31567982010 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 24 Nov 2015 15:37:29 +0100 +Subject: [PATCH 362/398] sw lok comments: fix map mode state after changing + zoom levels + +Zoom level of SwEditWin is kept in sync with the client, so that the +pixel-based comment widgets can be positioned correctly. But that does +not mean in general the SwEditWin map mode should not be disabled: so +that we don't have to tweak the map mode for each and every +postMouseEvent() call and still be able to send them using logic +coordinates. + +Change-Id: I6f686b93d2509d52fdd34e84a502cf04e1ce6e59 +(cherry picked from commit de2a6897876976d769504a36abf54eced626b01c) +--- + sw/source/core/view/viewsh.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx +index 093d5208fdda..e74a4a2514c8 100644 +--- a/sw/source/core/view/viewsh.cxx ++++ b/sw/source/core/view/viewsh.cxx +@@ -1886,6 +1886,8 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex + SwViewOption aOption(*GetViewOptions()); + aOption.SetZoom(fScale * 100); + ApplyViewOptions(aOption); ++ // Make sure the map mode (disabled in SwXTextDocument::initializeForTiledRendering()) is still disabled. ++ GetWin()->EnableMapMode(false); + } + + Rectangle aOutRect = Rectangle(Point(tilePosX, tilePosY), +-- +2.12.0 + diff --git a/SOURCES/0363-tdf-96243-don-t-crash-if-LibO-install.-wasn-t-found.patch b/SOURCES/0363-tdf-96243-don-t-crash-if-LibO-install.-wasn-t-found.patch new file mode 100644 index 0000000..d1bd737 --- /dev/null +++ b/SOURCES/0363-tdf-96243-don-t-crash-if-LibO-install.-wasn-t-found.patch @@ -0,0 +1,28 @@ +From 3f6d5ad9422e8f000527fa6d7650f9fe147242a4 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 7 Dec 2015 13:09:07 +0100 +Subject: [PATCH 363/398] tdf#96243 don't crash if LibO install. wasn't found + +Change-Id: I538e7238feb711a7d71faf745033264894f688f4 +(cherry picked from commit 7f73ea2e3975b305e09467eb7980a3d01cd37de9) +(cherry picked from commit 125382803df6502e467cb25b6ee70c24d5f4dfc0) +--- + include/LibreOfficeKit/LibreOfficeKitInit.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitInit.h b/include/LibreOfficeKit/LibreOfficeKitInit.h +index f18e3ca3c8e4..cb3654808cf9 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitInit.h ++++ b/include/LibreOfficeKit/LibreOfficeKitInit.h +@@ -219,6 +219,8 @@ static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_p + LokHookFunction2 *pSym2; + + dlhandle = lok_dlopen(install_path, &imp_lib); ++ if (!dlhandle) ++ return NULL; + + pSym2 = (LokHookFunction2 *) lok_dlsym(dlhandle, "libreofficekit_hook_2"); + if (!pSym2) +-- +2.12.0 + diff --git a/SOURCES/0364-improve-error-message-for-nonexist.-path.patch b/SOURCES/0364-improve-error-message-for-nonexist.-path.patch new file mode 100644 index 0000000..fcb7b9d --- /dev/null +++ b/SOURCES/0364-improve-error-message-for-nonexist.-path.patch @@ -0,0 +1,36 @@ +From 3c7839a75bdf8d033152d16fa9abad2c8bf7ae5c Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 7 Dec 2015 13:10:50 +0100 +Subject: [PATCH 364/398] improve error message for nonexist. path + +... which is currently somewhat misleading, because it mentions +libmerged.so. + +Change-Id: I1ab21ce0fe2f94eba1831c2c977d900827f320f1 +(cherry picked from commit 764ec21307009a84b2611fed5cb20069caa6d566) +(cherry picked from commit 01825a8c1722161876fa8209e15e413c44774a5c) +--- + include/LibreOfficeKit/LibreOfficeKitInit.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitInit.h b/include/LibreOfficeKit/LibreOfficeKitInit.h +index cb3654808cf9..2d0b00299800 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitInit.h ++++ b/include/LibreOfficeKit/LibreOfficeKitInit.h +@@ -154,6 +154,13 @@ static void *lok_dlopen( const char *install_path, char ** _imp_lib ) + if (!install_path) + return NULL; + ++ struct stat dir_st; ++ if (stat(install_path, &dir_st) != 0) ++ { ++ fprintf(stderr, "installation path \"%s\" does not exist\n", install_path); ++ return NULL; ++ } ++ + // allocate large enough buffer + partial_length = strlen(install_path); + imp_lib = (char *) malloc(partial_length + sizeof(TARGET_LIB) + sizeof(TARGET_MERGED_LIB) + 2); +-- +2.12.0 + diff --git a/SOURCES/0365-tdf-96246-Make-pRenderingArguments-nullable.patch b/SOURCES/0365-tdf-96246-Make-pRenderingArguments-nullable.patch new file mode 100644 index 0000000..44f5576 --- /dev/null +++ b/SOURCES/0365-tdf-96246-Make-pRenderingArguments-nullable.patch @@ -0,0 +1,36 @@ +From c61bb4b9c05be5b546d3823052a6ac2f593ce15b Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 6 Dec 2015 23:41:57 +0530 +Subject: [PATCH 365/398] tdf#96246: Make pRenderingArguments nullable + +Type gchar* is not nullable by convention. + +See: +https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Nullable_parameters + +Change-Id: Ibfee816a3ef2d29c7376071fb61eda7bf0538efb +Reviewed-on: https://gerrit.libreoffice.org/20425 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit 9e9703389e015d0f3520344715df6719559362e4) +(cherry picked from commit f37903004d93e7d7b008b2667881159bd8fee1e1) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index c947ce3f8369..8b6092c56ef2 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -65,7 +65,7 @@ GtkWidget* lok_doc_view_new_from_widget (LOKDocView* + * lok_doc_view_open_document: + * @pDocView: The #LOKDocView instance + * @pPath: (transfer full): The path of the document that #LOKDocView widget should try to open +- * @pRenderingArguments: lok::Document::initializeForRendering() arguments. ++ * @pRenderingArguments: (nullable): lok::Document::initializeForRendering() arguments. + * @cancellable: + * @callback: + * @userdata: +-- +2.12.0 + diff --git a/SOURCES/0366-tdf-96250-desktop-empty-str-is-the-same-as-0-str-in-.patch b/SOURCES/0366-tdf-96250-desktop-empty-str-is-the-same-as-0-str-in-.patch new file mode 100644 index 0000000..b38fa39 --- /dev/null +++ b/SOURCES/0366-tdf-96250-desktop-empty-str-is-the-same-as-0-str-in-.patch @@ -0,0 +1,29 @@ +From cfae897d306b6b140052c4c3f06dd614f9a22943 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Mon, 7 Dec 2015 14:54:19 +0100 +Subject: [PATCH 366/398] tdf#96250 desktop: empty str is the same as 0 str in + jsonToPropertyValues() + +Change-Id: I77306dc998afc53bb1d5710a8d1ae68717f945d1 +(cherry picked from commit 5cc574fefc8a2ee39db4a4bd843a3ec67dce2f11) +(cherry picked from commit e22f9ae034addbddbb5581cdee6bfd1c39aeedea) +--- + desktop/source/lib/init.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 57bb177f49db..6bed25514137 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -263,7 +263,7 @@ static OUString getAbsoluteURL(const char* pURL) + static void jsonToPropertyValues(const char* pJSON, uno::Sequence& rPropertyValues) + { + std::vector aArguments; +- if (pJSON) ++ if (pJSON && pJSON[0] != '\0') + { + boost::property_tree::ptree aTree; + std::stringstream aStream(pJSON); +-- +2.12.0 + diff --git a/SOURCES/0367-tdf-96316-Decouple-view-only-editable-modes.patch b/SOURCES/0367-tdf-96316-Decouple-view-only-editable-modes.patch new file mode 100644 index 0000000..1c0a3cd --- /dev/null +++ b/SOURCES/0367-tdf-96316-Decouple-view-only-editable-modes.patch @@ -0,0 +1,407 @@ +From 74730e13d8ebee67a1c235ef203a9b56a8097593 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 9 Dec 2015 01:03:02 +0530 +Subject: [PATCH 367/398] tdf#96316: Decouple view-only/editable modes + +- Move text selection and graphic selection tasks into functions +- Merge GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE conditional code +- Do not change to 'move' cursor in view-only mode +- Ignore LOK_POST_COMMAND, LOK_SET_GRAPHIC_SELECTION in view-only + +As a consequence this commit also allows dragging handles during text +selection in view-only mode which was earlier not possible. + +Change-Id: Iffb668d5447dd646a1e40237dee8d8d3fa3314b6 +Reviewed-on: https://gerrit.libreoffice.org/20487 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit b3bfc26d0863b074bb990725718f2ab23d05425d) +(cherry picked from commit 0a28049853ce84aa8ef4f871065970c1220ae855) +--- + libreofficekit/source/gtk/lokdocview.cxx | 312 ++++++++++++++++++------------- + 1 file changed, 180 insertions(+), 132 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 464348d95f1c..5e985d4a8c2f 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -312,6 +312,153 @@ isEmptyRectangle(const GdkRectangle& rRectangle) + return rRectangle.x == 0 && rRectangle.y == 0 && rRectangle.width == 0 && rRectangle.height == 0; + } + ++/// if handled, returns TRUE else FALSE ++static bool ++handleTextSelectionOnButtonPress(GdkRectangle& aClick, LOKDocView* pDocView) { ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ ++ if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, nullptr)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag start handle"); ++ priv->m_bInDragStartHandle = true; ++ return TRUE; ++ } ++ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, nullptr)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag middle handle"); ++ priv->m_bInDragMiddleHandle = true; ++ return TRUE; ++ } ++ else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, nullptr)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag end handle"); ++ priv->m_bInDragEndHandle = true; ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++/// if handled, returns TRUE else FALSE ++static bool ++handleGraphicSelectionOnButtonPress(GdkRectangle& aClick, LOKDocView* pDocView) { ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ GError* error = nullptr; ++ ++ for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) ++ { ++ if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], nullptr)) ++ { ++ g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i); ++ priv->m_bInDragGraphicHandles[i] = true; ++ ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); ++ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; ++ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom); ++ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); ++ ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != nullptr) ++ { ++ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); ++ g_clear_error(&error); ++ } ++ g_object_unref(task); ++ ++ return TRUE; ++ } ++ } ++ ++ return FALSE; ++} ++ ++/// if handled, returns TRUE else FALSE ++static bool ++handleTextSelectionOnButtonRelease(LOKDocView* pDocView) { ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ ++ if (priv->m_bInDragStartHandle) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag start handle"); ++ priv->m_bInDragStartHandle = false; ++ return TRUE; ++ } ++ else if (priv->m_bInDragMiddleHandle) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag middle handle"); ++ priv->m_bInDragMiddleHandle = false; ++ return TRUE; ++ } ++ else if (priv->m_bInDragEndHandle) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag end handle"); ++ priv->m_bInDragEndHandle = false; ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++/// if handled, returns TRUE else FALSE ++static bool ++handleGraphicSelectionOnButtonRelease(LOKDocView* pDocView, GdkEventButton* pEvent) { ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ GError* error = nullptr; ++ ++ for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) ++ { ++ if (priv->m_bInDragGraphicHandles[i]) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i); ++ priv->m_bInDragGraphicHandles[i] = false; ++ ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); ++ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; ++ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); ++ ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != nullptr) ++ { ++ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); ++ g_clear_error(&error); ++ } ++ g_object_unref(task); ++ ++ return TRUE; ++ } ++ } ++ ++ if (priv->m_bInDragGraphicSelection) ++ { ++ g_info("LOKDocView_Impl::signalButton: end of drag graphic selection"); ++ priv->m_bInDragGraphicSelection = false; ++ ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); ++ LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); ++ pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; ++ pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); ++ pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); ++ ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != nullptr) ++ { ++ g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); ++ g_clear_error(&error); ++ } ++ g_object_unref(task); ++ ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + static void + postKeyEventInThread(gpointer data) + { +@@ -747,11 +894,17 @@ callback (gpointer pData) + break; + case LOK_CALLBACK_MOUSE_POINTER: + { +- // The gtk docs claim that most css cursors should be supported, however +- // on my system at least this is not true and many cursors are unsupported. +- // In this case pCursor = null, which results in the default cursor being set. +- GdkCursor* pCursor = gdk_cursor_new_from_name(gtk_widget_get_display(GTK_WIDGET(pDocView)), pCallback->m_aPayload.c_str()); +- gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(pDocView)), pCursor); ++ // We do not want the cursor to get changed in view-only mode ++ if (priv->m_bEdit) ++ { ++ // The gtk docs claim that most css cursors should be supported, however ++ // on my system at least this is not true and many cursors are unsupported. ++ // In this case pCursor = null, which results in the default cursor ++ // being set. ++ GdkCursor* pCursor = gdk_cursor_new_from_name(gtk_widget_get_display(GTK_WIDGET(pDocView)), ++ pCallback->m_aPayload.c_str()); ++ gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(pDocView)), pCursor); ++ } + } + break; + case LOK_CALLBACK_GRAPHIC_SELECTION: +@@ -1176,140 +1329,21 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + (int)pixelToTwip(pEvent->y, priv->m_fZoom)); + gtk_widget_grab_focus(GTK_WIDGET(pDocView)); + +- if (pEvent->type == GDK_BUTTON_RELEASE) ++ switch (pEvent->type) + { +- if (priv->m_bInDragStartHandle) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag start handle"); +- priv->m_bInDragStartHandle = false; +- return FALSE; +- } +- else if (priv->m_bInDragMiddleHandle) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag middle handle"); +- priv->m_bInDragMiddleHandle = false; +- return FALSE; +- } +- else if (priv->m_bInDragEndHandle) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag end handle"); +- priv->m_bInDragEndHandle = false; +- return FALSE; +- } +- +- for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) +- { +- if (priv->m_bInDragGraphicHandles[i]) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag graphic handle #%d", i); +- priv->m_bInDragGraphicHandles[i] = false; +- +- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); +- LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); +- pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; +- pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); +- pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); +- g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != nullptr) +- { +- g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); +- g_clear_error(&error); +- } +- g_object_unref(task); +- +- return FALSE; +- } +- } +- +- if (priv->m_bInDragGraphicSelection) +- { +- g_info("LOKDocView_Impl::signalButton: end of drag graphic selection"); +- priv->m_bInDragGraphicSelection = false; +- +- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); +- LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); +- pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_END; +- pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(pEvent->x, priv->m_fZoom); +- pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(pEvent->y, priv->m_fZoom); +- g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != nullptr) +- { +- g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); +- g_clear_error(&error); +- } +- g_object_unref(task); +- +- return FALSE; +- } +- } +- +- if (priv->m_bEdit) ++ case GDK_BUTTON_PRESS: + { + GdkRectangle aClick; + aClick.x = pEvent->x; + aClick.y = pEvent->y; + aClick.width = 1; + aClick.height = 1; +- if (pEvent->type == GDK_BUTTON_PRESS) +- { +- if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleStartRect, nullptr)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag start handle"); +- priv->m_bInDragStartHandle = true; +- return FALSE; +- } +- else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleMiddleRect, nullptr)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag middle handle"); +- priv->m_bInDragMiddleHandle = true; +- return FALSE; +- } +- else if (gdk_rectangle_intersect(&aClick, &priv->m_aHandleEndRect, nullptr)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag end handle"); +- priv->m_bInDragEndHandle = true; +- return FALSE; +- } + +- for (int i = 0; i < GRAPHIC_HANDLE_COUNT; ++i) +- { +- if (gdk_rectangle_intersect(&aClick, &priv->m_aGraphicHandleRects[i], nullptr)) +- { +- g_info("LOKDocView_Impl::signalButton: start of drag graphic handle #%d", i); +- priv->m_bInDragGraphicHandles[i] = true; +- +- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); +- LOEvent* pLOEvent = new LOEvent(LOK_SET_GRAPHIC_SELECTION); +- pLOEvent->m_nSetGraphicSelectionType = LOK_SETGRAPHICSELECTION_START; +- pLOEvent->m_nSetGraphicSelectionX = pixelToTwip(priv->m_aGraphicHandleRects[i].x + priv->m_aGraphicHandleRects[i].width / 2, priv->m_fZoom); +- pLOEvent->m_nSetGraphicSelectionY = pixelToTwip(priv->m_aGraphicHandleRects[i].y + priv->m_aGraphicHandleRects[i].height / 2, priv->m_fZoom); +- g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != nullptr) +- { +- g_warning("Unable to call LOK_SET_GRAPHIC_SELECTION: %s", error->message); +- g_clear_error(&error); +- } +- g_object_unref(task); +- +- return FALSE; +- } +- } +- } +- } +- +- if (!priv->m_bEdit) +- lok_doc_view_set_edit(pDocView, TRUE); ++ if (handleTextSelectionOnButtonPress(aClick, pDocView)) ++ return FALSE; ++ if (handleGraphicSelectionOnButtonPress(aClick, pDocView)) ++ return FALSE; + +- switch (pEvent->type) +- { +- case GDK_BUTTON_PRESS: +- { + int nCount = 1; + if ((pEvent->time - priv->m_nLastButtonPressTime) < 250) + nCount++; +@@ -1347,6 +1381,11 @@ lok_doc_view_signal_button(GtkWidget* pWidget, GdkEventButton* pEvent) + } + case GDK_BUTTON_RELEASE: + { ++ if (handleTextSelectionOnButtonRelease(pDocView)) ++ return FALSE; ++ if (handleGraphicSelectionOnButtonRelease(pDocView, pEvent)) ++ return FALSE; ++ + int nCount = 1; + if ((pEvent->time - priv->m_nLastButtonReleaseTime) < 250) + nCount++; +@@ -1720,6 +1759,8 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + { + GTask* task = G_TASK(data); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); ++ LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); ++ LOKDocViewPrivate& priv = getPrivate(pDocView); + + switch (pLOEvent->m_nType) + { +@@ -1727,7 +1768,10 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + openDocumentInThread(task); + break; + case LOK_POST_COMMAND: +- postCommandInThread(task); ++ if (priv->m_bEdit) ++ postCommandInThread(task); ++ else ++ g_info ("LOK_POST_COMMAND: ignoring commands in view-only mode"); + break; + case LOK_SET_EDIT: + setEditInThread(task); +@@ -1739,6 +1783,7 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + setPartmodeInThread(task); + break; + case LOK_POST_KEY: ++ // view-only/editable mode already checked during signal key signal emission + postKeyEventInThread(task); + break; + case LOK_PAINT_TILE: +@@ -1748,7 +1793,10 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + postMouseEventInThread(task); + break; + case LOK_SET_GRAPHIC_SELECTION: +- setGraphicSelectionInThread(task); ++ if (priv->m_bEdit) ++ setGraphicSelectionInThread(task); ++ else ++ g_info ("LOK_SET_GRAPHIC_SELECTION: skipping graphical operation in view-only mode"); + break; + case LOK_SET_CLIENT_ZOOM: + setClientZoomInThread(task); +-- +2.12.0 + diff --git a/SOURCES/0368-tdf-96318-Add-searching-API.patch b/SOURCES/0368-tdf-96318-Add-searching-API.patch new file mode 100644 index 0000000..b06dde2 --- /dev/null +++ b/SOURCES/0368-tdf-96318-Add-searching-API.patch @@ -0,0 +1,296 @@ +From cc1e87b14fae9c6fb84ee5c9307ed27945fab289 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 9 Dec 2015 10:33:05 +0530 +Subject: [PATCH 368/398] tdf#96318: Add searching API + +Clients should now use these APIs to search for text in the +widget, rather than executing UNO commands directly on the +widget. This allows searching for text in the widget in view-only +mode too. + +Change-Id: I013b6f96e69a634ec33367394d39c0f645a4994d +Reviewed-on: https://gerrit.libreoffice.org/20488 +Tested-by: Jenkins +Reviewed-by: David Tardon +(cherry picked from commit 0f64cf72ff3b930e306e937bb18f4cbe55a8026a) +(cherry picked from commit e7cdd6803485bbe4cfe27f5f466b427823318334) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 38 ++++++++ + .../qa/gtktiledviewer/gtktiledviewer.cxx | 46 +++------ + libreofficekit/source/gtk/lokdocview.cxx | 107 +++++++++++++++++---- + 3 files changed, 139 insertions(+), 52 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 8b6092c56ef2..b2f17f14b6cb 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -195,6 +195,44 @@ void lok_doc_view_post_command (LOKDocView* + const gchar* pArguments, + gboolean bNotifyWhenFinished); + ++ ++/** ++ * lok_doc_view_find_next: ++ * @pDocView: The #LOKDocView instance ++ * @pText: text to search for ++ * @bHighlightAll: Whether all the matches should be highlighted or not ++ * ++ * Highlights the next matching text in the view. `search-not-found` signal will ++ * be emitted when no search is found ++ */ ++void lok_doc_view_find_next (LOKDocView* pDocView, ++ const gchar* pText, ++ gboolean bHighlightAll); ++ ++/** ++ * lok_doc_view_find_prev: ++ * @pDocView: The #LOKDocView instance ++ * @pText: text to search for ++ * @bHighlightAll: Whether all the matches should be highlighted or not ++ * ++ * Highlights the previous matching text in the view. `search-not-found` signal ++ * will be emitted when no search is found ++ */ ++void lok_doc_view_find_prev (LOKDocView* pDocView, ++ const gchar* pText, ++ gboolean bHighlightAll); ++ ++/** ++ * lok_doc_view_highlight_all: ++ * @pDocView: The #LOKDocView instance ++ * @pText: text to search for ++ * ++ * Highlights all matching texts in the view. `search-not-found` signal ++ * will be emitted when no search is found ++ */ ++void lok_doc_view_highlight_all (LOKDocView* pDocView, ++ const gchar* pText); ++ + /** + * lok_doc_view_pixel_to_twip: + * @pDocView: The #LOKDocView instance +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index e44a92a3f3de..2416e1c6dbcf 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -439,7 +439,11 @@ static void toggleEditing(GtkWidget* pButton, gpointer /*pItem*/) + static void toggleFindAll(GtkWidget* pButton, gpointer /*pItem*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ GtkEntry* pEntry = GTK_ENTRY(rWindow.m_pFindbarEntry); ++ const char* pText = gtk_entry_get_text(pEntry); ++ + rWindow.m_bFindAll = !rWindow.m_bFindAll; ++ lok_doc_view_highlight_all(LOK_DOC_VIEW(rWindow.m_pDocView), pText); + } + + /// Toggle the visibility of the findbar. +@@ -597,48 +601,24 @@ static void doPaste(GtkWidget* pButton, gpointer /*pItem*/) + pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", pText, strlen(pText)); + } + +-/// Searches for the next or previous text of TiledWindow::m_pFindbarEntry. +-static void doSearch(GtkWidget* pButton, bool bBackwards) ++/// Click handler for the search next button. ++static void signalSearchNext(GtkWidget* pButton, gpointer /*pItem*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pButton); + GtkEntry* pEntry = GTK_ENTRY(rWindow.m_pFindbarEntry); + const char* pText = gtk_entry_get_text(pEntry); +- boost::property_tree::ptree aTree; +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/type", '/'), "string"); +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/value", '/'), pText); +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean"); +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards); +- if (rWindow.m_bFindAll) +- { +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/type", '/'), "unsigned short"); +- // SvxSearchCmd::FIND_ALL +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/value", '/'), "1"); +- } +- +- LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); +- GdkRectangle aArea; +- getVisibleAreaTwips(rWindow.m_pDocView, &aArea); +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/type", '/'), "long"); +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/value", '/'), aArea.x); +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/type", '/'), "long"); +- aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/value", '/'), aArea.y); +- +- std::stringstream aStream; +- boost::property_tree::write_json(aStream, aTree); + +- lok_doc_view_post_command(pLOKDocView, ".uno:ExecuteSearch", aStream.str().c_str(), false); +-} +- +-/// Click handler for the search next button. +-static void signalSearchNext(GtkWidget* pButton, gpointer /*pItem*/) +-{ +- doSearch(pButton, /*bBackwards=*/false); ++ lok_doc_view_find_next(LOK_DOC_VIEW(rWindow.m_pDocView), pText, rWindow.m_bFindAll); + } + + /// Click handler for the search previous button. + static void signalSearchPrev(GtkWidget* pButton, gpointer /*pItem*/) + { +- doSearch(pButton, /*bBackwards=*/true); ++ TiledWindow& rWindow = lcl_getTiledWindow(pButton); ++ GtkEntry* pEntry = GTK_ENTRY(rWindow.m_pFindbarEntry); ++ const char* pText = gtk_entry_get_text(pEntry); ++ ++ lok_doc_view_find_prev(LOK_DOC_VIEW(rWindow.m_pDocView), pText, rWindow.m_bFindAll); + } + + /// Handles the key-press-event of the search entry widget. +@@ -651,7 +631,7 @@ static gboolean signalFindbar(GtkWidget* pWidget, GdkEventKey* pEvent, gpointer + case GDK_KEY_Return: + { + // Search forward. +- doSearch(pWidget, /*bBackwards=*/false); ++ signalSearchNext(pWidget, nullptr); + return TRUE; + } + case GDK_KEY_Escape: +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 5e985d4a8c2f..424d80eabcf9 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -306,6 +306,67 @@ callbackTypeToString (int nType) + return nullptr; + } + ++static void ++LOKPostCommand (LOKDocView* pDocView, ++ const gchar* pCommand, ++ const gchar* pArguments, ++ gboolean bNotifyWhenFinished) ++{ ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); ++ LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); ++ GError* error = nullptr; ++ pLOEvent->m_pCommand = pCommand; ++ pLOEvent->m_pArguments = g_strdup(pArguments); ++ pLOEvent->m_bNotifyWhenFinished = bNotifyWhenFinished; ++ ++ g_task_set_task_data(task, pLOEvent, LOEvent::destroy); ++ g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); ++ if (error != nullptr) ++ { ++ g_warning("Unable to call LOK_POST_COMMAND: %s", error->message); ++ g_clear_error(&error); ++ } ++ g_object_unref(task); ++} ++ ++static void ++doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highlightAll) ++{ ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ boost::property_tree::ptree aTree; ++ GtkWidget* drawingWidget = GTK_WIDGET(pDocView); ++ GdkWindow* drawingWindow = gtk_widget_get_window(drawingWidget); ++ cairo_region_t* cairoVisRegion = gdk_window_get_visible_region(drawingWindow); ++ cairo_rectangle_int_t cairoVisRect; ++ int x, y; ++ ++ cairo_region_get_rectangle(cairoVisRegion, 0, &cairoVisRect); ++ x = pixelToTwip (cairoVisRect.x, priv->m_fZoom); ++ y = pixelToTwip (cairoVisRect.y, priv->m_fZoom); ++ ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/type", '/'), "string"); ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/value", '/'), pText); ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean"); ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/value", '/'), bBackwards); ++ if (highlightAll) ++ { ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/type", '/'), "unsigned short"); ++ // SvxSearchCmd::FIND_ALL ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.Command/value", '/'), "1"); ++ } ++ ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/type", '/'), "long"); ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointX/value", '/'), x); ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/type", '/'), "long"); ++ aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchStartPointY/value", '/'), y); ++ ++ std::stringstream aStream; ++ boost::property_tree::write_json(aStream, aTree); ++ ++ LOKPostCommand (pDocView, ".uno:ExecuteSearch", aStream.str().c_str(), false); ++} ++ + static bool + isEmptyRectangle(const GdkRectangle& rRectangle) + { +@@ -1768,10 +1829,7 @@ lokThreadFunc(gpointer data, gpointer /*user_data*/) + openDocumentInThread(task); + break; + case LOK_POST_COMMAND: +- if (priv->m_bEdit) +- postCommandInThread(task); +- else +- g_info ("LOK_POST_COMMAND: ignoring commands in view-only mode"); ++ postCommandInThread(task); + break; + case LOK_SET_EDIT: + setEditInThread(task); +@@ -2573,7 +2631,6 @@ lok_doc_view_get_edit (LOKDocView* pDocView) + return priv->m_bEdit; + } + +- + SAL_DLLPUBLIC_EXPORT void + lok_doc_view_post_command (LOKDocView* pDocView, + const gchar* pCommand, +@@ -2581,21 +2638,33 @@ lok_doc_view_post_command (LOKDocView* pDocView, + gboolean bNotifyWhenFinished) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); +- LOEvent* pLOEvent = new LOEvent(LOK_POST_COMMAND); +- GError* error = nullptr; +- pLOEvent->m_pCommand = pCommand; +- pLOEvent->m_pArguments = g_strdup(pArguments); +- pLOEvent->m_bNotifyWhenFinished = bNotifyWhenFinished; ++ if (priv->m_bEdit) ++ LOKPostCommand(pDocView, pCommand, pArguments, bNotifyWhenFinished); ++ else ++ g_info ("LOK_POST_COMMAND: ignoring commands in view-only mode"); ++} + +- g_task_set_task_data(task, pLOEvent, LOEvent::destroy); +- g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +- if (error != nullptr) +- { +- g_warning("Unable to call LOK_POST_COMMAND: %s", error->message); +- g_clear_error(&error); +- } +- g_object_unref(task); ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_find_prev (LOKDocView* pDocView, ++ const gchar* pText, ++ gboolean bHighlightAll) ++{ ++ doSearch(pDocView, pText, true, bHighlightAll); ++} ++ ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_find_next (LOKDocView* pDocView, ++ const gchar* pText, ++ gboolean bHighlightAll) ++{ ++ doSearch(pDocView, pText, false, bHighlightAll); ++} ++ ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_highlight_all (LOKDocView* pDocView, ++ const gchar* pText) ++{ ++ doSearch(pDocView, pText, false, true); + } + + SAL_DLLPUBLIC_EXPORT float +-- +2.12.0 + diff --git a/SOURCES/0369-lokdocview-Set-a-default-path-for-LOK-init.patch b/SOURCES/0369-lokdocview-Set-a-default-path-for-LOK-init.patch new file mode 100644 index 0000000..6347e73 --- /dev/null +++ b/SOURCES/0369-lokdocview-Set-a-default-path-for-LOK-init.patch @@ -0,0 +1,65 @@ +From 3943bc9014e426740ca5f756eae4cf4dd124bc23 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 8 Dec 2015 23:14:25 +0530 +Subject: [PATCH 369/398] lokdocview: Set a 'default' path for LOK init + +When passed NULL to lok_doc_view_new, use the default path : +$libdir/libreoffice/program as LOK install path + +Change-Id: I1e033c407184b29b1509cfb8c416b514591d67ce +Reviewed-on: https://gerrit.libreoffice.org/20476 +Tested-by: Jenkins +Reviewed-by: David Tardon +(cherry picked from commit 424c09b10d3d6ba6edfed2dcf560d5ce2c950b9d) +(cherry picked from commit dabfa0ce06f605fd0e8de32774b6385fd6ffbd56) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 3 ++- + libreofficekit/Library_libreofficekitgtk.mk | 4 ++++ + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 3 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index b2f17f14b6cb..1b03e4633547 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -42,7 +42,8 @@ GType lok_doc_view_get_type (void) G_GNUC + + /** + * lok_doc_view_new: +- * @pPath: LibreOffice install path. ++ * @pPath: (nullable): LibreOffice install path. Pass null to set it to default ++ * path which in most cases would be $libdir/libreoffice/program + * @cancellable: The cancellable object that you can use to cancel this + * operation. + * @error: The error that will be set if the object fails to initialize. +diff --git a/libreofficekit/Library_libreofficekitgtk.mk b/libreofficekit/Library_libreofficekitgtk.mk +index 3eba939ad56c..fc62e72ca723 100644 +--- a/libreofficekit/Library_libreofficekitgtk.mk ++++ b/libreofficekit/Library_libreofficekitgtk.mk +@@ -28,6 +28,10 @@ $(eval $(call gb_Library_add_libs,libreofficekitgtk,\ + $(GTK3_LIBS) \ + )) + ++$(eval $(call gb_Library_add_defs,libreofficekitgtk,\ ++ -DLOK_PATH="\"$(LIBDIR)/libreoffice/$(LIBO_LIB_FOLDER)\"" \ ++)) ++ + ifeq ($(OS),$(filter LINUX %BSD SOLARIS, $(OS))) + $(eval $(call gb_Library_add_libs,libreofficekitgtk,\ + $(DLOPEN_LIBS) -lm \ +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 424d80eabcf9..34823437e6ad 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2385,7 +2385,7 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + SAL_DLLPUBLIC_EXPORT GtkWidget* + lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + { +- return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath, NULL)); ++ return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath == NULL ? LOK_PATH : pPath, NULL)); + } + + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOKDocView) +-- +2.12.0 + diff --git a/SOURCES/0370-tdf-96317-Add-API-for-copy-paste-from-to-the-widget.patch b/SOURCES/0370-tdf-96317-Add-API-for-copy-paste-from-to-the-widget.patch new file mode 100644 index 0000000..57ccd78 --- /dev/null +++ b/SOURCES/0370-tdf-96317-Add-API-for-copy-paste-from-to-the-widget.patch @@ -0,0 +1,152 @@ +From 3014df80526ebd05cd12707363db42e552f17686 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 9 Dec 2015 21:45:21 +0530 +Subject: [PATCH 370/398] tdf#96317: Add API for copy/paste from/to the widget + +Change-Id: Iac869ddb65cbdd2227f96d047d83159ca7819f11 +Reviewed-on: https://gerrit.libreoffice.org/20534 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit 7d7fad258dfde500c5ee99b5f1691172724383bd) +(cherry picked from commit 9c01ac05618875e812c9f6a18edf5cc6a7909b5e) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 29 +++++++++++++++++++ + .../qa/gtktiledviewer/gtktiledviewer.cxx | 8 ++---- + libreofficekit/source/gtk/lokdocview.cxx | 33 +++++++++++++++++++++- + 3 files changed, 64 insertions(+), 6 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 1b03e4633547..903a74256ffa 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -235,6 +235,35 @@ void lok_doc_view_highlight_all (LOKDocView* + const gchar* pText); + + /** ++ * lok_doc_view_copy_selection: ++ * @pDocView: The #LOKDocView instance ++ * @pMimeType: suggests the return format, for example text/plain;charset=utf-8 ++ * @pUsedMimeType: (out): output parameter to inform about the determined format ++ * (suggested or plain text). ++ * ++ * Returns: Selected text. The caller must free the returned buffer after use. ++ */ ++gchar* lok_doc_view_copy_selection (LOKDocView* pDocView, ++ const gchar* pMimeType, ++ gchar** pUsedMimeType); ++ ++/** ++ * lok_doc_view_paste: ++ * @pDocView: The #LOKDocView instance ++ * @pMimeType: format of pData, for example text/plain;charset=utf-8 ++ * @pData: the data to be pasted ++ * @nSize: length of data to be pasted ++ * ++ * Pastes the content at the current cursor position ++ * ++ * Returns: if pData was pasted successfully. ++ */ ++gboolean lok_doc_view_paste (LOKDocView* pDocView, ++ const gchar* pMimeType, ++ const gchar* pData, ++ gsize nSize); ++ ++/** + * lok_doc_view_pixel_to_twip: + * @pDocView: The #LOKDocView instance + * @fInput: The value in pixels to convert to twips +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 2416e1c6dbcf..d064c4ce3e47 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -548,9 +548,8 @@ static void doCopy(GtkWidget* pButton, gpointer /*pItem*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pButton); + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); +- LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); + char* pUsedFormat = nullptr; +- char* pSelection = pDocument->pClass->getTextSelection(pDocument, "text/html", &pUsedFormat); ++ char* pSelection = lok_doc_view_copy_selection(pLOKDocView, "text/html", &pUsedFormat); + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(rWindow.m_pDocView), GDK_SELECTION_CLIPBOARD); + std::string aUsedFormat(pUsedFormat); +@@ -566,7 +565,6 @@ static void doPaste(GtkWidget* pButton, gpointer /*pItem*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pButton); + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); +- LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pLOKDocView); + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(rWindow.m_pDocView), GDK_SELECTION_CLIPBOARD); + +@@ -590,7 +588,7 @@ static void doPaste(GtkWidget* pButton, gpointer /*pItem*/) + GtkSelectionData* pSelectionData = gtk_clipboard_wait_for_contents(pClipboard, *oTarget); + gint nLength; + const guchar* pData = gtk_selection_data_get_data_with_length(pSelectionData, &nLength); +- bool bSuccess = pDocument->pClass->paste(pDocument, "text/html", reinterpret_cast(pData), nLength); ++ bool bSuccess = lok_doc_view_paste(pLOKDocView, "text/html", reinterpret_cast(pData), nLength); + gtk_selection_data_free(pSelectionData); + if (bSuccess) + return; +@@ -598,7 +596,7 @@ static void doPaste(GtkWidget* pButton, gpointer /*pItem*/) + + gchar* pText = gtk_clipboard_wait_for_text(pClipboard); + if (pText) +- pDocument->pClass->paste(pDocument, "text/plain;charset=utf-8", pText, strlen(pText)); ++ lok_doc_view_paste(pLOKDocView, "text/plain;charset=utf-8", pText, strlen(pText)); + } + + /// Click handler for the search next button. +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 34823437e6ad..99ad819f6e5c 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -344,7 +344,7 @@ doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highligh + cairo_region_get_rectangle(cairoVisRegion, 0, &cairoVisRect); + x = pixelToTwip (cairoVisRect.x, priv->m_fZoom); + y = pixelToTwip (cairoVisRect.y, priv->m_fZoom); +- ++ + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/type", '/'), "string"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/value", '/'), pText); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.Backward/type", '/'), "boolean"); +@@ -2667,6 +2667,37 @@ lok_doc_view_highlight_all (LOKDocView* pDocView, + doSearch(pDocView, pText, false, true); + } + ++SAL_DLLPUBLIC_EXPORT gchar* ++lok_doc_view_copy_selection (LOKDocView* pDocView, ++ const gchar* pMimeType, ++ gchar** pUsedMimeType) ++{ ++ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pDocView); ++ return pDocument->pClass->getTextSelection(pDocument, pMimeType, pUsedMimeType); ++} ++ ++SAL_DLLPUBLIC_EXPORT gboolean ++lok_doc_view_paste (LOKDocView* pDocView, ++ const gchar* pMimeType, ++ const gchar* pData, ++ gsize nSize) ++{ ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ LibreOfficeKitDocument* pDocument = priv->m_pDocument; ++ gboolean ret = 0; ++ ++ if (!priv->m_bEdit) ++ { ++ g_info ("ignoring paste in view-only mode"); ++ return ret; ++ } ++ ++ if (pData) ++ ret = pDocument->pClass->paste(pDocument, pMimeType, pData, nSize); ++ ++ return ret; ++} ++ + SAL_DLLPUBLIC_EXPORT float + lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + { +-- +2.12.0 + diff --git a/SOURCES/0371-tdf-96384-Add-a-new-signal-text-selection-to-lokdocv.patch b/SOURCES/0371-tdf-96384-Add-a-new-signal-text-selection-to-lokdocv.patch new file mode 100644 index 0000000..dc68c43 --- /dev/null +++ b/SOURCES/0371-tdf-96384-Add-a-new-signal-text-selection-to-lokdocv.patch @@ -0,0 +1,76 @@ +From 8d11e5ab0f7d7fb882086a626c69bfb218c9ab3e Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 10 Dec 2015 21:10:16 +0530 +Subject: [PATCH 371/398] tdf#96384: Add a new signal 'text-selection' to + lokdocview + +To help client know when the user has selected a non-null text. + +Change-Id: Ie939612fc5f38e2e50e9ad9792e04e89ae918886 +Reviewed-on: https://gerrit.libreoffice.org/20621 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit ea5c99428f56e1d3a3e782505aa2f56f905038a4) +Signed-off-by: David Tardon +(cherry picked from commit 3f13961c45ea9a6f90c0bc268a2274634d9b8033) +--- + libreofficekit/source/gtk/lokdocview.cxx | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 99ad819f6e5c..012c75f29e1b 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -186,6 +186,7 @@ enum + SEARCH_RESULT_COUNT, + COMMAND_RESULT, + FORMULA_CHANGED, ++ TEXT_SELECTION, + + LAST_SIGNAL + }; +@@ -925,8 +926,9 @@ callback (gpointer pData) + case LOK_CALLBACK_TEXT_SELECTION: + { + priv->m_aTextSelectionRectangles = payloadToRectangles(pDocView, pCallback->m_aPayload.c_str()); ++ gboolean bIsTextSelected = !priv->m_aTextSelectionRectangles.empty(); + // In case the selection is empty, then we get no LOK_CALLBACK_TEXT_SELECTION_START/END events. +- if (priv->m_aTextSelectionRectangles.empty()) ++ if (!bIsTextSelected) + { + memset(&priv->m_aTextSelectionStart, 0, sizeof(priv->m_aTextSelectionStart)); + memset(&priv->m_aHandleStartRect, 0, sizeof(priv->m_aHandleStartRect)); +@@ -935,6 +937,8 @@ callback (gpointer pData) + } + else + memset(&priv->m_aHandleMiddleRect, 0, sizeof(priv->m_aHandleMiddleRect)); ++ ++ g_signal_emit(pDocView, doc_view_signals[TEXT_SELECTION], 0, bIsTextSelected); + gtk_widget_queue_draw(GTK_WIDGET(pDocView)); + } + break; +@@ -2380,6 +2384,21 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); ++ ++ /** ++ * LOKDocView::text-selection: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @bIsTextSelected: whether text selected is non-null ++ */ ++ doc_view_signals[TEXT_SELECTION] = ++ g_signal_new("text-selection", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ nullptr, nullptr, ++ g_cclosure_marshal_VOID__BOOLEAN, ++ G_TYPE_NONE, 1, ++ G_TYPE_BOOLEAN); + } + + SAL_DLLPUBLIC_EXPORT GtkWidget* +-- +2.12.0 + diff --git a/SOURCES/0372-tdf-96250-LOK-guard-against-0-pRenderingArguments.patch b/SOURCES/0372-tdf-96250-LOK-guard-against-0-pRenderingArguments.patch new file mode 100644 index 0000000..8115f59 --- /dev/null +++ b/SOURCES/0372-tdf-96250-LOK-guard-against-0-pRenderingArguments.patch @@ -0,0 +1,33 @@ +From 630f041ac5f60195fa4a75f22ad348fba1c14382 Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Wed, 16 Dec 2015 20:04:01 +0100 +Subject: [PATCH 372/398] tdf#96250 LOK: guard against 0 pRenderingArguments + +(cherry picked from commit 032e34d0014d2154feaf97105d2dbe69b290b8c5) + +Change-Id: Ifa39777795ce966662c31c891ffc1b9b1a297b00 +Reviewed-on: https://gerrit.libreoffice.org/20743 +Tested-by: Jenkins +Reviewed-by: David Tardon +(cherry picked from commit e390b5f4f1267071245e452baa8dd63cdb556f1d) +--- + libreofficekit/source/gtk/lokdocview.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 012c75f29e1b..927f4b509bb8 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2451,7 +2451,8 @@ lok_doc_view_open_document (LOKDocView* pDocView, + pLOEvent->m_pPath = pPath; + + priv->m_aDocPath = pPath; +- priv->m_aRenderingArguments = pRenderingArguments; ++ if (pRenderingArguments) ++ priv->m_aRenderingArguments = pRenderingArguments; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); +-- +2.12.0 + diff --git a/SOURCES/0373-lokdocview-Remove-an-easy-FIXME.patch b/SOURCES/0373-lokdocview-Remove-an-easy-FIXME.patch new file mode 100644 index 0000000..0ff41f1 --- /dev/null +++ b/SOURCES/0373-lokdocview-Remove-an-easy-FIXME.patch @@ -0,0 +1,43 @@ +From f921217577611da13e097a34c18e589e09850927 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 13 Dec 2015 10:48:45 +0530 +Subject: [PATCH 373/398] lokdocview: Remove an easy FIXME + +Change-Id: I8305f3eb45330f457089ca0524a0df004410f59c +Reviewed-on: https://gerrit.libreoffice.org/20774 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit 244aad533b0fd714136f4f62b5a07fc136c740f0) +Reviewed-on: https://gerrit.libreoffice.org/21263 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +(cherry picked from commit 2bb2c450a741a539be69494b5308428d07c56adf) +--- + libreofficekit/source/gtk/lokdocview.cxx | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 927f4b509bb8..a3e6b21165d9 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2428,8 +2428,7 @@ lok_doc_view_open_document_finish (LOKDocView* pDocView, GAsyncResult* res, GErr + GTask* task = G_TASK(res); + + g_return_val_if_fail(g_task_is_valid(res, pDocView), false); +- //FIXME: make source_tag work +- //g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, NULL); ++ g_return_val_if_fail(g_task_get_source_tag(task) == lok_doc_view_open_document, false); + g_return_val_if_fail(error == nullptr || *error == nullptr, false); + + return g_task_propagate_boolean(task, error); +@@ -2454,6 +2453,7 @@ lok_doc_view_open_document (LOKDocView* pDocView, + if (pRenderingArguments) + priv->m_aRenderingArguments = pRenderingArguments; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); ++ g_task_set_source_tag(task, reinterpret_cast(lok_doc_view_open_document)); + + g_thread_pool_push(priv->lokThreadPool, g_object_ref(task), &error); + if (error != nullptr) +-- +2.12.0 + diff --git a/SOURCES/0374-lokdocview-Superfluous-_set_zoom-call-on-widget-init.patch b/SOURCES/0374-lokdocview-Superfluous-_set_zoom-call-on-widget-init.patch new file mode 100644 index 0000000..19a4d53 --- /dev/null +++ b/SOURCES/0374-lokdocview-Superfluous-_set_zoom-call-on-widget-init.patch @@ -0,0 +1,46 @@ +From 9d844459f8aed0ef85a7985f48a2460f9d594a59 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Tue, 15 Dec 2015 00:23:46 +0530 +Subject: [PATCH 374/398] lokdocview: Superfluous *_set_zoom() call on widget + initialization + +G_PARAM_CONSTRUCT implies that parameter will be set upon widget +initialization which means calling lok_doc_view_set_zoom() while +document still points to null. + +Change-Id: Ib576ac3b32c2349be2b2df6067ae79a056a03028 +Reviewed-on: https://gerrit.libreoffice.org/20775 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit a2682e4b081a9a8c6814db768e4ee9e5390907ae) +Reviewed-on: https://gerrit.libreoffice.org/21264 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +(cherry picked from commit 0478825ba51d390486bfbecb410bf9aaa3a3ff59) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index a3e6b21165d9..ccc45657626b 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -760,6 +760,7 @@ static gboolean postDocumentLoad(gpointer pData) + nDocumentHeightPixels); + gtk_widget_set_can_focus(GTK_WIDGET(pLOKDocView), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(pLOKDocView)); ++ lok_doc_view_set_zoom(pLOKDocView, 1.0); + + return G_SOURCE_REMOVE; + } +@@ -2141,7 +2142,6 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + "The current zoom level of the content", + 0, 5.0, 1.0, + static_cast(G_PARAM_READWRITE | +- G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS))); + + /** +-- +2.12.0 + diff --git a/SOURCES/0375-lokdocview-Use-GLib-basic-types.patch b/SOURCES/0375-lokdocview-Use-GLib-basic-types.patch new file mode 100644 index 0000000..5a0f6d1 --- /dev/null +++ b/SOURCES/0375-lokdocview-Use-GLib-basic-types.patch @@ -0,0 +1,132 @@ +From 466c0c035a0d03c76c82ad360b350f887c221912 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 17 Dec 2015 20:35:23 +0530 +Subject: [PATCH 375/398] lokdocview: Use GLib basic types + +Change-Id: I07add7b9dcb1dc53d7ed61ff71545489de3be155 +Reviewed-on: https://gerrit.libreoffice.org/20778 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit b902432b431d01634c1f56e4758ec236a999650d) +Reviewed-on: https://gerrit.libreoffice.org/21265 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +(cherry picked from commit 0886f49224064a259ed6615961f420ab7b6fc3ef) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 12 ++++++------ + libreofficekit/source/gtk/lokdocview.cxx | 12 ++++++------ + 2 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 903a74256ffa..c3cba8fe3417 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -118,19 +118,19 @@ void lok_doc_view_set_zoom (LOKDocView* + * + * Returns: The current zoom factor value in float for pDocView + */ +-float lok_doc_view_get_zoom (LOKDocView* pDocView); ++gfloat lok_doc_view_get_zoom (LOKDocView* pDocView); + + /** + * lok_doc_view_get_parts: + * @pDocView: The #LOKDocView instance + */ +-int lok_doc_view_get_parts (LOKDocView* pDocView); ++gint lok_doc_view_get_parts (LOKDocView* pDocView); + + /** + * lok_doc_view_get_part: + * @pDocView: The #LOKDocView instance + */ +-int lok_doc_view_get_part (LOKDocView* pDocView); ++gint lok_doc_view_get_part (LOKDocView* pDocView); + + /** + * lok_doc_view_set_part: +@@ -145,7 +145,7 @@ void lok_doc_view_set_part (LOKDocView* + * @pDocView: The #LOKDocView instance + * @nPart: + */ +-char* lok_doc_view_get_part_name (LOKDocView* pDocView, ++gchar* lok_doc_view_get_part_name (LOKDocView* pDocView, + int nPart); + + /** +@@ -272,7 +272,7 @@ gboolean lok_doc_view_paste (LOKDocView* + * + * Returns: The corresponding value in twips + */ +-float lok_doc_view_pixel_to_twip (LOKDocView* pDocView, ++gfloat lok_doc_view_pixel_to_twip (LOKDocView* pDocView, + float fInput); + + /** +@@ -284,7 +284,7 @@ float lok_doc_view_pixel_to_twip (LOKDocView* + * + * Returns: The corresponding value in pixels + */ +-float lok_doc_view_twip_to_pixel (LOKDocView* pDocView, ++gfloat lok_doc_view_twip_to_pixel (LOKDocView* pDocView, + float fInput); + + G_END_DECLS +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index ccc45657626b..9d7f0740595e 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2507,14 +2507,14 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + g_object_unref(task); + } + +-SAL_DLLPUBLIC_EXPORT float ++SAL_DLLPUBLIC_EXPORT gfloat + lok_doc_view_get_zoom (LOKDocView* pDocView) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); + return priv->m_fZoom; + } + +-SAL_DLLPUBLIC_EXPORT int ++SAL_DLLPUBLIC_EXPORT gint + lok_doc_view_get_parts (LOKDocView* pDocView) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +@@ -2522,7 +2522,7 @@ lok_doc_view_get_parts (LOKDocView* pDocView) + return priv->m_pDocument->pClass->getParts( priv->m_pDocument ); + } + +-SAL_DLLPUBLIC_EXPORT int ++SAL_DLLPUBLIC_EXPORT gint + lok_doc_view_get_part (LOKDocView* pDocView) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +@@ -2550,7 +2550,7 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + g_object_unref(task); + } + +-SAL_DLLPUBLIC_EXPORT char* ++SAL_DLLPUBLIC_EXPORT gchar* + lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +@@ -2718,14 +2718,14 @@ lok_doc_view_paste (LOKDocView* pDocView, + return ret; + } + +-SAL_DLLPUBLIC_EXPORT float ++SAL_DLLPUBLIC_EXPORT gfloat + lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); + return pixelToTwip(fInput, priv->m_fZoom); + } + +-SAL_DLLPUBLIC_EXPORT float ++SAL_DLLPUBLIC_EXPORT gfloat + lok_doc_view_twip_to_pixel (LOKDocView* pDocView, float fInput) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +-- +2.12.0 + diff --git a/SOURCES/0376-lokdocview-Added-some-missing-comments-annotations.patch b/SOURCES/0376-lokdocview-Added-some-missing-comments-annotations.patch new file mode 100644 index 0000000..06924a4 --- /dev/null +++ b/SOURCES/0376-lokdocview-Added-some-missing-comments-annotations.patch @@ -0,0 +1,52 @@ +From 13818ff71142e735c06b92c03c188527dedbac70 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 17 Dec 2015 20:33:06 +0530 +Subject: [PATCH 376/398] lokdocview: Added some missing comments/annotations + +Change-Id: I2f62bae37719ce96677a5ca6ffd93c8edb325a6a +Reviewed-on: https://gerrit.libreoffice.org/20777 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit 9c8c3acffa304e2d85dcbbdb5bf9decc9b255b13) +Reviewed-on: https://gerrit.libreoffice.org/21266 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +(cherry picked from commit 2f5643d7fa1009155e900a89918d5cee3265c137) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index c3cba8fe3417..62d2e7f29247 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -123,12 +123,17 @@ gfloat lok_doc_view_get_zoom (LOKDocView* + /** + * lok_doc_view_get_parts: + * @pDocView: The #LOKDocView instance ++ * ++ * Returns: Part refers to either individual sheets in a Calc, or slides in Impress, ++ * and has no relevance for Writer. + */ + gint lok_doc_view_get_parts (LOKDocView* pDocView); + + /** + * lok_doc_view_get_part: + * @pDocView: The #LOKDocView instance ++ * ++ * Returns: Current part number of the document + */ + gint lok_doc_view_get_part (LOKDocView* pDocView); + +@@ -144,6 +149,8 @@ void lok_doc_view_set_part (LOKDocView* + * lok_doc_view_get_part_name: + * @pDocView: The #LOKDocView instance + * @nPart: ++ * ++ * Returns: Get current part name of loaded document + */ + gchar* lok_doc_view_get_part_name (LOKDocView* pDocView, + int nPart); +-- +2.12.0 + diff --git a/SOURCES/0377-lokdocview-Return-if-no-document-is-set.patch b/SOURCES/0377-lokdocview-Return-if-no-document-is-set.patch new file mode 100644 index 0000000..32f7284 --- /dev/null +++ b/SOURCES/0377-lokdocview-Return-if-no-document-is-set.patch @@ -0,0 +1,199 @@ +From 192a19277531a36bccadde67fbf307eebe60b3ea Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Thu, 17 Dec 2015 21:03:47 +0530 +Subject: [PATCH 377/398] lokdocview: Return if no document is set + +For example, when document has been destroyed using +lok_doc_view_destroy_document() + +Change-Id: I531b85018ffa25bcf88fb101c912b9f11b489a97 +Reviewed-on: https://gerrit.libreoffice.org/20779 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit df4a196b8f1e97d8a45d1d517942e01bd13182e7) +Reviewed-on: https://gerrit.libreoffice.org/21267 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +(cherry picked from commit dd6006be974ce808f276c550d32f1bc01582aaf3) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 10 ++++--- + .../qa/gtktiledviewer/gtktiledviewer.cxx | 3 ++ + libreofficekit/source/gtk/lokdocview.cxx | 35 ++++++++++++++++++++-- + 3 files changed, 42 insertions(+), 6 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 62d2e7f29247..911bbdfa6049 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -125,7 +125,7 @@ gfloat lok_doc_view_get_zoom (LOKDocView* + * @pDocView: The #LOKDocView instance + * + * Returns: Part refers to either individual sheets in a Calc, or slides in Impress, +- * and has no relevance for Writer. ++ * and has no relevance for Writer. Returns -1 if no document is set currently. + */ + gint lok_doc_view_get_parts (LOKDocView* pDocView); + +@@ -133,7 +133,7 @@ gint lok_doc_view_get_parts (LOKDocView* + * lok_doc_view_get_part: + * @pDocView: The #LOKDocView instance + * +- * Returns: Current part number of the document ++ * Returns: Current part number of the document. Returns -1 if no document is set currently. + */ + gint lok_doc_view_get_part (LOKDocView* pDocView); + +@@ -150,7 +150,8 @@ void lok_doc_view_set_part (LOKDocView* + * @pDocView: The #LOKDocView instance + * @nPart: + * +- * Returns: Get current part name of loaded document ++ * Returns: Get current part name of loaded document. Returns null if no ++ * document is set, or document has been destroyed using lok_doc_view_destroy_document. + */ + gchar* lok_doc_view_get_part_name (LOKDocView* pDocView, + int nPart); +@@ -248,7 +249,8 @@ void lok_doc_view_highlight_all (LOKDocView* + * @pUsedMimeType: (out): output parameter to inform about the determined format + * (suggested or plain text). + * +- * Returns: Selected text. The caller must free the returned buffer after use. ++ * Returns: Selected text. The caller must free the returned buffer after ++ * use. Returns null if no document is set. + */ + gchar* lok_doc_view_copy_selection (LOKDocView* pDocView, + const gchar* pMimeType, +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index d064c4ce3e47..e867e1b239a7 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -549,7 +549,10 @@ static void doCopy(GtkWidget* pButton, gpointer /*pItem*/) + TiledWindow& rWindow = lcl_getTiledWindow(pButton); + LOKDocView* pLOKDocView = LOK_DOC_VIEW(rWindow.m_pDocView); + char* pUsedFormat = nullptr; ++ // TODO: Should check `text-selection` signal before trying to copy + char* pSelection = lok_doc_view_copy_selection(pLOKDocView, "text/html", &pUsedFormat); ++ if (!pSelection) ++ return; + + GtkClipboard* pClipboard = gtk_clipboard_get_for_display(gtk_widget_get_display(rWindow.m_pDocView), GDK_SELECTION_CLIPBOARD); + std::string aUsedFormat(pUsedFormat); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 9d7f0740595e..858f08b66890 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -342,6 +342,9 @@ doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highligh + cairo_rectangle_int_t cairoVisRect; + int x, y; + ++ if (!priv->m_pDocument) ++ return; ++ + cairo_region_get_rectangle(cairoVisRegion, 0, &cairoVisRect); + x = pixelToTwip (cairoVisRect.x, priv->m_fZoom); + y = pixelToTwip (cairoVisRect.y, priv->m_fZoom); +@@ -1630,8 +1633,6 @@ setClientZoomInThread(gpointer data) + LOKDocViewPrivate& priv = getPrivate(pDocView); + LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); + +- if (!priv->m_pDocument) +- return; + priv->m_pDocument->pClass->setClientZoom(priv->m_pDocument, + pLOEvent->m_nTilePixelWidth, + pLOEvent->m_nTilePixelHeight, +@@ -2518,6 +2519,9 @@ SAL_DLLPUBLIC_EXPORT gint + lok_doc_view_get_parts (LOKDocView* pDocView) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ if (!priv->m_pDocument) ++ return -1; ++ + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getParts( priv->m_pDocument ); + } +@@ -2526,6 +2530,9 @@ SAL_DLLPUBLIC_EXPORT gint + lok_doc_view_get_part (LOKDocView* pDocView) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ if (!priv->m_pDocument) ++ return -1; ++ + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getPart( priv->m_pDocument ); + } +@@ -2538,6 +2545,9 @@ lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); + GError* error = nullptr; + ++ if (!priv->m_pDocument) ++ return; ++ + pLOEvent->m_nPart = nPart; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +@@ -2554,6 +2564,10 @@ SAL_DLLPUBLIC_EXPORT gchar* + lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ ++ if (!priv->m_pDocument) ++ return nullptr; ++ + priv->m_pDocument->pClass->setView(priv->m_pDocument, priv->m_nViewId); + return priv->m_pDocument->pClass->getPartName( priv->m_pDocument, nPart ); + } +@@ -2566,6 +2580,10 @@ lok_doc_view_set_partmode(LOKDocView* pDocView, + GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); + GError* error = nullptr; ++ ++ if (!priv->m_pDocument) ++ return; ++ + pLOEvent->m_nPartMode = nPartMode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +@@ -2632,6 +2650,10 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); + GError* error = nullptr; ++ ++ if (!priv->m_pDocument) ++ return; ++ + pLOEvent->m_bEdit = bEdit; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +@@ -2658,6 +2680,10 @@ lok_doc_view_post_command (LOKDocView* pDocView, + gboolean bNotifyWhenFinished) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ ++ if (!priv->m_pDocument) ++ return; ++ + if (priv->m_bEdit) + LOKPostCommand(pDocView, pCommand, pArguments, bNotifyWhenFinished); + else +@@ -2693,6 +2719,8 @@ lok_doc_view_copy_selection (LOKDocView* pDocView, + gchar** pUsedMimeType) + { + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(pDocView); ++ if (!pDocument) ++ return nullptr; + return pDocument->pClass->getTextSelection(pDocument, pMimeType, pUsedMimeType); + } + +@@ -2706,6 +2734,9 @@ lok_doc_view_paste (LOKDocView* pDocView, + LibreOfficeKitDocument* pDocument = priv->m_pDocument; + gboolean ret = 0; + ++ if (!pDocument) ++ return false; ++ + if (!priv->m_bEdit) + { + g_info ("ignoring paste in view-only mode"); +-- +2.12.0 + diff --git a/SOURCES/0378-coverity-1343631-Resource-leak.patch b/SOURCES/0378-coverity-1343631-Resource-leak.patch new file mode 100644 index 0000000..2b200a6 --- /dev/null +++ b/SOURCES/0378-coverity-1343631-Resource-leak.patch @@ -0,0 +1,39 @@ +From 3ebf54f0b940967c5c8de7f6d9df8c0b09a4bf21 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 19 Dec 2015 15:08:01 +0000 +Subject: [PATCH 378/398] coverity#1343631 Resource leak + +Change-Id: Ic5d7c88ae4080c2e103fb691c2e326a9e239aa12 +(cherry picked from commit 169298fa73d2c5429d1960db6049a4ed15653b4f) +Reviewed-on: https://gerrit.libreoffice.org/21268 +Reviewed-by: David Tardon +Tested-by: Jenkins +(cherry picked from commit 195866b16f044bc792526145b739602166ca7276) +--- + libreofficekit/source/gtk/lokdocview.cxx | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 858f08b66890..a5fc4e34439e 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2647,13 +2647,13 @@ lok_doc_view_set_edit(LOKDocView* pDocView, + gboolean bEdit) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ if (!priv->m_pDocument) ++ return; ++ + GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_EDIT); + GError* error = nullptr; + +- if (!priv->m_pDocument) +- return; +- + pLOEvent->m_bEdit = bEdit; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +-- +2.12.0 + diff --git a/SOURCES/0379-coverity-1343632-Resource-leak.patch b/SOURCES/0379-coverity-1343632-Resource-leak.patch new file mode 100644 index 0000000..fdf48db --- /dev/null +++ b/SOURCES/0379-coverity-1343632-Resource-leak.patch @@ -0,0 +1,39 @@ +From 8aacde4431b46b6ecca8aa59cdfa81fc3ef76e04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 19 Dec 2015 15:09:10 +0000 +Subject: [PATCH 379/398] coverity#1343632 Resource leak + +Change-Id: I79bf35a4c1a2f0463abc202f6c2b104ffdd5139c +(cherry picked from commit 5b05a3fa2d6873c1046a959c545db133b1974e2c) +Reviewed-on: https://gerrit.libreoffice.org/21269 +Reviewed-by: David Tardon +Tested-by: Jenkins +(cherry picked from commit 699b5e361d1f75b1414a351dfe4d05d88e2b49e2) +--- + libreofficekit/source/gtk/lokdocview.cxx | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index a5fc4e34439e..ec3eb4b9e3ba 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2577,13 +2577,13 @@ lok_doc_view_set_partmode(LOKDocView* pDocView, + int nPartMode) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ if (!priv->m_pDocument) ++ return; ++ + GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PARTMODE); + GError* error = nullptr; + +- if (!priv->m_pDocument) +- return; +- + pLOEvent->m_nPartMode = nPartMode; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +-- +2.12.0 + diff --git a/SOURCES/0380-coverity-1343633-Resource-leak.patch b/SOURCES/0380-coverity-1343633-Resource-leak.patch new file mode 100644 index 0000000..8ea1e5a --- /dev/null +++ b/SOURCES/0380-coverity-1343633-Resource-leak.patch @@ -0,0 +1,75 @@ +From 9b6a3417e3a6190f356e9f608346d5ee07bbd19d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 19 Dec 2015 15:11:03 +0000 +Subject: [PATCH 380/398] coverity#1343633 Resource leak + +Change-Id: I2384091557c2a3b061e2c60118309f35b65b45d6 +(cherry picked from commit 746da6b7fb3829e1ca23a4b8dfec6c502bac681c) +Reviewed-on: https://gerrit.libreoffice.org/21270 +Reviewed-by: David Tardon +Tested-by: Jenkins +(cherry picked from commit af32996eb55008b9787516a280a237b61a05ca05) +--- + libreofficekit/source/gtk/lokdocview.cxx | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index ec3eb4b9e3ba..4d2842005f37 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -335,6 +335,9 @@ static void + doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highlightAll) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ if (!priv->m_pDocument) ++ return; ++ + boost::property_tree::ptree aTree; + GtkWidget* drawingWidget = GTK_WIDGET(pDocView); + GdkWindow* drawingWindow = gtk_widget_get_window(drawingWidget); +@@ -342,9 +345,6 @@ doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highligh + cairo_rectangle_int_t cairoVisRect; + int x, y; + +- if (!priv->m_pDocument) +- return; +- + cairo_region_get_rectangle(cairoVisRegion, 0, &cairoVisRect); + x = pixelToTwip (cairoVisRect.x, priv->m_fZoom); + y = pixelToTwip (cairoVisRect.y, priv->m_fZoom); +@@ -2541,13 +2541,13 @@ SAL_DLLPUBLIC_EXPORT void + lok_doc_view_set_part (LOKDocView* pDocView, int nPart) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ if (!priv->m_pDocument) ++ return; ++ + GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_PART); + GError* error = nullptr; + +- if (!priv->m_pDocument) +- return; +- + pLOEvent->m_nPart = nPart; + g_task_set_task_data(task, pLOEvent, LOEvent::destroy); + +@@ -2564,7 +2564,6 @@ SAL_DLLPUBLIC_EXPORT gchar* + lok_doc_view_get_part_name (LOKDocView* pDocView, int nPart) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- + if (!priv->m_pDocument) + return nullptr; + +@@ -2680,7 +2679,6 @@ lok_doc_view_post_command (LOKDocView* pDocView, + gboolean bNotifyWhenFinished) + { + LOKDocViewPrivate& priv = getPrivate(pDocView); +- + if (!priv->m_pDocument) + return; + +-- +2.12.0 + diff --git a/SOURCES/0381-coverity-1315075-Uninitialized-scalar-field.patch b/SOURCES/0381-coverity-1315075-Uninitialized-scalar-field.patch new file mode 100644 index 0000000..fb83cad --- /dev/null +++ b/SOURCES/0381-coverity-1315075-Uninitialized-scalar-field.patch @@ -0,0 +1,33 @@ +From eb95d95b7554c8e1417b96b030d2880dd3e61483 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 21 Dec 2015 09:11:16 +0000 +Subject: [PATCH 381/398] coverity#1315075 Uninitialized scalar field + +Change-Id: I003839589354f02f8064b6a6af6174d2793b9b3a +(cherry picked from commit 92305c3c41d120b868e0821221a583697868ad6d) +Reviewed-on: https://gerrit.libreoffice.org/21271 +Reviewed-by: David Tardon +Tested-by: Jenkins +(cherry picked from commit d753e9e41283ca1e0d77001ec1174426451dd7fe) +--- + libreofficekit/source/gtk/tilebuffer.hxx | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx +index 244ca882d051..90d95891918b 100644 +--- a/libreofficekit/source/gtk/tilebuffer.hxx ++++ b/libreofficekit/source/gtk/tilebuffer.hxx +@@ -268,6 +268,10 @@ struct LOEvent + , m_nSetGraphicSelectionType(0) + , m_nSetGraphicSelectionX(0) + , m_nSetGraphicSelectionY(0) ++ , m_nTilePixelWidth(0) ++ , m_nTilePixelHeight(0) ++ , m_nTileTwipWidth(0) ++ , m_nTileTwipHeight(0) + { + } + +-- +2.12.0 + diff --git a/SOURCES/0382-lokdocview-Use-an-array-to-install-properties.patch b/SOURCES/0382-lokdocview-Use-an-array-to-install-properties.patch new file mode 100644 index 0000000..32ace51 --- /dev/null +++ b/SOURCES/0382-lokdocview-Use-an-array-to-install-properties.patch @@ -0,0 +1,308 @@ +From 5a4d9a54a05efee6cb004b41207e53b6eadbd1a8 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 18 Dec 2015 21:51:23 +0530 +Subject: [PATCH 382/398] lokdocview: Use an array to install properties + +This way we can directly reference any property by pointers to +GParamSpec stored in a static array, rather than looking for +property using property name. The former is a faster approach. + +This will come in handy for functions, such as, g_object_notify +which needs to access properties to notify the object of any +property change in a faster way. + +Change-Id: Ic4087bff3bdb63a3e8853d158c7af688e5e67811 +Reviewed-on: https://gerrit.libreoffice.org/20797 +Tested-by: Jenkins +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit 81f31f5151b54899ac5461c9c7c4021cdf31a9a6) +Reviewed-on: https://gerrit.libreoffice.org/21272 +Reviewed-by: Pranav Kant +(cherry picked from commit 09c73ad5b1462161b855bf3d43a3d86a3ee28659) +--- + libreofficekit/source/gtk/lokdocview.cxx | 187 +++++++++++++++---------------- + 1 file changed, 90 insertions(+), 97 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 4d2842005f37..07e5f993b79b 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -206,10 +206,13 @@ enum + PROP_DOC_WIDTH, + PROP_DOC_HEIGHT, + PROP_CAN_ZOOM_IN, +- PROP_CAN_ZOOM_OUT ++ PROP_CAN_ZOOM_OUT, ++ ++ PROP_LAST + }; + + static guint doc_view_signals[LAST_SIGNAL] = { 0 }; ++static GParamSpec *properties[PROP_LAST] = { nullptr }; + + static void lok_doc_view_initable_iface_init (GInitableIface *iface); + static void callbackWorker (int nType, const char* pPayload, void* pData); +@@ -2046,15 +2049,14 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * + * The absolute path of the LibreOffice install. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_LO_PATH, +- g_param_spec_string("lopath", +- "LO Path", +- "LibreOffice Install Path", +- nullptr, +- static_cast(G_PARAM_READWRITE | +- G_PARAM_CONSTRUCT_ONLY | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_LO_PATH] = ++ g_param_spec_string("lopath", ++ "LO Path", ++ "LibreOffice Install Path", ++ nullptr, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:lopointer: +@@ -2062,28 +2064,26 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * A LibreOfficeKit* in case lok_init() is already called + * previously. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_LO_POINTER, +- g_param_spec_pointer("lopointer", +- "LO Pointer", +- "A LibreOfficeKit* from lok_init()", +- static_cast(G_PARAM_READWRITE | +- G_PARAM_CONSTRUCT_ONLY | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_LO_POINTER] = ++ g_param_spec_pointer("lopointer", ++ "LO Pointer", ++ "A LibreOfficeKit* from lok_init()", ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:docpath: + * + * The path of the document that is currently being viewed. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_DOC_PATH, +- g_param_spec_string("docpath", +- "Document Path", +- "The URI of the document to open", +- nullptr, +- static_cast(G_PARAM_READWRITE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_DOC_PATH] = ++ g_param_spec_string("docpath", ++ "Document Path", ++ "The URI of the document to open", ++ nullptr, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:docpointer: +@@ -2091,27 +2091,25 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * A LibreOfficeKitDocument* in case documentLoad() is already called + * previously. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_DOC_POINTER, +- g_param_spec_pointer("docpointer", +- "Document Pointer", +- "A LibreOfficeKitDocument* from documentLoad()", +- static_cast(G_PARAM_READWRITE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_DOC_POINTER] = ++ g_param_spec_pointer("docpointer", ++ "Document Pointer", ++ "A LibreOfficeKitDocument* from documentLoad()", ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:editable: + * + * Whether the document loaded inside of #LOKDocView is editable or not. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_EDITABLE, +- g_param_spec_boolean("editable", +- "Editable", +- "Whether the content is in edit mode or not", +- FALSE, +- static_cast(G_PARAM_READWRITE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_EDITABLE] = ++ g_param_spec_boolean("editable", ++ "Editable", ++ "Whether the content is in edit mode or not", ++ FALSE, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:load-progress: +@@ -2121,14 +2119,13 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * very accurate progress indicator, and its value might reset it couple of + * times to 0 and start again. You should not rely on its numbers. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_LOAD_PROGRESS, +- g_param_spec_double("load-progress", +- "Estimated Load Progress", +- "Shows the progress of the document load operation", +- 0.0, 1.0, 0.0, +- static_cast(G_PARAM_READABLE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_LOAD_PROGRESS] = ++ g_param_spec_double("load-progress", ++ "Estimated Load Progress", ++ "Shows the progress of the document load operation", ++ 0.0, 1.0, 0.0, ++ static_cast(G_PARAM_READABLE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:zoom-level: +@@ -2136,14 +2133,13 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * The current zoom level of the document loaded inside #LOKDocView. The + * default value is 1.0. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_ZOOM, +- g_param_spec_float("zoom-level", +- "Zoom Level", +- "The current zoom level of the content", +- 0, 5.0, 1.0, +- static_cast(G_PARAM_READWRITE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_ZOOM] = ++ g_param_spec_float("zoom-level", ++ "Zoom Level", ++ "The current zoom level of the content", ++ 0, 5.0, 1.0, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:is-loading: +@@ -2151,70 +2147,67 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + * Whether the requested document is being loaded or not. %TRUE if it is + * being loaded, otherwise %FALSE. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_IS_LOADING, +- g_param_spec_boolean("is-loading", +- "Is Loading", +- "Whether the view is loading a document", +- FALSE, +- static_cast(G_PARAM_READABLE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_IS_LOADING] = ++ g_param_spec_boolean("is-loading", ++ "Is Loading", ++ "Whether the view is loading a document", ++ FALSE, ++ static_cast(G_PARAM_READABLE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:doc-width: + * + * The width of the currently loaded document in #LOKDocView in twips. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_DOC_WIDTH, +- g_param_spec_long("doc-width", +- "Document Width", +- "Width of the document in twips", +- 0, G_MAXLONG, 0, +- static_cast(G_PARAM_READWRITE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_DOC_WIDTH] = ++ g_param_spec_long("doc-width", ++ "Document Width", ++ "Width of the document in twips", ++ 0, G_MAXLONG, 0, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:doc-height: + * + * The height of the currently loaded document in #LOKDocView in twips. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_DOC_HEIGHT, +- g_param_spec_long("doc-height", +- "Document Height", +- "Height of the document in twips", +- 0, G_MAXLONG, 0, +- static_cast(G_PARAM_READWRITE | +- G_PARAM_STATIC_STRINGS))); ++ properties[PROP_DOC_HEIGHT] = ++ g_param_spec_long("doc-height", ++ "Document Height", ++ "Height of the document in twips", ++ 0, G_MAXLONG, 0, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:can-zoom-in: + * + * It tells whether the view can further be zoomed in or not. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_CAN_ZOOM_IN, +- g_param_spec_boolean("can-zoom-in", +- "Can Zoom In", +- "Whether the view can be zoomed in further", +- TRUE, +- static_cast(G_PARAM_READABLE +- | G_PARAM_STATIC_STRINGS))); ++ properties[PROP_CAN_ZOOM_IN] = ++ g_param_spec_boolean("can-zoom-in", ++ "Can Zoom In", ++ "Whether the view can be zoomed in further", ++ TRUE, ++ static_cast(G_PARAM_READABLE ++ | G_PARAM_STATIC_STRINGS)); + + /** + * LOKDocView:can-zoom-out: + * + * It tells whether the view can further be zoomed out or not. + */ +- g_object_class_install_property (pGObjectClass, +- PROP_CAN_ZOOM_OUT, +- g_param_spec_boolean("can-zoom-out", +- "Can Zoom Out", +- "Whether the view can be zoomed out further", +- TRUE, +- static_cast(G_PARAM_READABLE +- | G_PARAM_STATIC_STRINGS))); ++ properties[PROP_CAN_ZOOM_OUT] = ++ g_param_spec_boolean("can-zoom-out", ++ "Can Zoom Out", ++ "Whether the view can be zoomed out further", ++ TRUE, ++ static_cast(G_PARAM_READABLE ++ | G_PARAM_STATIC_STRINGS)); ++ ++ g_object_class_install_properties(pGObjectClass, PROP_LAST, properties); + + /** + * LOKDocView::load-changed: +-- +2.12.0 + diff --git a/SOURCES/0383-tdf-96514-Emits-a-notify-signal-when-zoom-changes.patch b/SOURCES/0383-tdf-96514-Emits-a-notify-signal-when-zoom-changes.patch new file mode 100644 index 0000000..513542e --- /dev/null +++ b/SOURCES/0383-tdf-96514-Emits-a-notify-signal-when-zoom-changes.patch @@ -0,0 +1,34 @@ +From 59c312354b33f115f359900ba5db85b61792f4ea Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 18 Dec 2015 21:58:26 +0530 +Subject: [PATCH 383/398] tdf#96514: Emits a 'notify' signal when zoom changes + +Change-Id: I5f55e4cce26096afcae3ad3711efa37757aada39 +Reviewed-on: https://gerrit.libreoffice.org/20798 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit 398ef76d5dc3ec1ed22fa1d9fd9151b61cce54e2) +Reviewed-on: https://gerrit.libreoffice.org/21273 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +(cherry picked from commit 1fb882cb1e2eedbef688cf2b3a2ca9322486c9cb) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 07e5f993b79b..5cf44e98c796 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2483,6 +2483,8 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + nDocumentWidthPixels, + nDocumentHeightPixels); + ++ g_object_notify_by_pspec(G_OBJECT(pDocView), properties[PROP_ZOOM]); ++ + // Update the client's view size + GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_CLIENT_ZOOM); +-- +2.12.0 + diff --git a/SOURCES/0384-lokdocview-Use-shared_ptr-to-fix-a-possible-memory-l.patch b/SOURCES/0384-lokdocview-Use-shared_ptr-to-fix-a-possible-memory-l.patch new file mode 100644 index 0000000..98fbb45 --- /dev/null +++ b/SOURCES/0384-lokdocview-Use-shared_ptr-to-fix-a-possible-memory-l.patch @@ -0,0 +1,55 @@ +From 480d4e70b53487da92a4add51395b4068f2e73c0 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 10 Jan 2016 22:50:46 +0530 +Subject: [PATCH 384/398] lokdocview: Use shared_ptr to fix a possible memory + leak + +Possible because boost::property_tree can throw an exception. + +Change-Id: I68394ce3b30d448d40d8e22555bafdff1ffa6092 +Reviewed-on: https://gerrit.libreoffice.org/21309 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit 02b49890d51ec463d32846f1108344159664a9eb) +Reviewed-on: https://gerrit.libreoffice.org/21345 +Tested-by: Jenkins +Reviewed-by: Michael Stahl +(cherry picked from commit 1673606de9a520e615e1a32da94f28d55ebaea20) +--- + libreofficekit/source/gtk/lokdocview.cxx | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 5cf44e98c796..b6febbd9fe66 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -344,13 +345,12 @@ doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highligh + boost::property_tree::ptree aTree; + GtkWidget* drawingWidget = GTK_WIDGET(pDocView); + GdkWindow* drawingWindow = gtk_widget_get_window(drawingWidget); +- cairo_region_t* cairoVisRegion = gdk_window_get_visible_region(drawingWindow); ++ std::shared_ptr cairoVisRegion( gdk_window_get_visible_region(drawingWindow), ++ cairo_region_destroy); + cairo_rectangle_int_t cairoVisRect; +- int x, y; +- +- cairo_region_get_rectangle(cairoVisRegion, 0, &cairoVisRect); +- x = pixelToTwip (cairoVisRect.x, priv->m_fZoom); +- y = pixelToTwip (cairoVisRect.y, priv->m_fZoom); ++ cairo_region_get_rectangle(cairoVisRegion.get(), 0, &cairoVisRect); ++ int x = pixelToTwip (cairoVisRect.x, priv->m_fZoom); ++ int y = pixelToTwip (cairoVisRect.y, priv->m_fZoom); + + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/type", '/'), "string"); + aTree.put(boost::property_tree::ptree::path_type("SearchItem.SearchString/value", '/'), pText); +-- +2.12.0 + diff --git a/SOURCES/0385-tdf-96421-Return-if-no-window-is-realized.patch b/SOURCES/0385-tdf-96421-Return-if-no-window-is-realized.patch new file mode 100644 index 0000000..1ed32d7 --- /dev/null +++ b/SOURCES/0385-tdf-96421-Return-if-no-window-is-realized.patch @@ -0,0 +1,33 @@ +From c86a367308b61437e45d2763fb2b0499767cb9bd Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Fri, 18 Dec 2015 22:42:53 +0530 +Subject: [PATCH 385/398] tdf#96421: Return if no window is realized + +Change-Id: I13de7e6eae4e73932e8441ba2e2ad3e4ff888f41 +Reviewed-on: https://gerrit.libreoffice.org/20799 +Tested-by: Jenkins +Reviewed-by: David Tardon +(cherry picked from commit 4200a678fb54f0fa5d2f0c26c655252f9267a527) +Reviewed-on: https://gerrit.libreoffice.org/21346 +Reviewed-by: Michael Stahl +(cherry picked from commit 0056a61e17e0d8faf314431c701c00c3b6c8d5f9) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index b6febbd9fe66..5cfc22d611d7 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -345,6 +345,8 @@ doSearch(LOKDocView* pDocView, const char* pText, bool bBackwards, bool highligh + boost::property_tree::ptree aTree; + GtkWidget* drawingWidget = GTK_WIDGET(pDocView); + GdkWindow* drawingWindow = gtk_widget_get_window(drawingWidget); ++ if (!drawingWindow) ++ return; + std::shared_ptr cairoVisRegion( gdk_window_get_visible_region(drawingWindow), + cairo_region_destroy); + cairo_rectangle_int_t cairoVisRect; +-- +2.12.0 + diff --git a/SOURCES/0386-lokdocview-Fix-WARNING-when-creating-an-error.patch b/SOURCES/0386-lokdocview-Fix-WARNING-when-creating-an-error.patch new file mode 100644 index 0000000..bf995d1 --- /dev/null +++ b/SOURCES/0386-lokdocview-Fix-WARNING-when-creating-an-error.patch @@ -0,0 +1,39 @@ +From 6b4439ee8561429eee14e60c62788df63c318f67 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Fri, 8 Jan 2016 18:06:18 +0100 +Subject: [PATCH 386/398] lokdocview: Fix WARNING when creating an error + +A GError needs a valid GQuark as the domain. Passing 0 leads to: + GLib-WARNING **: (gerror.c:408):g_error_new_valist: runtime check + failed: (domain != 0) + +Change-Id: I2f252eaa83a1519b5d16c7ba22c8f593732807ca +Reviewed-on: https://gerrit.libreoffice.org/21261 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +Reviewed-by: jan iversen +(cherry picked from commit 3ba1b60c97b342c13593d37ccf2b97a919808dfc) +Reviewed-on: https://gerrit.libreoffice.org/21384 +Reviewed-by: David Tardon +Tested-by: David Tardon +(cherry picked from commit 9f6cb113a9a6a55de34bf2fab6da757275ead6ea) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 5cfc22d611d7..9774acacad83 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -1681,7 +1681,7 @@ openDocumentInThread (gpointer data) + if ( !priv->m_pDocument ) + { + char *pError = priv->m_pOffice->pClass->getError( priv->m_pOffice ); +- g_task_return_new_error(task, 0, 0, "%s", pError); ++ g_task_return_new_error(task, g_quark_from_static_string ("LOK error"), 0, "%s", pError); + } + else + { +-- +2.12.0 + diff --git a/SOURCES/0387-tdf-96513-Limit-LOKDocView-s-zoom-in-0.25-5.0.patch b/SOURCES/0387-tdf-96513-Limit-LOKDocView-s-zoom-in-0.25-5.0.patch new file mode 100644 index 0000000..2ab2e14 --- /dev/null +++ b/SOURCES/0387-tdf-96513-Limit-LOKDocView-s-zoom-in-0.25-5.0.patch @@ -0,0 +1,97 @@ +From b94feb218000f0c0a1e156cb868531295763b68d Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sat, 19 Dec 2015 20:36:47 +0530 +Subject: [PATCH 387/398] tdf#96513: Limit LOKDocView's zoom in [0.25, 5.0] + +Change-Id: Ibee485909dca1ea4a3774fca7a840afbf2d9883c +Reviewed-on: https://gerrit.libreoffice.org/20819 +Tested-by: Jenkins +Reviewed-by: David Tardon +(cherry picked from commit ba539fa91f9c3316107dcdf4a95718a49335d92e) +Reviewed-on: https://gerrit.libreoffice.org/21347 +Reviewed-by: Christian Lohmaier +(cherry picked from commit bd85600aa4a81fba19c98e0a1c2d5ccdcb8fb3fc) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 4 +++- + libreofficekit/source/gtk/lokdocview.cxx | 29 +++++++++++++++++++++++++++-- + 2 files changed, 30 insertions(+), 3 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 911bbdfa6049..e06d154f772e 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -107,7 +107,9 @@ LibreOfficeKitDocument* lok_doc_view_get_document (LOKDocView* + * @pDocView: The #LOKDocView instance + * @fZoom: The new zoom level that pDocView must set it into. + * +- * Sets the new zoom level for the widget. ++ * Sets the new zoom level for the widget. Does nothing if fZoom is equal to ++ * existing zoom level. Values outside the range [0.25, 5.0] are clamped into ++ * the nearest allowed value in the interval. + */ + void lok_doc_view_set_zoom (LOKDocView* pDocView, + float fZoom); +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 9774acacad83..d2c66b951b7d 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -39,6 +39,10 @@ + #define CURSOR_HANDLE_DIR "android/experimental/LOAndroid3/res/drawable/" + // Number of handles around a graphic selection. + #define GRAPHIC_HANDLE_COUNT 8 ++// Maximum Zoom allowed ++#define MAX_ZOOM 5.0f ++// Minimum Zoom allowed ++#define MIN_ZOOM 0.25f + + /// Private struct used by this GObject type + struct LOKDocViewPrivateImpl +@@ -125,8 +129,8 @@ struct LOKDocViewPrivateImpl + m_aDocPath(nullptr), + m_nLoadProgress(0), + m_bIsLoading(false), +- m_bCanZoomIn(false), +- m_bCanZoomOut(false), ++ m_bCanZoomIn(true), ++ m_bCanZoomOut(true), + m_pOffice(nullptr), + m_pDocument(nullptr), + lokThreadPool(nullptr), +@@ -2473,6 +2477,13 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + LOKDocViewPrivate& priv = getPrivate(pDocView); + GError* error = nullptr; + ++ // Clamp the input value in [MIN_ZOOM, MAX_ZOOM] ++ fZoom = fZoom < MIN_ZOOM ? MIN_ZOOM : fZoom; ++ fZoom = fZoom > MAX_ZOOM ? MAX_ZOOM : fZoom; ++ ++ if (fZoom == priv->m_fZoom) ++ return; ++ + priv->m_fZoom = fZoom; + long nDocumentWidthPixels = twipToPixel(priv->m_nDocumentWidthTwips, fZoom); + long nDocumentHeightPixels = twipToPixel(priv->m_nDocumentHeightTwips, fZoom); +@@ -2487,6 +2498,20 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) + + g_object_notify_by_pspec(G_OBJECT(pDocView), properties[PROP_ZOOM]); + ++ // set properties to indicate if view can be further zoomed in/out ++ bool bCanZoomIn = priv->m_fZoom < MAX_ZOOM; ++ bool bCanZoomOut = priv->m_fZoom > MIN_ZOOM; ++ if (bCanZoomIn != priv->m_bCanZoomIn) ++ { ++ priv->m_bCanZoomIn = bCanZoomIn; ++ g_object_notify_by_pspec(G_OBJECT(pDocView), properties[PROP_CAN_ZOOM_IN]); ++ } ++ if (bCanZoomOut != priv->m_bCanZoomOut) ++ { ++ priv->m_bCanZoomOut = bCanZoomOut; ++ g_object_notify_by_pspec(G_OBJECT(pDocView), properties[PROP_CAN_ZOOM_OUT]); ++ } ++ + // Update the client's view size + GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr); + LOEvent* pLOEvent = new LOEvent(LOK_SET_CLIENT_ZOOM); +-- +2.12.0 + diff --git a/SOURCES/0388-lokdocview-Center-the-widget-inside-the-allocation.patch b/SOURCES/0388-lokdocview-Center-the-widget-inside-the-allocation.patch new file mode 100644 index 0000000..7de3c60 --- /dev/null +++ b/SOURCES/0388-lokdocview-Center-the-widget-inside-the-allocation.patch @@ -0,0 +1,48 @@ +From 356c869cbd52306275956973c18da53a15fe7655 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 20 Jan 2016 14:49:29 +0530 +Subject: [PATCH 388/398] lokdocview: Center the widget inside the allocation + +Change-Id: I8d7f8ffb1c5ddd07ccf7d56bdf0ccc866c927401 +Reviewed-on: https://gerrit.libreoffice.org/21624 +Tested-by: Jenkins +Reviewed-by: Pranav Kant +(cherry picked from commit 070bfedb7c0bc01ada0c0b95622543472ccb4a1c) +Reviewed-on: https://gerrit.libreoffice.org/21638 +Reviewed-by: Miklos Vajna +(cherry picked from commit 3763ab42fa88d9f2a2248eba1854f3d97fcfbde8) +--- + libreofficekit/source/gtk/lokdocview.cxx | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index d2c66b951b7d..1af678e1acc2 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2404,14 +2404,21 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + SAL_DLLPUBLIC_EXPORT GtkWidget* + lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + { +- return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, "lopath", pPath == NULL ? LOK_PATH : pPath, NULL)); ++ return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, ++ "lopath", pPath == nullptr ? LOK_PATH : pPath, ++ "halign", GTK_ALIGN_CENTER, ++ nullptr)); + } + + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOKDocView) + { + LOKDocViewPrivate& pOldPriv = getPrivate(pOldLOKDocView); + GtkWidget* pNewDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/nullptr, /*error=*/nullptr, +- "lopath", pOldPriv->m_aLOPath, "lopointer", pOldPriv->m_pOffice, "docpointer", pOldPriv->m_pDocument, NULL)); ++ "lopath", pOldPriv->m_aLOPath, ++ "lopointer", pOldPriv->m_pOffice, ++ "docpointer", pOldPriv->m_pDocument, ++ "halign", GTK_ALIGN_CENTER, ++ nullptr)); + + // No documentLoad(), just a createView(). + LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pNewDocView)); +-- +2.12.0 + diff --git a/SOURCES/0389-libreofficekit-password-interaction-optional-and-off.patch b/SOURCES/0389-libreofficekit-password-interaction-optional-and-off.patch new file mode 100644 index 0000000..eb6ce55 --- /dev/null +++ b/SOURCES/0389-libreofficekit-password-interaction-optional-and-off.patch @@ -0,0 +1,520 @@ +From 419ebb636dc46040fe508f71af3f6baad3c930ff Mon Sep 17 00:00:00 2001 +From: Michael Stahl +Date: Fri, 22 Jan 2016 13:39:32 +0100 +Subject: [PATCH 389/398] libreofficekit: password interaction optional and off + by default + +Add setOptionalFeatures() function that clients must call during +initialization, and enum LibreOfficeKitOptionalFeatures. + +Reviewed-on: https://gerrit.libreoffice.org/21809 +Reviewed-by: Jan Holesovsky +Tested-by: Jan Holesovsky +(cherry picked from commit 23a0ee3c01c3588472e1c19605909d6b9401253c) + +libreofficekit: ask for password when loading encrypted documents +(cherry picked from commit 2b63e576a5cf06f4af877d63403ad7955ac71b72) + +desktop: use x prefix for uno::Reference +(cherry picked from commit 0101cd3da6262169fa273309a86ba5e7cfe573bf) + +loplugin:defaultparams +(cherry picked from commit 95c8b8e85d3328bfbe906ef3f69145842aae01db) + +Reviewed-on: https://gerrit.libreoffice.org/21838 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit 2241a7fd97b8b70d2d3106ac531cc72192ad708f) + +Change-Id: I73035193c87033052921c3aad94fdc057fe81111 +--- + desktop/inc/lib/init.hxx | 13 +++- + desktop/source/lib/init.cxx | 38 +++++++++- + desktop/source/lib/lokinteractionhandler.cxx | 107 +++++++++++++++++++++++++-- + desktop/source/lib/lokinteractionhandler.hxx | 19 ++++- + include/LibreOfficeKit/LibreOfficeKit.h | 9 +++ + include/LibreOfficeKit/LibreOfficeKit.hxx | 34 +++++++++ + include/LibreOfficeKit/LibreOfficeKitEnums.h | 45 ++++++++++- + libreofficekit/source/gtk/lokdocview.cxx | 10 +++ + 8 files changed, 264 insertions(+), 11 deletions(-) + +diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx +index 4f878d26c007..560bd06c6cd9 100644 +--- a/desktop/inc/lib/init.hxx ++++ b/desktop/inc/lib/init.hxx +@@ -7,13 +7,16 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + #include ++#include + #include + #include + #include ++#include ++#include + #include "../../source/inc/desktopdllapi.h" + #include + +-using namespace css; ++class LOKInteractionHandler; + + namespace desktop { + struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public _LibreOfficeKitDocument +@@ -34,7 +37,15 @@ namespace desktop { + oslThread maThread; + LibreOfficeKitCallback mpCallback; + void *mpCallbackData; ++ int64_t mOptionalFeatures; ++ std::map> mInteractionMap; + + LibLibreOffice_Impl(); ++ ~LibLibreOffice_Impl(); ++ ++ bool hasOptionalFeature(LibreOfficeKitOptionalFeatures const feature) ++ { ++ return (mOptionalFeatures & feature) != 0; ++ } + }; + } +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 6bed25514137..35ba91306036 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -433,11 +433,16 @@ static void lo_registerCallback (LibreOfficeKit* pThis, + LibreOfficeKitCallback pCallback, + void* pData); + static char* lo_getFilterTypes(LibreOfficeKit* pThis); ++static void lo_setOptionalFeatures(LibreOfficeKit* pThis, uint64_t features); ++static void lo_setDocumentPassword(LibreOfficeKit* pThis, ++ const char* pURL, ++ const char* pPassword); + + LibLibreOffice_Impl::LibLibreOffice_Impl() + : maThread(0) + , mpCallback(nullptr) + , mpCallbackData(nullptr) ++ , mOptionalFeatures(0) + { + if(!(m_pOfficeClass = gOfficeClass.lock())) { + m_pOfficeClass.reset(new LibreOfficeKitClass); +@@ -449,6 +454,8 @@ LibLibreOffice_Impl::LibLibreOffice_Impl() + m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions; + m_pOfficeClass->registerCallback = lo_registerCallback; + m_pOfficeClass->getFilterTypes = lo_getFilterTypes; ++ m_pOfficeClass->setOptionalFeatures = lo_setOptionalFeatures; ++ m_pOfficeClass->setDocumentPassword = lo_setDocumentPassword; + + gOfficeClass = m_pOfficeClass; + } +@@ -456,6 +463,10 @@ LibLibreOffice_Impl::LibLibreOffice_Impl() + pClass = m_pOfficeClass.get(); + } + ++LibLibreOffice_Impl::~LibLibreOffice_Impl() ++{ ++} ++ + namespace + { + +@@ -517,7 +528,10 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, + uno::makeAny(OUString::createFromAscii(pOptions)), + beans::PropertyState_DIRECT_VALUE); + +- uno::Reference xInteraction(new LOKInteractionHandler(::comphelper::getProcessComponentContext())); ++ rtl::Reference const pInteraction( ++ new LOKInteractionHandler(::comphelper::getProcessComponentContext(), pLib)); ++ auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction))); ++ uno::Reference const xInteraction(pInteraction.get()); + aFilterOptions[1].Name = "InteractionHandler"; + aFilterOptions[1].Value <<= xInteraction; + +@@ -536,6 +550,12 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, + aURL, OUString("_blank"), 0, + aFilterOptions); + ++ assert(!xComponent.is() || pair.second); // concurrent loading of same URL ought to fail ++ if (!pair.second) ++ { ++ pLib->mInteractionMap.erase(aURL.toUtf8()); ++ } ++ + if (!xComponent.is()) + { + pLib->maLastExceptionMsg = "loadComponentFromURL returned an empty reference"; +@@ -1579,6 +1599,22 @@ static char* lo_getFilterTypes(LibreOfficeKit* pThis) + return strdup(aStream.str().c_str()); + } + ++static void lo_setOptionalFeatures(LibreOfficeKit* pThis, uint64_t const features) ++{ ++ LibLibreOffice_Impl *const pLib = static_cast(pThis); ++ pLib->mOptionalFeatures = features; ++} ++ ++static void lo_setDocumentPassword(LibreOfficeKit* pThis, ++ const char* pURL, const char* pPassword) ++{ ++ assert(pThis); ++ assert(pURL); ++ LibLibreOffice_Impl *const pLib = static_cast(pThis); ++ assert(pLib->mInteractionMap.find(OString(pURL)) != pLib->mInteractionMap.end()); ++ pLib->mInteractionMap.find(OString(pURL))->second->SetPassword(pPassword); ++} ++ + static void force_c_locale() + { + // force locale (and resource files loaded) to en-US +diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx +index 1d20b0219e28..50a79721ff69 100644 +--- a/desktop/source/lib/lokinteractionhandler.cxx ++++ b/desktop/source/lib/lokinteractionhandler.cxx +@@ -19,14 +19,28 @@ + + #include "lokinteractionhandler.hxx" + ++#include + #include + ++#include + #include ++#include ++#include ++ ++#define LOK_USE_UNSTABLE_API ++#include <../../inc/lib/init.hxx> ++ ++#include + + using namespace com::sun::star; + +-LOKInteractionHandler::LOKInteractionHandler(uno::Reference const & /*rxContext*/) ++LOKInteractionHandler::LOKInteractionHandler( ++ uno::Reference const & /*rxContext*/, ++ desktop::LibLibreOffice_Impl *const pLOKit) ++ : m_pLOKit(pLOKit) ++ , m_usePassword(false) + { ++ assert(m_pLOKit); + } + + LOKInteractionHandler::~LOKInteractionHandler() +@@ -58,15 +72,84 @@ void SAL_CALL LOKInteractionHandler::initialize(uno::Sequence const & + { + } + +-void SAL_CALL LOKInteractionHandler::handle(uno::Reference const & rRequest) throw (uno::RuntimeException, std::exception) ++void SAL_CALL LOKInteractionHandler::handle( ++ uno::Reference const & xRequest) ++throw (uno::RuntimeException, std::exception) + { + // just do the same thing in both cases +- handleInteractionRequest(rRequest); ++ handleInteractionRequest(xRequest); + } + +-sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(const uno::Reference& rRequest) throw ( uno::RuntimeException, std::exception ) ++sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest( ++ const uno::Reference& xRequest) ++throw (uno::RuntimeException, std::exception) + { +- uno::Sequence> const &rContinuations = rRequest->getContinuations(); ++ uno::Sequence> const &rContinuations = xRequest->getContinuations(); ++ ++ uno::Any const request(xRequest->getRequest()); ++ task::DocumentPasswordRequest2 passwordRequest; ++ if (request >>= passwordRequest) ++ { ++ if (m_pLOKit->hasOptionalFeature((passwordRequest.IsRequestPasswordToModify) ++ ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY ++ : LOK_FEATURE_DOCUMENT_PASSWORD)) ++ { ++ OString const url(passwordRequest.Name.toUtf8()); ++ m_pLOKit->mpCallback(passwordRequest.IsRequestPasswordToModify ++ ? LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY ++ : LOK_CALLBACK_DOCUMENT_PASSWORD, ++ url.getStr(), ++ m_pLOKit->mpCallbackData); ++ ++ // block until SetPassword is called ++ m_havePassword.wait(); ++ m_havePassword.reset(); ++ } ++ ++ for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i) ++ { ++ if (m_usePassword) ++ { ++ if (passwordRequest.IsRequestPasswordToModify) ++ { ++ uno::Reference const xIPW2( ++ rContinuations[i], uno::UNO_QUERY); ++ xIPW2->setPasswordToModify(m_Password); ++ xIPW2->select(); ++ } ++ else ++ { ++ uno::Reference const xIPW( ++ rContinuations[i], uno::UNO_QUERY); ++ if (xIPW.is()) ++ { ++ xIPW->setPassword(m_Password); ++ xIPW->select(); ++ } ++ } ++ } ++ else ++ { ++ if (passwordRequest.IsRequestPasswordToModify) ++ { ++ uno::Reference const xIPW2( ++ rContinuations[i], uno::UNO_QUERY); ++ xIPW2->setRecommendReadOnly(true); ++ xIPW2->select(); ++ } ++ else ++ { ++ uno::Reference const xAbort( ++ rContinuations[i], uno::UNO_QUERY); ++ if (xAbort.is()) ++ { ++ xAbort->select(); ++ } ++ } ++ } ++ } ++ return sal_True; ++ } + + // TODO: add LOK api that allows handling this for real, for the moment we + // just set the interaction as 'Approved' +@@ -80,4 +163,18 @@ sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(const uno::Ref + return sal_True; + } + ++void LOKInteractionHandler::SetPassword(char const*const pPassword) ++{ ++ if (pPassword) ++ { ++ m_Password = OUString(pPassword, strlen(pPassword), RTL_TEXTENCODING_UTF8); ++ m_usePassword = true; ++ } ++ else ++ { ++ m_usePassword = false; ++ } ++ m_havePassword.set(); ++} ++ + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ +diff --git a/desktop/source/lib/lokinteractionhandler.hxx b/desktop/source/lib/lokinteractionhandler.hxx +index 6d4aa8231daf..584658337fc4 100644 +--- a/desktop/source/lib/lokinteractionhandler.hxx ++++ b/desktop/source/lib/lokinteractionhandler.hxx +@@ -20,12 +20,15 @@ + #ifndef INCLUDED_DESKTOP_SOURCE_LIB_LOKINTERACTIONHANDLER_HXX + #define INCLUDED_DESKTOP_SOURCE_LIB_LOKINTERACTIONHANDLER_HXX + ++#include + #include + + #include + #include + #include + ++namespace desktop { struct LibLibreOffice_Impl; } ++ + /** InteractionHandler is an interface that provides the user with various dialogs / error messages. + + We need an own implementation for the LibreOfficeKit so that we can route the +@@ -38,11 +41,21 @@ class LOKInteractionHandler: public cppu::WeakImplHelper + { +- LOKInteractionHandler(const LOKInteractionHandler&) SAL_DELETED_FUNCTION; +- LOKInteractionHandler& operator=(const LOKInteractionHandler&) SAL_DELETED_FUNCTION; ++private: ++ desktop::LibLibreOffice_Impl * m_pLOKit; ++ OUString m_Password; ++ bool m_usePassword; ++ osl::Condition m_havePassword; ++ ++ LOKInteractionHandler(const LOKInteractionHandler&) = delete; ++ LOKInteractionHandler& operator=(const LOKInteractionHandler&) = delete; + + public: +- explicit LOKInteractionHandler(com::sun::star::uno::Reference const & rxContext); ++ void SetPassword(char const* pPassword); ++ ++ explicit LOKInteractionHandler( ++ com::sun::star::uno::Reference const & rxContext, ++ desktop::LibLibreOffice_Impl *); + + virtual ~LOKInteractionHandler(); + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h +index 5189cca5eb5e..b31e5eef1c01 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.h ++++ b/include/LibreOfficeKit/LibreOfficeKit.h +@@ -15,6 +15,7 @@ + #ifdef LOK_USE_UNSTABLE_API + // the unstable API needs C99's bool + #include ++#include + #endif + + #include +@@ -62,6 +63,14 @@ struct _LibreOfficeKitClass + + /// @see lok::Office::getFilterTypes(). + char* (*getFilterTypes) (LibreOfficeKit* pThis); ++ ++ /// @see lok::Office::setOptionalFeatures(). ++ void (*setOptionalFeatures)(LibreOfficeKit* pThis, uint64_t features); ++ ++ /// @see lok::Office::setDocumentPassword(). ++ void (*setDocumentPassword) (LibreOfficeKit* pThis, ++ char const* pURL, ++ char const* pPassword); + #endif + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx +index e592bbe549ab..53ad4359357a 100644 +--- a/include/LibreOfficeKit/LibreOfficeKit.hxx ++++ b/include/LibreOfficeKit/LibreOfficeKit.hxx +@@ -442,6 +442,40 @@ public: + { + return mpThis->pClass->getFilterTypes(mpThis); + } ++ ++ /** ++ * Set bitmask of optional features supported by the client. ++ * ++ * @see LibreOfficeKitOptionalFeatures ++ */ ++ void setOptionalFeatures(uint64_t features) ++ { ++ return mpThis->pClass->setOptionalFeatures(mpThis, features); ++ } ++ ++ /** ++ * Set password required for loading or editing a document. ++ * ++ * Loading the document is blocked until the password is provided. ++ * ++ * @param pURL the URL of the document, as sent to the callback ++ * @param pPassword the password, nullptr indicates no password ++ * ++ * In response to LOK_CALLBACK_DOCUMENT_PASSWORD, a vaild password ++ * will continue loading the document, an invalid password will ++ * result in another LOK_CALLBACK_DOCUMENT_PASSWORD request, ++ * and a NULL password will abort loading the document. ++ * ++ * In response to LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY, a vaild ++ * password will continue loading the document, an invalid password will ++ * result in another LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY request, ++ * and a NULL password will continue loading the document in read-only ++ * mode. ++ */ ++ inline void setDocumentPassword(char const* pURL, char const* pPassword) ++ { ++ mpThis->pClass->setDocumentPassword(mpThis, pURL, pPassword); ++ } + #endif // LOK_USE_UNSTABLE_API + }; + +diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h +index a0f5e886dcac..5931f7871e50 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h ++++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h +@@ -40,6 +40,32 @@ typedef enum + } + LibreOfficeKitTileMode; + ++/** Optional features of LibreOfficeKit, in particular callbacks that block ++ * LibreOfficeKit until the corresponding reply is received, which would ++ * deadlock if the client does not support the feature. ++ * ++ * @see lok::Office::setOptionalFeatures(). ++ */ ++typedef enum ++{ ++ /** ++ * Handle LOK_CALLBACK_DOCUMENT_PASSWORD by prompting the user ++ * for a password. ++ * ++ * @see lok::Office::setDocumentPassword(). ++ */ ++ LOK_FEATURE_DOCUMENT_PASSWORD = (1ULL << 0), ++ ++ /** ++ * Handle LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY by prompting the user ++ * for a password. ++ * ++ * @see lok::Office::setDocumentPassword(). ++ */ ++ LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY = (1ULL << 1), ++} ++LibreOfficeKitOptionalFeatures; ++ + typedef enum + { + /** +@@ -221,7 +247,24 @@ typedef enum + /** + * The text content of the formula bar in Calc. + */ +- LOK_CALLBACK_CELL_FORMULA ++ LOK_CALLBACK_CELL_FORMULA, ++ ++ /** ++ * Loading a document requires a password. ++ * ++ * Loading the document is blocked until the password is provided via ++ * lok::Office::setDocumentPassword(). The document cannot be loaded ++ * without the password. ++ */ ++ LOK_CALLBACK_DOCUMENT_PASSWORD, ++ ++ /** ++ * Editing a document requires a password. ++ * ++ * Loading the document is blocked until the password is provided via ++ * lok::Office::setDocumentPassword(). ++ */ ++ LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY, + } + LibreOfficeKitCallbackType; + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 1af678e1acc2..960c8c1f2624 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -804,6 +804,14 @@ globalCallback (gpointer pData) + g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, 1.0); + } + break; ++ case LOK_CALLBACK_DOCUMENT_PASSWORD: ++ case LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY: ++ { ++ char const*const pURL(pCallback->m_aPayload.c_str()); ++ // TODO maybe allow more passwords ++ priv->m_pOffice->pClass->setDocumentPassword(priv->m_pOffice, pURL, "1"); ++ } ++ break; + default: + g_assert(false); + break; +@@ -2026,6 +2034,8 @@ static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* / + return FALSE; + } + ++// priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, LOK_FEATURE_DOCUMENT_PASSWORD|LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY); ++ + return TRUE; + } + +-- +2.12.0 + diff --git a/SOURCES/0390-libreofficekit-fix-inverted-condition.patch b/SOURCES/0390-libreofficekit-fix-inverted-condition.patch new file mode 100644 index 0000000..dc9a6ef --- /dev/null +++ b/SOURCES/0390-libreofficekit-fix-inverted-condition.patch @@ -0,0 +1,62 @@ +From 1404902fec558c589f17d757192548e009acdfc1 Mon Sep 17 00:00:00 2001 +From: Michael Stahl +Date: Mon, 1 Feb 2016 12:31:32 +0100 +Subject: [PATCH 390/398] libreofficekit: fix inverted condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +... that prevented loading the same URL multiple times. Also make this +exception-safe while at it. + +(cherry picked from commit 61e80cd9e3e425674e18221237b8b0574645f377) + +Change-Id: Ic71735fef1ad8f79a210279d4d03f1fd5fa8cf69 +Reviewed-on: https://gerrit.libreoffice.org/22001 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 24c3426d07f5b8fcd19da6f4bc3ee7dd56758ab1) +--- + desktop/source/lib/init.cxx | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 35ba91306036..fe297fb09414 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -531,6 +532,12 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, + rtl::Reference const pInteraction( + new LOKInteractionHandler(::comphelper::getProcessComponentContext(), pLib)); + auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction))); ++ comphelper::ScopeGuard const g([&] () { ++ if (pair.second) ++ { ++ pLib->mInteractionMap.erase(aURL.toUtf8()); ++ } ++ }); + uno::Reference const xInteraction(pInteraction.get()); + aFilterOptions[1].Name = "InteractionHandler"; + aFilterOptions[1].Value <<= xInteraction; +@@ -551,10 +558,6 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis, + aFilterOptions); + + assert(!xComponent.is() || pair.second); // concurrent loading of same URL ought to fail +- if (!pair.second) +- { +- pLib->mInteractionMap.erase(aURL.toUtf8()); +- } + + if (!xComponent.is()) + { +-- +2.12.0 + diff --git a/SOURCES/0391-Missing-include.patch b/SOURCES/0391-Missing-include.patch new file mode 100644 index 0000000..7f84315 --- /dev/null +++ b/SOURCES/0391-Missing-include.patch @@ -0,0 +1,27 @@ +From 2ae4679d0324522442a87fd11c68e4a0cd44c3ab Mon Sep 17 00:00:00 2001 +From: Stephan Bergmann +Date: Thu, 28 Jan 2016 15:47:41 +0100 +Subject: [PATCH 391/398] Missing include + +Change-Id: I4930837c2a5bd78c16a83dcccde34843d3026618 +(cherry picked from commit 63cada47911029cce512f3b8ac0b6a6d2c323032) +(cherry picked from commit 201793cb2c204475422cd0ee86f4065f03e4b9be) +--- + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index e867e1b239a7..a21daf199fa7 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +-- +2.12.0 + diff --git a/SOURCES/0392-lokdocview-Handle-password-protected-documents.patch b/SOURCES/0392-lokdocview-Handle-password-protected-documents.patch new file mode 100644 index 0000000..3cfceb0 --- /dev/null +++ b/SOURCES/0392-lokdocview-Handle-password-protected-documents.patch @@ -0,0 +1,342 @@ +From fe80bd09aa8bbe1e190d91c7f85c2a8b977c1dd1 Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Wed, 27 Jan 2016 16:56:14 +0530 +Subject: [PATCH 392/398] lokdocview: Handle password protected documents +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-on: https://gerrit.libreoffice.org/21861 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 18fbddcca569c109ca2f46f7d791187e672d4d83) +Signed-off-by: Michael Stahl + +Change-Id: I606a1112c8eb4c1cc4596d6947ce1223543cc87c +(cherry picked from commit 89a3c1b4d69aac447606dc6f0e661b2ef4dddc8c) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 12 +++ + .../qa/gtktiledviewer/gtktiledviewer.cxx | 50 ++++++++++ + libreofficekit/source/gtk/lokdocview.cxx | 109 ++++++++++++++++++++- + 3 files changed, 166 insertions(+), 5 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index e06d154f772e..1df27c106214 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -275,6 +275,18 @@ gboolean lok_doc_view_paste (LOKDocView* + gsize nSize); + + /** ++ * lok_doc_view_set_document_password: ++ * @pDocView: The #LOKDocView instance ++ * @pUrl: the URL of the document to set password for, as sent with signal `password-required` ++ * @pPassword: (nullable): the password, NULL for no password ++ * ++ * Set the password for password protected documents ++ */ ++void lok_doc_view_set_document_password (LOKDocView* pDocView, ++ const gchar* pURL, ++ const gchar* pPassword); ++ ++/** + * lok_doc_view_pixel_to_twip: + * @pDocView: The #LOKDocView instance + * @fInput: The value in pixels to convert to twips +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index a21daf199fa7..3dc9f246f18e 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -462,10 +462,20 @@ static void toggleFindbar(GtkWidget* pButton, gpointer /*pItem*/) + } + } + ++static void ++setLOKFeatures (GtkWidget* pDocView) ++{ ++ g_object_set(G_OBJECT(pDocView), ++ "doc-password", TRUE, ++ "doc-password-to-modify", TRUE, ++ nullptr); ++} ++ + /// Common initialization, regardless if it's just a new view or a full init. + static TiledWindow& setupWidgetAndCreateWindow(GtkWidget* pDocView) + { + setupDocView(pDocView); ++ setLOKFeatures(pDocView); + TiledWindow aWindow; + aWindow.m_pDocView = pDocView; + GtkWidget* pWindow = createWindow(aWindow); +@@ -797,6 +807,45 @@ static void formulaChanged(LOKDocView* pLOKDocView, char* pPayload, gpointer /*p + gtk_entry_set_text(GTK_ENTRY(rWindow.m_pFormulabarEntry), pPayload); + } + ++/// LOKDocView password is requried to open the document ++static void passwordRequired(LOKDocView* pLOKDocView, gchar* pUrl, gboolean bModify, gpointer /*pData*/) ++{ ++ GtkWidget* pPasswordDialog = gtk_dialog_new_with_buttons ("Password required", ++ GTK_WINDOW (gtk_widget_get_toplevel(GTK_WIDGET(pLOKDocView))), ++ GTK_DIALOG_MODAL, ++ "OK", ++ GTK_RESPONSE_OK, ++ nullptr); ++ g_object_set(G_OBJECT(pPasswordDialog), "resizable", FALSE, nullptr); ++ GtkWidget* pDialogMessageArea = gtk_dialog_get_content_area (GTK_DIALOG (pPasswordDialog)); ++ GtkWidget* pPasswordEntry = gtk_entry_new (); ++ gtk_entry_set_visibility (GTK_ENTRY(pPasswordEntry), FALSE); ++ gtk_entry_set_invisible_char (GTK_ENTRY(pPasswordEntry), '*'); ++ gtk_box_pack_end(GTK_BOX(pDialogMessageArea), pPasswordEntry, TRUE, TRUE, 2); ++ if (bModify) ++ { ++ GtkWidget* pSecondaryLabel = gtk_label_new ("Document requires password to edit"); ++ gtk_box_pack_end(GTK_BOX(pDialogMessageArea), pSecondaryLabel, TRUE, TRUE, 2); ++ gtk_dialog_add_button (GTK_DIALOG (pPasswordDialog), "Open as read-only", GTK_RESPONSE_ACCEPT); ++ } ++ gtk_widget_show_all(pPasswordDialog); ++ ++ gint res = gtk_dialog_run (GTK_DIALOG(pPasswordDialog)); ++ switch (res) ++ { ++ case GTK_RESPONSE_OK: ++ lok_doc_view_set_document_password (pLOKDocView, pUrl, gtk_entry_get_text(GTK_ENTRY(pPasswordEntry))); ++ break; ++ case GTK_RESPONSE_ACCEPT: ++ // User accepts to open this document as read-only ++ case GTK_RESPONSE_DELETE_EVENT: ++ lok_doc_view_set_document_password (pLOKDocView, pUrl, nullptr); ++ break; ++ } ++ ++ gtk_widget_destroy(pPasswordDialog); ++} ++ + static void toggleToolItem(GtkWidget* pWidget, gpointer /*pData*/) + { + TiledWindow& rWindow = lcl_getTiledWindow(pWidget); +@@ -1254,6 +1303,7 @@ static void setupDocView(GtkWidget* pDocView) + g_signal_connect(pDocView, "hyperlink-clicked", G_CALLBACK(signalHyperlink), NULL); + g_signal_connect(pDocView, "cursor-changed", G_CALLBACK(cursorChanged), NULL); + g_signal_connect(pDocView, "formula-changed", G_CALLBACK(formulaChanged), NULL); ++ g_signal_connect(pDocView, "password-required", G_CALLBACK(passwordRequired), nullptr); + } + + int main( int argc, char* argv[] ) +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 960c8c1f2624..f0dd7342c1a3 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -65,6 +65,8 @@ struct LOKDocViewPrivateImpl + glong m_nDocumentHeightTwips; + /// View or edit mode. + gboolean m_bEdit; ++ /// LOK Features ++ guint64 m_nLOKFeatures; + /// Position and size of the visible cursor. + GdkRectangle m_aVisibleCursor; + /// Cursor overlay is visible or hidden (for blinking). +@@ -138,6 +140,7 @@ struct LOKDocViewPrivateImpl + m_nDocumentWidthTwips(0), + m_nDocumentHeightTwips(0), + m_bEdit(FALSE), ++ m_nLOKFeatures(0), + m_aVisibleCursor({0, 0, 0, 0}), + m_bCursorOverlayVisible(false), + m_bCursorVisible(true), +@@ -192,6 +195,7 @@ enum + COMMAND_RESULT, + FORMULA_CHANGED, + TEXT_SELECTION, ++ PASSWORD_REQUIRED, + + LAST_SIGNAL + }; +@@ -212,6 +216,8 @@ enum + PROP_DOC_HEIGHT, + PROP_CAN_ZOOM_IN, + PROP_CAN_ZOOM_OUT, ++ PROP_DOC_PASSWORD, ++ PROP_DOC_PASSWORD_TO_MODIFY, + + PROP_LAST + }; +@@ -311,6 +317,10 @@ callbackTypeToString (int nType) + return "LOK_CALLBACK_SET_PART"; + case LOK_CALLBACK_SEARCH_RESULT_SELECTION: + return "LOK_CALLBACK_SEARCH_RESULT_SELECTION"; ++ case LOK_CALLBACK_DOCUMENT_PASSWORD: ++ return "LOK_CALLBACK_DOCUMENT_PASSWORD"; ++ case LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY: ++ return "LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY"; + } + return nullptr; + } +@@ -783,6 +793,7 @@ globalCallback (gpointer pData) + { + CallbackData* pCallback = static_cast(pData); + LOKDocViewPrivate& priv = getPrivate(pCallback->m_pDocView); ++ gboolean bModify = false; + + switch (pCallback->m_nType) + { +@@ -804,12 +815,12 @@ globalCallback (gpointer pData) + g_signal_emit (pCallback->m_pDocView, doc_view_signals[LOAD_CHANGED], 0, 1.0); + } + break; +- case LOK_CALLBACK_DOCUMENT_PASSWORD: + case LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY: ++ bModify = true; ++ case LOK_CALLBACK_DOCUMENT_PASSWORD: + { + char const*const pURL(pCallback->m_aPayload.c_str()); +- // TODO maybe allow more passwords +- priv->m_pOffice->pClass->setDocumentPassword(priv->m_pOffice, pURL, "1"); ++ g_signal_emit (pCallback->m_pDocView, doc_view_signals[PASSWORD_REQUIRED], 0, pURL, bModify); + } + break; + default: +@@ -1910,6 +1921,8 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal + { + LOKDocView* pDocView = LOK_DOC_VIEW (object); + LOKDocViewPrivate& priv = getPrivate(pDocView); ++ gboolean bDocPasswordEnabled = priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD; ++ gboolean bDocPasswordToModifyEnabled = priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY; + + switch (propId) + { +@@ -1937,6 +1950,20 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal + case PROP_DOC_HEIGHT: + priv->m_nDocumentHeightTwips = g_value_get_long (value); + break; ++ case PROP_DOC_PASSWORD: ++ if (g_value_get_boolean (value) != bDocPasswordEnabled) ++ { ++ priv->m_nLOKFeatures = priv->m_nLOKFeatures ^ LOK_FEATURE_DOCUMENT_PASSWORD; ++ priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, priv->m_nLOKFeatures); ++ } ++ break; ++ case PROP_DOC_PASSWORD_TO_MODIFY: ++ if ( g_value_get_boolean (value) != bDocPasswordToModifyEnabled) ++ { ++ priv->m_nLOKFeatures = priv->m_nLOKFeatures ^ LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY; ++ priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, priv->m_nLOKFeatures); ++ } ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec); + } +@@ -1985,6 +2012,12 @@ static void lok_doc_view_get_property (GObject* object, guint propId, GValue *va + case PROP_CAN_ZOOM_OUT: + g_value_set_boolean (value, priv->m_bCanZoomOut); + break; ++ case PROP_DOC_PASSWORD: ++ g_value_set_boolean (value, priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD); ++ break; ++ case PROP_DOC_PASSWORD_TO_MODIFY: ++ g_value_set_boolean (value, priv->m_nLOKFeatures & LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY); ++ break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propId, pspec); + } +@@ -2034,8 +2067,6 @@ static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* / + return FALSE; + } + +-// priv->m_pOffice->pClass->setOptionalFeatures(priv->m_pOffice, LOK_FEATURE_DOCUMENT_PASSWORD|LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY); +- + return TRUE; + } + +@@ -2223,6 +2254,33 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + static_cast(G_PARAM_READABLE + | G_PARAM_STATIC_STRINGS)); + ++ /** ++ * LOKDocView:doc-password: ++ * ++ * Set it to true if client supports providing password for viewing ++ * password protected documents ++ */ ++ properties[PROP_DOC_PASSWORD] = ++ g_param_spec_boolean("doc-password", ++ "Document password capability", ++ "Whether client supports providing document passwords", ++ FALSE, ++ static_cast(G_PARAM_READWRITE ++ | G_PARAM_STATIC_STRINGS)); ++ ++ /** ++ * LOKDocView:doc-password-to-modify: ++ * ++ * Set it to true if client supports providing password for edit-protected documents ++ */ ++ properties[PROP_DOC_PASSWORD_TO_MODIFY] = ++ g_param_spec_boolean("doc-password-to-modify", ++ "Edit document password capability", ++ "Whether the client supports providing passwords to edit documents", ++ FALSE, ++ static_cast(G_PARAM_READWRITE ++ | G_PARAM_STATIC_STRINGS)); ++ + g_object_class_install_properties(pGObjectClass, PROP_LAST, properties); + + /** +@@ -2409,6 +2467,37 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); ++ ++ /** ++ * LOKDocView::password-required: ++ * @pDocView: the #LOKDocView on which the signal is emitted ++ * @pUrl: URL of the document for which password is required ++ * @bModify: whether password id required to modify the document ++ * This is true when password is required to edit the document, ++ * while it can still be viewed without password. In such cases, provide a NULL ++ * password for read-only access to the document. ++ * If false, password is required for opening the document, and document ++ * cannot be opened without providing a valid password. ++ * ++ * Password must be provided by calling lok_doc_view_set_document_password ++ * function with pUrl as provided by the callback. ++ * ++ * Upon entering a invalid password, another `password-required` signal is ++ * emitted. ++ * Upon entering a valid password, document starts to load. ++ * Upon entering a NULL password: if bModify is %TRUE, document starts to ++ * open in view-only mode, else loading of document is aborted. ++ */ ++ doc_view_signals[PASSWORD_REQUIRED] = ++ g_signal_new("password-required", ++ G_TYPE_FROM_CLASS(pGObjectClass), ++ G_SIGNAL_RUN_FIRST, ++ 0, ++ nullptr, nullptr, ++ g_cclosure_marshal_generic, ++ G_TYPE_NONE, 2, ++ G_TYPE_STRING, ++ G_TYPE_BOOLEAN); + } + + SAL_DLLPUBLIC_EXPORT GtkWidget* +@@ -2786,6 +2875,16 @@ lok_doc_view_paste (LOKDocView* pDocView, + return ret; + } + ++SAL_DLLPUBLIC_EXPORT void ++lok_doc_view_set_document_password (LOKDocView* pDocView, ++ const gchar* pURL, ++ const gchar* pPassword) ++{ ++ LOKDocViewPrivate& priv = getPrivate(pDocView); ++ ++ priv->m_pOffice->pClass->setDocumentPassword(priv->m_pOffice, pURL, pPassword); ++} ++ + SAL_DLLPUBLIC_EXPORT gfloat + lok_doc_view_pixel_to_twip (LOKDocView* pDocView, float fInput) + { +-- +2.12.0 + diff --git a/SOURCES/0393-lok-fix-saveAs-for-a-loaded-HTML-document.patch b/SOURCES/0393-lok-fix-saveAs-for-a-loaded-HTML-document.patch new file mode 100644 index 0000000..5a737df --- /dev/null +++ b/SOURCES/0393-lok-fix-saveAs-for-a-loaded-HTML-document.patch @@ -0,0 +1,43 @@ +From ed0cf5fe7f448b471a6627b045e2ea3df464e83f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Toma=C5=BE=20Vajngerl?= +Date: Thu, 4 Feb 2016 14:44:36 +0100 +Subject: [PATCH 393/398] lok: fix saveAs for a loaded HTML document + +a HTML document is reported as "com.sun.star.text.WebDocument" +which is a unsupported document type in LOK so report it as a +LOK_DOCTYPE_TEXT instead. + +Change-Id: Iaa77cb8b1f55cf31ebbb4fd4d69c02702e60e251 +(cherry picked from commit 806d34981f480908645038f4cfc29ebcf25ca145) +Reviewed-on: https://gerrit.libreoffice.org/22119 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit 1deed8dae78be05cafde17768d111035c111b567) +--- + desktop/source/lib/init.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index fe297fb09414..9e5c52917eb7 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -621,6 +621,7 @@ static int doc_saveAs(LibreOfficeKitDocument* pThis, const char* sUrl, const cha + break; + case LOK_DOCTYPE_OTHER: + default: ++ SAL_INFO("lok", "Can't save document - unsopported document type."); + return false; + } + +@@ -756,7 +757,7 @@ static int doc_getDocumentType (LibreOfficeKitDocument* pThis) + { + return LOK_DOCTYPE_DRAWING; + } +- else if (xDocument->supportsService("com.sun.star.text.TextDocument")) ++ else if (xDocument->supportsService("com.sun.star.text.TextDocument") || xDocument->supportsService("com.sun.star.text.WebDocument")) + { + return LOK_DOCTYPE_TEXT; + } +-- +2.12.0 + diff --git a/SOURCES/0394-lokdocview-Center-the-widget-vertically-inside-the-a.patch b/SOURCES/0394-lokdocview-Center-the-widget-vertically-inside-the-a.patch new file mode 100644 index 0000000..a55f07b --- /dev/null +++ b/SOURCES/0394-lokdocview-Center-the-widget-vertically-inside-the-a.patch @@ -0,0 +1,38 @@ +From 8b9d23f92cc6b9efef313ea155958e48d1a3faef Mon Sep 17 00:00:00 2001 +From: Pranav Kant +Date: Sun, 14 Feb 2016 20:44:00 +0530 +Subject: [PATCH 394/398] lokdocview: Center the widget vertically inside the + allocation + +Change-Id: I891519d54212ecd99273a54aca2a44e2d54c1933 +Reviewed-on: https://gerrit.libreoffice.org/22517 +Tested-by: Jenkins +Reviewed-by: Miklos Vajna +(cherry picked from commit bcaee2b0149651173cc93763231c47ff2f5a55c2) +--- + libreofficekit/source/gtk/lokdocview.cxx | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index f0dd7342c1a3..9f47138bbc37 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -2506,6 +2506,7 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + return GTK_WIDGET (g_initable_new (LOK_TYPE_DOC_VIEW, cancellable, error, + "lopath", pPath == nullptr ? LOK_PATH : pPath, + "halign", GTK_ALIGN_CENTER, ++ "valign", GTK_ALIGN_CENTER, + nullptr)); + } + +@@ -2517,6 +2518,7 @@ SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOK + "lopointer", pOldPriv->m_pOffice, + "docpointer", pOldPriv->m_pDocument, + "halign", GTK_ALIGN_CENTER, ++ "valign", GTK_ALIGN_CENTER, + nullptr)); + + // No documentLoad(), just a createView(). +-- +2.12.0 + diff --git a/SOURCES/0395-WaE-buggy-warning-in-vs2015-r1.patch b/SOURCES/0395-WaE-buggy-warning-in-vs2015-r1.patch new file mode 100644 index 0000000..e37d8f2 --- /dev/null +++ b/SOURCES/0395-WaE-buggy-warning-in-vs2015-r1.patch @@ -0,0 +1,46 @@ +From e30be4212a631189bdfb68e3a72e2f80ae0a6f75 Mon Sep 17 00:00:00 2001 +From: Norbert Thiebaud +Date: Sun, 21 Feb 2016 08:27:05 -0800 +Subject: [PATCH 395/398] WaE buggy warning in vs2015-r1 + +http://stackoverflow.com/questions/34013930/error-c4592-symbol-will-be-dynamically-initialized-vs2015-1-static-const-std + +Change-Id: Icbe882ad237d1e4f105006d8821ed5c89b06f525 +Reviewed-on: https://gerrit.libreoffice.org/22601 +Reviewed-by: Michael Stahl +Tested-by: Michael Stahl +(cherry picked from commit e895f1979ebf82cbab9739356ce97fc937efbdd0) +Signed-off-by: Michael Stahl +(cherry picked from commit c344820237efee7c3c7309a9f30ff8739aa8b5b4) +--- + desktop/source/lib/init.cxx | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx +index 9e5c52917eb7..184d7772ffc9 100644 +--- a/desktop/source/lib/init.cxx ++++ b/desktop/source/lib/init.cxx +@@ -186,6 +186,10 @@ static const ExtensionMap aDrawExtensionMap[] = + * by css, it might turn out to be worth mapping some of these missing cursors + * to available cursors? + */ ++#ifdef _MSC_VER ++#pragma warning(push) ++#pragma warning( disable : 4592) ++#endif + static const std::map aPointerMap { + { PointerStyle::Arrow, "default" }, + // PointerStyle::Null ? +@@ -228,6 +232,9 @@ static const std::map aPointerMap { + // Pivot Delete, TabSelectS through TabSelectSW + // PaintBrush, HideWhiteSpace, ShowWhiteSpace + }; ++#ifdef _MSC_VER ++#pragma warning(pop) ++#endif + + static OUString getUString(const char* pString) + { +-- +2.12.0 + diff --git a/SOURCES/0396-gtktiledviewer-needs-gtk3-not-gtk2.patch b/SOURCES/0396-gtktiledviewer-needs-gtk3-not-gtk2.patch new file mode 100644 index 0000000..8204dbd --- /dev/null +++ b/SOURCES/0396-gtktiledviewer-needs-gtk3-not-gtk2.patch @@ -0,0 +1,38 @@ +From 91e8213dde243c9acf18ffe2bcdce489d0fcbd8b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Mon, 7 Mar 2016 13:19:55 +0000 +Subject: [PATCH 396/398] gtktiledviewer needs gtk3 not gtk2 + +Change-Id: Iede2008139cb570ff65202762e92f6694548a065 +(cherry picked from commit e451b03e8c21ad23cb1abfd6dd68b6d1e8188121) +Reviewed-on: https://gerrit.libreoffice.org/22982 +Tested-by: Jenkins +Reviewed-by: Adolfo Jayme Barrientos +(cherry picked from commit 13ee59bf851b60a50d679a153641343206d58474) +--- + Repository.mk | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Repository.mk b/Repository.mk +index dd0afca39b7a..fad426921935 100644 +--- a/Repository.mk ++++ b/Repository.mk +@@ -67,13 +67,13 @@ $(eval $(call gb_Helper_register_executables,NONE, \ + svptest \ + svpclient \ + pixelctl ) \ +- $(if $(and $(ENABLE_GTK), $(filter LINUX %BSD SOLARIS,$(OS))), tilebench) \ ++ $(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), tilebench) \ + $(if $(filter LINUX MACOSX SOLARIS WNT %BSD,$(OS)),icontest \ + outdevgrind) \ + vcldemo \ + tiledrendering \ + mtfdemo \ +- $(if $(and $(ENABLE_GTK), $(filter LINUX %BSD SOLARIS,$(OS))), gtktiledviewer) \ ++ $(if $(and $(ENABLE_GTK3), $(filter LINUX %BSD SOLARIS,$(OS))), gtktiledviewer) \ + )) + + $(eval $(call gb_Helper_register_executables_for_install,SDK,sdk, \ +-- +2.12.0 + diff --git a/SOURCES/0397-tdf-99314-lokdocview-add-new-userprofileurl-property.patch b/SOURCES/0397-tdf-99314-lokdocview-add-new-userprofileurl-property.patch new file mode 100644 index 0000000..247fe7f --- /dev/null +++ b/SOURCES/0397-tdf-99314-lokdocview-add-new-userprofileurl-property.patch @@ -0,0 +1,191 @@ +From 4b8ba14da9d58594e16c317682897f195349a40c Mon Sep 17 00:00:00 2001 +From: Miklos Vajna +Date: Tue, 19 Apr 2016 09:09:19 +0200 +Subject: [PATCH 397/398] tdf#99314 lokdocview: add new userprofileurl property +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So that users of the widget can use a custom user profile, allowing +running widgets users and LibreOffice in parallel. + +(cherry picked from commit df784ec1bf3d1745a291056df28bec799d4fdee3) + +Conflicts: + libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx + +Change-Id: I1bd0a8e53aa3216adc721052cf30f0dd174327bd +Reviewed-on: https://gerrit.libreoffice.org/24591 +Tested-by: Jenkins +Reviewed-by: Caolán McNamara +Tested-by: Caolán McNamara +(cherry picked from commit 549f67a85774838abdefdb7916beb0f26e2f9d2c) +--- + include/LibreOfficeKit/LibreOfficeKitGtk.h | 17 ++++++++++ + .../qa/gtktiledviewer/gtktiledviewer.cxx | 12 +++++-- + libreofficekit/source/gtk/lokdocview.cxx | 37 +++++++++++++++++++++- + 3 files changed, 63 insertions(+), 3 deletions(-) + +diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h +index 1df27c106214..91e29c83db57 100644 +--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h ++++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h +@@ -55,6 +55,23 @@ GtkWidget* lok_doc_view_new (const gchar* + GError **error); + + /** ++ * lok_doc_view_new_from_user_profile: ++ * @pPath: (nullable): LibreOffice install path. Pass null to set it to default ++ * path which in most cases would be $libdir/libreoffice/program ++ * @pUserProfile: (nullable): User profile URL. Pass non-null to be able to ++ * use this widget and LibreOffice itself in parallel. ++ * @cancellable: The cancellable object that you can use to cancel this ++ * operation. ++ * @error: The error that will be set if the object fails to initialize. ++ * ++ * Returns: (transfer none): The #LOKDocView widget instance. ++ */ ++GtkWidget* lok_doc_view_new_from_user_profile (const gchar* pPath, ++ const gchar* pUserProfile, ++ GCancellable *cancellable, ++ GError **error); ++ ++/** + * lok_doc_view_new_from_widget: + * @pDocView: The #LOKDocView instance + * +diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +index 3dc9f246f18e..54c9294e5398 100644 +--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx ++++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx +@@ -35,7 +35,7 @@ static int help() + fprintf(stderr, "Usage: gtktiledviewer [ ... ]\n\n"); + fprintf(stderr, "Options:\n\n"); + fprintf(stderr, "--hide-whitespace: Hide whitespace between pages in text documents.\n"); +- fprintf(stderr, "--background-color : Set custom background color, e.g. 'yellow'.\n"); ++ fprintf(stderr, "--user-profile: Path to a custom user profile.\n"); + return 1; + } + +@@ -497,7 +497,15 @@ static void createView(GtkWidget* pButton, gpointer /*pItem*/) + /// Creates a new model, i.e. LOK init and document load, one view implicitly. + static void createModelAndView(const char* pLOPath, const char* pDocPath, const std::vector& rArguments) + { +- GtkWidget* pDocView = lok_doc_view_new(pLOPath, nullptr, nullptr); ++ std::string aUserProfile; ++ for (size_t i = 0; i < rArguments.size(); ++i) ++ { ++ const std::string& rArgument = rArguments[i]; ++ if (rArgument == "--user-profile" && i + 1 < rArguments.size()) ++ aUserProfile = std::string("file://") + rArguments[i + 1].c_str(); ++ } ++ const gchar* pUserProfile = aUserProfile.empty() ? nullptr : aUserProfile.c_str(); ++ GtkWidget* pDocView = lok_doc_view_new_from_user_profile(pLOPath, pUserProfile, nullptr, nullptr); + + setupWidgetAndCreateWindow(pDocView); + +diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx +index 9f47138bbc37..13ae6ea00e63 100644 +--- a/libreofficekit/source/gtk/lokdocview.cxx ++++ b/libreofficekit/source/gtk/lokdocview.cxx +@@ -48,6 +48,7 @@ + struct LOKDocViewPrivateImpl + { + const gchar* m_aLOPath; ++ const gchar* m_pUserProfileURL; + const gchar* m_aDocPath; + std::string m_aRenderingArguments; + gdouble m_nLoadProgress; +@@ -128,6 +129,7 @@ struct LOKDocViewPrivateImpl + + LOKDocViewPrivateImpl() + : m_aLOPath(nullptr), ++ m_pUserProfileURL(nullptr), + m_aDocPath(nullptr), + m_nLoadProgress(0), + m_bIsLoading(false), +@@ -206,6 +208,7 @@ enum + + PROP_LO_PATH, + PROP_LO_POINTER, ++ PROP_USER_PROFILE_URL, + PROP_DOC_PATH, + PROP_DOC_POINTER, + PROP_EDITABLE, +@@ -1932,6 +1935,9 @@ static void lok_doc_view_set_property (GObject* object, guint propId, const GVal + case PROP_LO_POINTER: + priv->m_pOffice = static_cast(g_value_get_pointer(value)); + break; ++ case PROP_USER_PROFILE_URL: ++ priv->m_pUserProfileURL = g_value_dup_string(value); ++ break; + case PROP_DOC_PATH: + priv->m_aDocPath = g_value_dup_string (value); + break; +@@ -1982,6 +1988,9 @@ static void lok_doc_view_get_property (GObject* object, guint propId, GValue *va + case PROP_LO_POINTER: + g_value_set_pointer(value, priv->m_pOffice); + break; ++ case PROP_USER_PROFILE_URL: ++ g_value_set_string(value, priv->m_pUserProfileURL); ++ break; + case PROP_DOC_PATH: + g_value_set_string (value, priv->m_aDocPath); + break; +@@ -2056,7 +2065,7 @@ static gboolean lok_doc_view_initable_init (GInitable *initable, GCancellable* / + if (priv->m_pOffice != nullptr) + return TRUE; + +- priv->m_pOffice = lok_init (priv->m_aLOPath); ++ priv->m_pOffice = lok_init_2(priv->m_aLOPath, priv->m_pUserProfileURL); + + if (priv->m_pOffice == nullptr) + { +@@ -2120,6 +2129,20 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass) + G_PARAM_STATIC_STRINGS)); + + /** ++ * LOKDocView:userprofileurl: ++ * ++ * The absolute path of the LibreOffice user profile. ++ */ ++ properties[PROP_USER_PROFILE_URL] = ++ g_param_spec_string("userprofileurl", ++ "User profile path", ++ "LibreOffice user profile path", ++ nullptr, ++ static_cast(G_PARAM_READWRITE | ++ G_PARAM_CONSTRUCT_ONLY | ++ G_PARAM_STATIC_STRINGS)); ++ ++ /** + * LOKDocView:docpath: + * + * The path of the document that is currently being viewed. +@@ -2510,11 +2533,23 @@ lok_doc_view_new (const gchar* pPath, GCancellable *cancellable, GError **error) + nullptr)); + } + ++SAL_DLLPUBLIC_EXPORT GtkWidget* ++lok_doc_view_new_from_user_profile (const gchar* pPath, const gchar* pUserProfile, GCancellable *cancellable, GError **error) ++{ ++ return GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, cancellable, error, ++ "lopath", pPath == nullptr ? LOK_PATH : pPath, ++ "userprofileurl", pUserProfile, ++ "halign", GTK_ALIGN_CENTER, ++ "valign", GTK_ALIGN_CENTER, ++ nullptr)); ++} ++ + SAL_DLLPUBLIC_EXPORT GtkWidget* lok_doc_view_new_from_widget(LOKDocView* pOldLOKDocView) + { + LOKDocViewPrivate& pOldPriv = getPrivate(pOldLOKDocView); + GtkWidget* pNewDocView = GTK_WIDGET(g_initable_new(LOK_TYPE_DOC_VIEW, /*cancellable=*/nullptr, /*error=*/nullptr, + "lopath", pOldPriv->m_aLOPath, ++ "userprofileurl", pOldPriv->m_pUserProfileURL, + "lopointer", pOldPriv->m_pOffice, + "docpointer", pOldPriv->m_pDocument, + "halign", GTK_ALIGN_CENTER, +-- +2.12.0 + diff --git a/SOURCES/0398-fix-build.patch b/SOURCES/0398-fix-build.patch new file mode 100644 index 0000000..da20034 --- /dev/null +++ b/SOURCES/0398-fix-build.patch @@ -0,0 +1,46 @@ +From d46c13839afcc2998c2b0d61058f86799b358798 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 20 Mar 2017 21:26:13 +0100 +Subject: [PATCH 398/398] fix build + +Change-Id: I571029ffef0e7f426458197a4bbfcddc473f79dd +--- + desktop/inc/lib/init.hxx | 4 ++-- + desktop/qa/desktop_lib/test_desktop_lib.cxx | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx +index 560bd06c6cd9..3f1fd67d7ad7 100644 +--- a/desktop/inc/lib/init.hxx ++++ b/desktop/inc/lib/init.hxx +@@ -21,12 +21,12 @@ class LOKInteractionHandler; + namespace desktop { + struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public _LibreOfficeKitDocument + { +- uno::Reference mxComponent; ++ css::uno::Reference mxComponent; + std::shared_ptr< LibreOfficeKitDocumentClass > m_pDocumentClass; + LibreOfficeKitCallback mpCallback; + void *mpCallbackData; + +- explicit LibLODocument_Impl(const uno::Reference &xComponent); ++ explicit LibLODocument_Impl(const css::uno::Reference &xComponent); + ~LibLODocument_Impl(); + }; + +diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx +index 4b08f9448f61..cb0bf721a4a5 100644 +--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx ++++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx +@@ -512,7 +512,7 @@ void DesktopLOKTest::testWriterComments() + TimeValue aTimeValue = {2 , 0}; // 2 seconds max + m_aCommandResultCondition.reset(); + pDocument->pClass->postUnoCommand(pDocument, ".uno:InsertAnnotation", nullptr, true); +- m_aCommandResultCondition.wait(aTimeValue); ++ m_aCommandResultCondition.wait(&aTimeValue); + CPPUNIT_ASSERT(!m_aCommandResult.isEmpty()); + xToolkit->reschedule(); + +-- +2.12.0 + diff --git a/SOURCES/libreoffice-installfix.patch b/SOURCES/libreoffice-installfix.patch new file mode 100644 index 0000000..e2448a5 --- /dev/null +++ b/SOURCES/libreoffice-installfix.patch @@ -0,0 +1,24 @@ +From 2ed57bc3ba020ebc6aec933445ae0b274685499e Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 3 Feb 2014 21:41:00 +0100 +Subject: [PATCH] installation fix + +--- + solenv/bin/modules/installer/worker.pm | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/solenv/bin/modules/installer/worker.pm b/solenv/bin/modules/installer/worker.pm +index aab676f..0e6f67d 100644 +--- a/solenv/bin/modules/installer/worker.pm ++++ b/solenv/bin/modules/installer/worker.pm +@@ -96,7 +96,6 @@ sub create_installation_directory + + $installdir = installer::systemactions::create_directories("install", $languageref); + installer::logger::print_message( "... creating installation set in $installdir ...\n" ); +- remove_old_installation_sets($installdir); + my $inprogressinstalldir = $installdir . "_inprogress"; + installer::systemactions::rename_directory($installdir, $inprogressinstalldir); + $installdir = $inprogressinstalldir; +-- +1.8.4.2 + diff --git a/SOURCES/libreoffice-multiliblauncher.sh b/SOURCES/libreoffice-multiliblauncher.sh new file mode 100644 index 0000000..05c9d3f --- /dev/null +++ b/SOURCES/libreoffice-multiliblauncher.sh @@ -0,0 +1,16 @@ +#!/bin/sh +OOO_ARCH=$(uname -m) +case $OOO_ARCH in + x86_64 | s390x | sparc64 | aarch64) + OOO_LIB_DIR="/usr/lib64" + SECONDARY_LIB_DIR="/usr/lib" + ;; + * ) + OOO_LIB_DIR="/usr/lib" + SECONDARY_LIB_DIR="/usr/lib64" + ;; +esac +if [ ! -x $OOO_LIB_DIR/BRAND/program/LAUNCHER ]; then + OOO_LIB_DIR="$SECONDARY_LIB_DIR" +fi +exec $OOO_LIB_DIR/BRAND/program/LAUNCHER "$@" diff --git a/SOURCES/openoffice.org-2.4.0.ooo86080.unopkg.bodge.patch b/SOURCES/openoffice.org-2.4.0.ooo86080.unopkg.bodge.patch new file mode 100644 index 0000000..02368bd --- /dev/null +++ b/SOURCES/openoffice.org-2.4.0.ooo86080.unopkg.bodge.patch @@ -0,0 +1,81 @@ +From 4ee0775161d44acc5089aeec2013d461fe592e23 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 3 Feb 2014 20:24:50 +0100 +Subject: [PATCH] i#86080 unopkg bodge + +--- + desktop/scripts/unopkg.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 51 insertions(+), 2 deletions(-) + +diff --git a/desktop/scripts/unopkg.sh b/desktop/scripts/unopkg.sh +index ca1e3bc..6393e99 100755 +--- a/desktop/scripts/unopkg.sh ++++ b/desktop/scripts/unopkg.sh +@@ -78,6 +78,53 @@ if [ "$(id -u)" -eq "0" ]; then + fi + fi + ++if [ $isnotuser -eq 1 ]; then ++ echo $@ | grep -q env:JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY ++ if [ $? -ne 0 ]; then ++ set -- $@ '-env:JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY=1' ++ fi ++ echo $@ | grep -q env:UNO_JAVA_JFW_INSTALL_DATA ++ if [ $? -ne 0 -a -w $sd_prog/../share/config/javasettingsunopkginstall.xml ]; then ++ set -- $@ '-env:UNO_JAVA_JFW_INSTALL_DATA=$$ORIGIN/../share/config/javasettingsunopkginstall.xml' ++ fi ++ echo $@ | grep -q env:UserInstallation ++ if [ $? -ne 0 ]; then ++ INSTDIR=`/bin/mktemp -d --tmpdir unoinstall.XXXXXX` ++ if [ $? -ne 0 ]; then ++ echo "Could not create tmp dir" >&2 ++ exit 1 ++ fi ++ set -- $@ '-env:UserInstallation=file://'$INSTDIR ++ fi ++fi ++ ++isnotuser=0 ++for arg in $@ ++do ++if [ "$arg" = "--shared" -o "$arg" = "--bundled" ]; then ++ isnotuser=1 ++fi ++done ++if [ $isnotuser -eq 1 ]; then ++ echo $@ | grep -q env:JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY ++ if [ $? -ne 0 ]; then ++ set -- $@ '-env:JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY=1' ++ fi ++ echo $@ | grep -q env:UNO_JAVA_JFW_INSTALL_DATA ++ if [ $? -ne 0 -a -w $sd_prog/../share/config/javasettingsunopkginstall.xml ]; then ++ set -- $@ '-env:UNO_JAVA_JFW_INSTALL_DATA=$$ORIGIN/../share/config/javasettingsunopkginstall.xml' ++ fi ++ echo $@ | grep -q env:UserInstallation ++ if [ $? -ne 0 ]; then ++ INSTDIR=`/bin/mktemp -d --tmpdir unoinstall.XXXXXX` ++ if [ $? -ne 0 ]; then ++ echo "Could not create tmp dir" >&2 ++ exit 1 ++ fi ++ set -- $@ '-env:UserInstallation=file://'$INSTDIR ++ fi ++fi ++ + # extend the ld_library_path for java: javaldx checks the sofficerc for us + if [ -x "${sd_prog}/javaldx" ] ; then + my_path=`"${sd_prog}/javaldx" $BOOTSTRAPVARS \ +@@ -106,6 +153,8 @@ unset XENVIRONMENT + # SAL_NO_XINITTHREADS=true; export SAL_NO_XINITTHREADS + + # execute binary +-exec "$sd_prog/unopkg.bin" "$@" \ ++"$sd_prog/unopkg.bin" "$@" \ + "-env:INIFILENAME=vnd.sun.star.pathname:$sd_prog/redirectrc" +- ++if [ -n "$INSTDIR" ]; then ++ rm -rf $INSTDIR ++fi +-- +2.4.2 + diff --git a/SOURCES/openoffice.org-3.1.0.oooXXXXX.solenv.allowmissing.patch b/SOURCES/openoffice.org-3.1.0.oooXXXXX.solenv.allowmissing.patch new file mode 100644 index 0000000..1e994db --- /dev/null +++ b/SOURCES/openoffice.org-3.1.0.oooXXXXX.solenv.allowmissing.patch @@ -0,0 +1,58 @@ +From eab93c587dd524241f63e885b0e4ac8700da5d16 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 3 Feb 2014 20:31:04 +0100 +Subject: [PATCH] solenv: allow missing files + +--- + solenv/bin/modules/installer/scriptitems.pm | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/solenv/bin/modules/installer/scriptitems.pm b/solenv/bin/modules/installer/scriptitems.pm +index 4c384ce..963ca84 100644 +--- a/solenv/bin/modules/installer/scriptitems.pm ++++ b/solenv/bin/modules/installer/scriptitems.pm +@@ -1133,11 +1133,10 @@ sub remove_Files_Without_Sourcedirectory + + if ( ! $installer::globals::languagepack && !$installer::globals::helppack) + { +- $infoline = "ERROR: Removing file $filename from file list.\n"; ++ $infoline = "WARNING: Removing file $filename from file list.\n"; + push( @installer::globals::logfileinfo, $infoline); + +- push(@missingfiles, "ERROR: File not found: $filename\n"); +- $error_occurred = 1; ++ push(@missingfiles, "WARNING: File not found: $filename\n"); + + next; # removing this file from list, if sourcepath is empty + } +@@ -1145,11 +1144,10 @@ sub remove_Files_Without_Sourcedirectory + { + if (( $onefile->{'ismultilingual'} ) || ( $styles =~ /\bFORCELANGUAGEPACK\b/ )) + { +- $infoline = "ERROR: Removing file $filename from file list.\n"; ++ $infoline = "WARNING: Removing file $filename from file list.\n"; + push( @installer::globals::logfileinfo, $infoline); + +- push(@missingfiles, "ERROR: File not found: $filename\n"); +- $error_occurred = 1; ++ push(@missingfiles, "WARNING: File not found: $filename\n"); + + next; # removing this file from list, if sourcepath is empty + } +@@ -1167,11 +1165,10 @@ sub remove_Files_Without_Sourcedirectory + { + if (( $onefile->{'ismultilingual'} ) || ( $styles =~ /\bFORCEHELPPACK\b/ )) + { +- $infoline = "ERROR: Removing file $filename from file list.\n"; ++ $infoline = "WARNING: Removing file $filename from file list.\n"; + push( @installer::globals::logfileinfo, $infoline); + +- push(@missingfiles, "ERROR: File not found: $filename\n"); +- $error_occurred = 1; ++ push(@missingfiles, "WARNING: File not found: $filename\n"); + + next; # removing this file from list, if sourcepath is empty + } +-- +1.8.4.2 + diff --git a/SPECS/libreoffice.spec b/SPECS/libreoffice.spec new file mode 100644 index 0000000..b341840 --- /dev/null +++ b/SPECS/libreoffice.spec @@ -0,0 +1,3833 @@ +# download path contains version without the last (fourth) digit +%define libo_version 5.0.6 +# Should contain .alphaX / .betaX, if this is pre-release (actually +# pre-RC) version. The pre-release string is part of tarball file names, +# so we need a way to define it easily at one place. +%define libo_prerelease %{nil} +# rhbz#715152 state vendor +%if 0%{?rhel} +%define vendoroption --with-vendor="Red Hat, Inc." +%define libo_use_python3 %{nil} +%define libo_python python +%define libo_python_sitearch %{python_sitearch} +%endif +%if 0%{?fedora} +%define libo_use_python3 1 +%define libo_python python3 +%define libo_python_sitearch %{python3_sitearch} +%define vendoroption --with-vendor="The Fedora Project" +%endif +# rhbz#465664 jar-repacking breaks help by reordering META-INF/MANIFEST.MF +%define __jar_repack %{nil} +# make it easier to download sources from pre-release site +# %%define source_url http://dev-builds.libreoffice.org/pre-releases/src +%define source_url http://download.documentfoundation.org/libreoffice/src/%{libo_version} +# URL for external projects' tarballs +%define external_url http://dev-www.libreoffice.org/src/ +# limit to fedora, as it breaks building of some bundled projects +%if 0%{?fedora} +# default for f23 onwards +%global _hardened_build 1 +%endif +%global girapiversion 0.1 + +# get english only and no-langpacks for a faster smoketest build +# fedpkg compile/install/local/mockbuild does not handle --without ATM, +# so it is necessary to change this to bcond_with to achieve the same +# effect +%bcond_without langpacks + +# remove workdir at the end of %%build, to allow build on space-constrained machines +%ifarch s390 s390x +%bcond_without smallbuild +%else +%bcond_with smallbuild +%endif + +# generated by %%langpack definitions +%global langpack_langs %{nil} + +%global bundling_options %{nil} + +Summary: Free Software Productivity Suite +Name: libreoffice +Epoch: 1 +Version: %{libo_version}.2 +Release: 15%{?libo_prerelease}%{?dist} +License: (MPLv1.1 or LGPLv3+) and LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and Public Domain and ASL 2.0 and Artistic and MPLv2.0 and CC0 +Group: Applications/Productivity +URL: http://www.libreoffice.org/ + +Source0: %{source_url}/libreoffice-%{version}%{?libo_prerelease}.tar.xz +Source1: %{source_url}/libreoffice-help-%{version}%{?libo_prerelease}.tar.xz +Source2: %{source_url}/libreoffice-translations-%{version}%{?libo_prerelease}.tar.xz +Source3: http://dev-www.libreoffice.org/extern/185d60944ea767075d27247c3162b3bc-unowinreg.dll +Source4: libreoffice-multiliblauncher.sh +Source5: %{external_url}/a7983f859eafb2677d7ff386a023bc40-xsltml_2.1.2.zip +Source6: %{external_url}/1f24ab1d39f4a51faf22244c94a6203f-xmlsec1-1.2.14.tar.gz +Source7: %{external_url}/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip +Source8: %{external_url}/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip +#Unfortunately later versions of hsqldb changed the file format, so if we use a later version we loose +#backwards compatability. +Source9: %{external_url}/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip +%global bundling_options %{?bundling_options} --without-system-hsqldb + +%if 0%{?rhel} +Source10: %{external_url}/0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz +%global bundling_options %{?bundling_options} --without-system-ucpp +%endif + +%if 0%{?fedora} +Source40: %{external_url}/4b87018f7fff1d054939d19920b751a0-collada2gltf-master-cb1d97788a.tar.bz2 +%endif + +# symbolic icons +Source42: https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/libreoffice-base-symbolic.svg +Source43: https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/libreoffice-calc-symbolic.svg +Source44: https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/libreoffice-draw-symbolic.svg +Source45: https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/libreoffice-impress-symbolic.svg +Source46: https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/libreoffice-main-symbolic.svg +Source47: https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/libreoffice-math-symbolic.svg +Source48: https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/libreoffice-writer-symbolic.svg + +# build tools +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: bc +BuildRequires: binutils +BuildRequires: bison +%if 0%{?rhel} && 0%{?rhel} < 7 +BuildRequires: chrpath +%endif +BuildRequires: desktop-file-utils +BuildRequires: doxygen +BuildRequires: findutils +BuildRequires: flex +BuildRequires: gcc-c++ +BuildRequires: gdb +BuildRequires: git +BuildRequires: gperf +BuildRequires: icu +BuildRequires: make +BuildRequires: perl(Archive::Zip) +BuildRequires: perl(Digest::MD5) +%if 0%{?fedora} +BuildRequires: libappstream-glib +BuildRequires: ucpp +%endif +BuildRequires: zip + +# libs / headers - common +BuildRequires: %{libo_python}-devel +BuildRequires: boost-devel +BuildRequires: cups-devel +BuildRequires: expat-devel +BuildRequires: fontpackages-devel +BuildRequires: glm-devel +BuildRequires: hyphen-devel +BuildRequires: libicu-devel +BuildRequires: libjpeg-turbo-devel +BuildRequires: lpsolve-devel +BuildRequires: openldap-devel +BuildRequires: pam-devel +BuildRequires: pkgconfig(bluez) +BuildRequires: pkgconfig(cppunit) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(evolution-data-server-1.2) +BuildRequires: pkgconfig(freetype2) +BuildRequires: pkgconfig(gconf-2.0) +BuildRequires: pkgconfig(glew) >= 1.10.0 +BuildRequires: pkgconfig(glu) +BuildRequires: pkgconfig(gobject-introspection-1.0) +BuildRequires: pkgconfig(graphite2) +BuildRequires: pkgconfig(gstreamer-1.0) +BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) +BuildRequires: pkgconfig(gtk+-2.0) +BuildRequires: pkgconfig(gtk+-3.0) +BuildRequires: pkgconfig(harfbuzz) +BuildRequires: pkgconfig(hunspell) +BuildRequires: pkgconfig(ice) +BuildRequires: pkgconfig(lcms2) +BuildRequires: pkgconfig(libabw-0.1) +BuildRequires: pkgconfig(libcdr-0.1) +BuildRequires: pkgconfig(libclucene-core) +BuildRequires: pkgconfig(libcmis-0.5) +BuildRequires: pkgconfig(libcurl) +BuildRequires: pkgconfig(libetonyek-0.1) +BuildRequires: pkgconfig(libexttextcat) +BuildRequires: pkgconfig(libfreehand-0.1) +BuildRequires: pkgconfig(libidn) +BuildRequires: pkgconfig(liblangtag) +BuildRequires: pkgconfig(libmspub-0.1) +BuildRequires: pkgconfig(libmwaw-0.3) +BuildRequires: pkgconfig(libodfgen-0.1) +BuildRequires: pkgconfig(liborcus-0.8) +BuildRequires: pkgconfig(libpagemaker-0.0) +BuildRequires: pkgconfig(librevenge-0.0) +BuildRequires: pkgconfig(libvisio-0.1) +BuildRequires: pkgconfig(libwpd-0.10) +BuildRequires: pkgconfig(libwpg-0.3) +BuildRequires: pkgconfig(libwps-0.3) +BuildRequires: pkgconfig(libxml-2.0) +BuildRequires: pkgconfig(libxslt) +BuildRequires: pkgconfig(mdds) >= 0.12.0 +BuildRequires: pkgconfig(mythes) +BuildRequires: pkgconfig(neon) +BuildRequires: pkgconfig(nss) +BuildRequires: pkgconfig(poppler) +BuildRequires: pkgconfig(poppler-cpp) +BuildRequires: pkgconfig(redland) +BuildRequires: pkgconfig(sane-backends) +BuildRequires: pkgconfig(xext) +BuildRequires: pkgconfig(xinerama) +BuildRequires: pkgconfig(xt) +BuildRequires: pkgconfig(zlib) +BuildRequires: postgresql-devel +BuildRequires: unixODBC-devel +BuildRequires: vigra-devel + + +# libs / headers - conditional +%if 0%{?fedora} +BuildRequires: firebird-devel +BuildRequires: kdelibs4-devel +BuildRequires: openCOLLADA-devel +BuildRequires: pkgconfig(libe-book-0.1) +BuildRequires: pkgconfig(libeot) +BuildRequires: pkgconfig(libgltf-0.0) +%endif + +# java stuff +BuildRequires: ant +BuildRequires: apache-commons-codec +BuildRequires: apache-commons-lang +BuildRequires: bsh +BuildRequires: java-devel +BuildRequires: jakarta-commons-httpclient +BuildRequires: junit +BuildRequires: pentaho-reporting-flow-engine + +# fonts needed for unit tests +BuildRequires: liberation-mono-fonts +BuildRequires: liberation-sans-fonts +BuildRequires: liberation-serif-fonts + +Requires: %{name}-writer = %{epoch}:%{version}-%{release} +Requires: %{name}-calc = %{epoch}:%{version}-%{release} +Requires: %{name}-impress = %{epoch}:%{version}-%{release} +Requires: %{name}-draw = %{epoch}:%{version}-%{release} +Requires: %{name}-math = %{epoch}:%{version}-%{release} +Requires: %{name}-base = %{epoch}:%{version}-%{release} +Requires: %{name}-emailmerge = %{epoch}:%{version}-%{release} + +# not upstreamed +Patch0: openoffice.org-2.4.0.ooo86080.unopkg.bodge.patch +# not upstreamed +Patch1: openoffice.org-3.1.0.oooXXXXX.solenv.allowmissing.patch +# not upstreamed +Patch2: libreoffice-installfix.patch +# not upstreamed +Patch3: 0001-Resolves-rhbz-1035092-no-shortcut-key-for-Italian-To.patch +# not upstreamed +Patch4: 0001-disable-firebird-unit-test.patch +# not upstreamed +Patch5: 0001-never-run-autogen.sh.patch +# not upstreamed +Patch6: 0001-add-X-TryExec-entries-to-desktop-files.patch +# not upstreamed +Patch7: 0001-disable-PSD-import-test-which-deadlocks-on-ARM.patch +# upstreamed +Patch8: 0001-Resolves-tdf-89905-don-t-copy-palettes-from-shared-t.patch +Patch9: 0001-Resolves-tdf-49407-enable-CaseMap-property-in-impres.patch +Patch10: 0001-rhbz-1233420-handle-inexistent-cond.-format.patch +Patch11: 0001-allow-slide-design-to-affect-multiple-standard-pages.patch +Patch12: 0001-implement-equalize-width-and-height-for-impress-draw.patch +Patch13: 0001-f22-openjdk-for-ppc64le-has-both-these-dirs-but-jawt.patch +Patch14: 0001-implement-undo-for-equalize-marked-objects.patch +Patch15: 0001-time-stamp-object-selections-and-use-newest-as-ref-f.patch +Patch16: 0001-Resolves-rhbz-1256843-no-obvious-means-to-close-temp.patch +Patch17: 0001-implement-undo-of-delete-impress-cell-contents.patch +Patch18: 0001-Fix-export-of-tdf-93675-to-.docx-as-much-as-is-possi.patch +Patch19: 0001-default-to-as-character-caption-contents.patch +Patch20: 0001-Related-tdf-93676-msword-wraps-slightly-differently-.patch +Patch21: 0002-Related-tdf-93676-msword-wraps-slightly-differently-.patch +Patch22: 0001-implement-save-slide-background-for-impress.patch +Patch23: 0001-Related-tdf-72880-presumably-using-startcenter-as-ge.patch +Patch24: 0001-implement-dialog-control-over-enhanced-shape-control.patch +Patch25: 0001-tdf-95210-SetHandleControllerPosition-is-busted-wrt-.patch +Patch26: 0001-Resolves-tdf-95682-spell-dialog-add-a-button-to-open.patch +Patch27: 0001-backport-5-1-idle-timers-loop-to-5-0.patch +Patch28: 0001-gtk3-implement-SAL_INVERT_50-rectangle-case.patch +Patch29: 0001-Resolves-tdf-95962-incorrect-scanline-stride.patch +Patch30: 0001-Related-rhbz-1281906-wayland-toolbar-drawn-over-menu.patch +Patch31: 0001-Resolves-rhbz-1285380-get-menus-working-under-waylan.patch +Patch32: 0001-gtk3-wayland-wrong-dialog-sizes.patch +Patch33: 0001-Resolves-rhbz-1289398-unable-to-use-scroll-wheel-und.patch +Patch34: 0001-valgrind-scary-warning-that-the-cairo-font-options-w.patch +Patch35: 0001-gtk3-gtk_gesture_get_point-may-return-false.patch +Patch36: 0001-move-things-around-a-little-to-make-backporting-easi.patch +Patch37: 0001-Resolves-tdf-96285-restore-bodge-for-unresizable-win.patch +Patch38: 0001-gtk3-wayland-dialogs-work-a-lot-better-if-a-min-size.patch +Patch39: 0001-Related-rhbz-1290014-gtk3-use-gtk_window_set_modal-o.patch +Patch40: 0001-Resolves-rhbz-1289394-gtk3-implement-tooltips-native.patch +Patch41: 0001-rhbz-1283420-cairo-text-xrender-bodge.patch +Patch42: 0001-Resolves-rhbz-1287581-explicitly-state-we-don-t-want.patch +Patch43: 0001-gtk3-wayland-enable-manual-movement-of-toolbars.patch +Patch44: 0001-gtk3-stop-the-ever-shrinking-size-of-toplevel-on-eve.patch +Patch45: 0001-Resolves-rhbz-1291925-implement-SAL_INVERT_TRACKFRAM.patch +Patch46: 0001-Related-rhbz-1281906-set-a-min-size-on-un-resizeable.patch +Patch47: 0001-but-only-for-dialog.patch +Patch48: 0001-impress-s-AnnotationWindow-is-the-only-user-of-WB_NE.patch +Patch49: 0002-remove-newly-unused-WB_NEEDSFOCUS-and-fragile-FLOAT_.patch +Patch50: 0003-gtk3-wayland-start-floating-windows-hidden.patch +Patch51: 0001-these-popups-should-start-invisible-and-take-default.patch +Patch52: 0002-disable-tearability-of-color-window.patch +Patch53: 0001-Resolves-tdf-99604-ungrab-modal-dialogs.patch +Patch54: 0001-gtk3-avoid-empty-target-clipboard-warning.patch +Patch55: 0002-Fix-memleak-of-strings-allocated-in-VclGtkClipboard-.patch +Patch56: 0003-Resolves-rhbz-1240591-gtk3-store-clipboard-when-Libr.patch +Patch57: 0001-rerun-autoconf-after-remove-BOOST_SYSTEM.patch +Patch58: 0001-rhbz-1168757-propagate-selected-slides-to-print-dial.patch +Patch59: 0001-Resolves-rhbz-1294208-trackpad-two-finger-scroll-doe.patch +Patch60: 0001-use-the-users-preferred-initials-for-impress-annotat.patch +Patch61: 0001-gtk3-Resolves-tdf-96333-fix-RTL-menu-positioning.patch +Patch62: 0001-tdf-97665-Let-s-hope-that-over-activation-isn-t-real.patch +Patch63: 0001-Resolves-rhbz-1315385-use-preferred-size-if-widget-s.patch +Patch64: 0001-Resolves-tdf-96989-videos-playback-at-maximum-possib.patch +Patch65: 0001-delete-hidden-pages-before-deleting-unused-masters.patch +Patch66: 0001-tdf-39271-allow-to-export-only-notes-pages.patch +Patch67: 0001-Resolves-tdf-91778-drawing-the-background-over-an-ac.patch +Patch68: 0001-Pasting-from-a-pdf-from-a-fallback-font-doesn-t-give.patch +Patch69: 0001-tdf-99460-sw-layout-don-t-split-table-before-fly.patch +Patch70: 0001-Resolves-tdf-99498-don-t-overwrite-trwWidth-value-if.patch +Patch71: 0001-rhbz-1326602-avoid-exp.-bg-bitmaps-from-deleted-slid.patch +Patch72: 0001-Resolves-tdf-99417-explicitly-track-formula-cells-fo.patch +Patch73: 0001-tdf-99353-take-the-footgun-away-from-FilterCache.patch +Patch74: 0001-Resolves-tdf-94146-a11y-crash-obtain-formula-using-t.patch +Patch75: 0001-only-set-cur.-page-once-when-removing-mult.-pages.patch +Patch76: 0001-tdf-86575-for-OOXML-write-plain-REF-if-deleted-parts.patch +Patch77: 0001-improve-perf.-of-VCL-event-dispatch.patch +Patch78: 0001-rtf-m_aStates-can-be-empty-in-the-inner-condition.patch +Patch79: 0001-Resolves-rhbz-1364335-tooltips-are-truncated.patch +Patch80: 0001-lp-1566050-prevent-cyclic-reference-zombies.patch +Patch81: 0001-fix-Link-operator.patch +Patch82: 0001-tdf-80999-Canceling-password-prompt-should-abort-det.patch +Patch83: 0001-Resolves-rhbz-1401082-gnome-hangs-opening-a-certain-.patch +Patch84: 0001-Resolves-tdf-101213-drop-use-of-CAIRO_OPERATOR_DIFFE.patch +Patch85: 0001-disable-generation-of-ole-previews-in-ODF-format-unt.patch +Patch86: 0001-Resolves_rhbz-1437537-fix-csv-a11y.patch +Patch87: 0001-ofz-372-check-if-ImplSplit-succeeded.patch +Patch88: 0001-limit-WEBSERVICE-to-http-s-protocols.patch + +%if 0%{?rhel} +# not upstreamed +Patch500: 0001-disable-libe-book-support.patch +# not upstreamed +Patch501: 0001-Revert-upload-libwps-0.4.0.patch + +# rebase libreofficekit to 5.1 +Patch600: 0002-LOK-remove-unused-LOK_PARTMODE_EMBEDDEDOBJ.patch +Patch601: 0003-Look-for-libsofficeapp.dylib-in-the-right-place-on-O.patch +Patch602: 0004-Don-t-do-any-magic-LO-OS-X-application-stuff-in-a-LO.patch +Patch603: 0005-loplugin-staticmethods.patch +Patch604: 0006-loplugin-cstylecast-deal-with-those-that-are-technic.patch +Patch605: 0007-fsanitize-float-divide-by-zero.patch +Patch606: 0008-LOK-fix-the-rectangle-format-mentioned-in-documentat.patch +Patch607: 0009-loplugin-cstylecast-deal-with-remaining-pointer-cast.patch +Patch608: 0010-lokdocview-add-width-and-height-to-the-visible-recta.patch +Patch609: 0011-lokdocview-use-GtkDrawingArea-for-drawing-tiles.patch +Patch610: 0012-Add-tile-buffering-support.patch +Patch611: 0013-lokdocview-Use-maps-instead-of-vector.patch +Patch612: 0014-lokdocview-Add-support-for-editing-documents.patch +Patch613: 0015-lokdocview-move-commonly-used-functions-and-variable.patch +Patch614: 0016-lokdocview-wrap-a-functionality-inside-a-member-func.patch +Patch615: 0017-lokdocview-tilebuffer-clean-up.patch +Patch616: 0018-lokdocview-fixed-rectangle-format-in-documentation-c.patch +Patch617: 0019-lokdocview-check-payload-for-inconsistencies-before-.patch +Patch618: 0020-lokdocview-move-GtkDrawingArea-size-request-out-of-r.patch +Patch619: 0021-lokdocview-fix-render-calls-after-LOK-callbacks.patch +Patch620: 0022-lokdocview-Let-G_BEGIN-END_DECLS-handle-the-compiler.patch +Patch621: 0023-lokdocview-Lets-follow-the-GObject-naming-convention.patch +Patch622: 0024-lokdocview-Modernise-LOKDocView-as-GObject.patch +Patch623: 0025-lokdocview-mark-_get_type-with-const-function-attrib.patch +Patch624: 0026-libreofficekit-fix-RHEL5-build-of-tilebuffer.patch +Patch625: 0027-lokdocview-Make-tilebuffer-an-instance.patch +Patch626: 0028-tilebuffer-ZoomFactor-as-member-variable-is-superflu.patch +Patch627: 0029-tilebuffer-tileSize-as-member-variable-is-superfluou.patch +Patch628: 0030-Werror-Wunused-private-field.patch +Patch629: 0031-loplugin-literaltoboolconversion.patch +Patch630: 0032-loplugin-unreffun.patch +Patch631: 0033-Werror-Wignored-attributes-attribute-declaration-mus.patch +Patch632: 0034-loplugin-unreffun-workaround-for-visibility-adding-r.patch +Patch633: 0035-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch +Patch634: 0036-sw-tiled-rendering-set-minimal-window-size.patch +Patch635: 0037-Revert-sw-LOK_CALLBACK_CURSOR_VISIBLE-callback.patch +Patch636: 0038-CID-1306215-Uninitialized-members.patch +Patch637: 0039-lokdocview-Change-parent-class-to-GtkDrawingArea.patch +Patch638: 0040-lokdocview-Make-this-GObject-class-introspectable.patch +Patch639: 0041-lokdocview-Create-LOK-context-inside-of-lok_doc_view.patch +Patch640: 0042-Fix-RHEL5-build.patch +Patch641: 0043-cppcheck-postfixOperator.patch +Patch642: 0044-Typo.patch +Patch643: 0045-lokdocview-gtktiledviewer-Port-to-gtk3.patch +Patch644: 0046-lokdocview-Port-to-gtk3-expose-event-draw.patch +Patch645: 0047-lokdocview-gtktiledviewer-Remove-gtk-version-checks.patch +Patch646: 0048-gtktiledviewer-Replace-deprecated-Gtk-functions.patch +Patch647: 0049-Repository.mk-libreofficekitgtk-is-conditional-on-EN.patch +Patch648: 0050-lokdocview-Restructure-this-GObject-class.patch +Patch649: 0051-Superfluous-block-lets-merge-into-one.patch +Patch650: 0052-lokdocview-couple-for-missing-static_cast-GParamFlag.patch +Patch651: 0053-gtktiledviewer-add-copy-button.patch +Patch652: 0054-gtktiledviewer-do-HTML-copying-if-possible.patch +Patch653: 0055-lokdocview-Use-GInitable.patch +Patch654: 0056-lokdocview-Use-get_instance_private-to-get-private-s.patch +Patch655: 0057-lokdocview-fixed-a-signal-name.patch +Patch656: 0058-cppcheck-noExplicitConstructor.patch +Patch657: 0059-lokdocview-Don-t-handle-hyperlink-clicks.patch +Patch658: 0060-lokdocview-Remove-superfluous-_post_key.patch +Patch659: 0061-tilebuffer-Add-timer-to-measure-paintTile-call.patch +Patch660: 0062-lokdocview-Handle-DELETE-key.patch +Patch661: 0063-gtktiledviewer-Don-t-continue-on-widget-init-failure.patch +Patch662: 0064-g_assert_nonnull-was-not-declared.patch +Patch663: 0065-LOK-Don-t-try-to-absolutize-URL-s.patch +Patch664: 0066-LOK-Cleanup-absolutizing-of-URLs.patch +Patch665: 0067-LOK-Corner-case-with-working-dir-as.patch +Patch666: 0068-lokdocview-Grab-focus-on-mouse-button-press-event.patch +Patch667: 0069-vcl-ITiledRenderable-getTextSelection-can-be-pure-vi.patch +Patch668: 0070-With-enable-gtk3-we-need-GLib-2.38.patch +Patch669: 0071-gtktiledviewer-method-for-resetting-all-tiles.patch +Patch670: 0072-lokdocview-Call-open_document-in-another-thread.patch +Patch671: 0073-lokdocview-Emit-load-changed-signal-showing-load-pro.patch +Patch672: 0074-gtktiledviewer-Fill-whole-statusbar-with-progressbar.patch +Patch673: 0075-lokdocview-Use-a-thread-pool-for-most-LOK-calls.patch +Patch674: 0076-lokdocview-Make-paintTile-async.patch +Patch675: 0077-lokdocview-tilebuffer-Add-DOxygen-comments.patch +Patch676: 0078-Use-thread-pool-for-LOK-call-paintTile.patch +Patch677: 0079-lokdocview-Cannot-use-same-GTask-object-for-all-call.patch +Patch678: 0080-lokdocview-Follow-the-camelCase-naming-convention.patch +Patch679: 0081-lokdocview-Use-only-one-ctor-for-instantiating-LOEve.patch +Patch680: 0082-lokdocview-Move-postMouseEvent-in-separate-LOK-threa.patch +Patch681: 0083-lokdocview-setGraphicSelection-in-another-thread.patch +Patch682: 0084-lokdocview-post_command-arguments-are-not-supposed-t.patch +Patch683: 0085-libreofficekit-Werror-Wformat-security.patch +Patch684: 0086-LOK-Implement-parts-for-Writer-too.patch +Patch685: 0087-Removed-some-whole-page-invalidations-in-impress.patch +Patch686: 0088-coverity-1315075-Uninitialized-pointer-field.patch +Patch687: 0089-lokdocview-Don-t-use-extern-variable-lokThreadPool.patch +Patch688: 0090-LOKit-set-thread-name-lo_startmain.patch +Patch689: 0091-tdf-93154-Save-button-often-does-not-save.patch +Patch690: 0092-sc-LOK_CALLBACK_DOCUMENT_SIZE_CHANGED-callback.patch +Patch691: 0093-sc-fix-LOKit-invalidate-setPart.patch +Patch692: 0094-gtktiledviewer-Jump-to-cursor-position-when-it-chang.patch +Patch693: 0095-lok-Document-getStyles-method.patch +Patch694: 0096-lok-namespace-and-re-work-various-types-helper-funct.patch +Patch695: 0097-Fix-incomplete-g-i-annotations.patch +Patch696: 0098-log-resource-usage-of-unit-tests-on-UNX-platforms.patch +Patch697: 0099-sal-don-t-use-target-as-parameter-to-cppunittester.patch +Patch698: 0100-LOK-added-a-general-getCommandValues-method.patch +Patch699: 0101-LOK-allow-float-numbers-in-json-property-value-conve.patch +Patch700: 0102-Revert-LOK-added-a-general-getCommandValues-method.patch +Patch701: 0103-LOK-moved-the-decalaration-of-LibLODocument_Impl-to-.patch +Patch702: 0104-desktop-enable-CppunitTest_desktop_lib-only-on-Linux.patch +Patch703: 0105-LOK-added-a-general-getCommandValues-method.patch +Patch704: 0106-LOK-getFonts-method.patch +Patch705: 0107-lokdocview-GTK-calls-should-be-made-from-the-main-th.patch +Patch706: 0108-LOK-don-t-use-unstable-API-unconditionally-when-incl.patch +Patch707: 0109-LOK-Implement-an-own-trivial-InteractionHandler.patch +Patch708: 0110-create_tree.sh-Generate-g-i-files.patch +Patch709: 0111-get-feedback-for-style-font-font-size-in-tiledrender.patch +Patch710: 0112-lok-initialize-UNO-url-command-dispatch.patch +Patch711: 0113-LOK-Sync-the-list-of-commands-we-initialize-with-tho.patch +Patch712: 0114-LOK-Avoid-crash-when-the-command-is-not-available-in.patch +Patch713: 0115-tdf-94237-tiled-rendering-Use-the-entire-document-as.patch +Patch714: 0116-sysui-depend-on-libreofficekitgtk-for-introspection.patch +Patch715: 0117-vcl-ITiledRenderable-add-getCurrentViewShell-and-imp.patch +Patch716: 0118-sfx2-add-SfxLokHelper.patch +Patch717: 0119-lok-Document-add-createView.patch +Patch718: 0120-gtktiledviewer-add-button-tooltips.patch +Patch719: 0121-lok-Office-add-getViews.patch +Patch720: 0122-CppunitTest_desktop_lib-fix-reported-name-of-failed-.patch +Patch721: 0123-lok-Document-add-destroyView.patch +Patch722: 0124-sfx2-add-missing-header-guard.patch +Patch723: 0125-gtktiledviewer-these-globals-can-be-static.patch +Patch724: 0126-gtktiledviewer-allow-multiple-DocView-instances.patch +Patch725: 0127-gtktiledviewer-allow-multiple-status-bars.patch +Patch726: 0128-gtktiledviwer-allow-GtkToolItems-in-multiple-windows.patch +Patch727: 0129-gtktiledviwer-tool-item-registration-is-per-window.patch +Patch728: 0130-gtktiledviewer-allow-part-selector-in-multiple-windo.patch +Patch729: 0131-gtktiledviewer-allow-findbar-in-multiple-windows.patch +Patch730: 0132-lokdocview-allow-not-calling-documentLoad.patch +Patch731: 0133-gtktiledviewer-factor-out-createWindow-from-main.patch +Patch732: 0134-gtktiledviewer-factor-out-setupDocView-from-main.patch +Patch733: 0135-gtktiledviewer-set-up-a-new-GtkWindow-for-a-new-view.patch +Patch734: 0136-lokdocview-avoid-GTK-calls-in-openDocumentInThread.patch +Patch735: 0137-lokdocview-set-up-the-widget-in-all-windows.patch +Patch736: 0138-gtktiledviewer-add-setupWidgetAndCreateWindow-to-avo.patch +Patch737: 0139-lok-Document-add-get-setView.patch +Patch738: 0140-Use-SfxViewFrame-Current.patch +Patch739: 0141-gtktiledviewer-use-setView-before-postKeyEvent.patch +Patch740: 0142-LOK-make-getViews-be-a-member-function-of-Document.patch +Patch741: 0143-LOK-allow-postMouseEvent-in-multiple-views.patch +Patch742: 0144-Add-missing-lok-Document-setPartMode-wrapper.patch +Patch743: 0145-lokdocview-set-view-before-calling-lok-Document-memb.patch +Patch744: 0146-SfxLokHelper-setView-check-if-view-is-already-curren.patch +Patch745: 0147-sfx2-add-SfxViewShell-libreOfficeKitViewCallback.patch +Patch746: 0148-comphelper-add-LibreOfficeKit-set-isViewCallback.patch +Patch747: 0149-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_TILES.patch +Patch748: 0150-lok-Document-register-callback-in-the-view-if-reques.patch +Patch749: 0151-sw-implement-per-view-LOK_CALLBACK_INVALIDATE_VISIBL.patch +Patch750: 0152-gtktiledviewer-don-t-crash-on-opening-non-existing-f.patch +Patch751: 0153-gtktiledviewer-fix-leftover-import-progressbar-in-cr.patch +Patch752: 0154-sw-implement-per-view-LOK_CALLBACK_TEXT_SELECTION.patch +Patch753: 0155-sw-implement-per-view-LOK_CALLBACK_CURSOR_VISIBLE.patch +Patch754: 0156-CppCheck-reduce-variables-scope.patch +Patch755: 0157-lok-add-Office-getFilterTypes.patch +Patch756: 0158-desktop-make-LibLibreOffice_Impl-visible-to-testcase.patch +Patch757: 0159-fix-build.patch +Patch758: 0160-Add-lok-Office-getFilterTypes-testcase.patch +Patch759: 0161-Move-all-introspection-comments-to-header-file.patch +Patch760: 0162-sd-tiled-rendering-avoid-passing-explicit-0-vcl-Wind.patch +Patch761: 0163-libreofficekit-fix-mismatched-free-delete.patch +Patch762: 0164-lok-add-Document-getPartPageRectangles.patch +Patch763: 0165-coverity-1325053-Dereference-after-null-check.patch +Patch764: 0166-lokdocview-Reset-view-completely.patch +Patch765: 0167-Impress-set-current-page-Id-before-showing-the-new-p.patch +Patch766: 0168-desktop-vcl-support-transparency-in-VirtualDevices-w.patch +Patch767: 0169-sw-tiled-rendering-default-to-transparent-background.patch +Patch768: 0170-vcl-tiled-rendering-avoid-Pixel-represents-color-val.patch +Patch769: 0171-desktop-handle-sal_uInt16-in-jsonToPropertyValues.patch +Patch770: 0172-LOK-add-CALLBACK_SEARCH_RESULT_COUNT-and-implement-i.patch +Patch771: 0173-lokdocview-handle-LOK_CALLBACK_SEARCH_RESULT_COUNT.patch +Patch772: 0174-gtktiledviewer-make-it-possible-to-trigger-SearchIte.patch +Patch773: 0175-LOK-added-the-button-type-and-key-modifier-to-postMo.patch +Patch774: 0176-CppunitTest_sw_tiledrendering-testcase-for-LOK_CALLB.patch +Patch775: 0177-LOK-add-the-search-phrase-to-the-search-result-count.patch +Patch776: 0178-LOK-fixed-duplicated-switch-case-values.patch +Patch777: 0179-LOK-add-CALLBACK_SEARCH_RESULT_SELECTION-and-impleme.patch +Patch778: 0180-gtktiledviewer-recognize-LOK_CALLBACK_SEARCH_RESULT_.patch +Patch779: 0181-CppunitTest_sw_tiledrendering-CALLBACK_SEARCH_RESULT.patch +Patch780: 0182-lokdocview-log-paintTile-arguments.patch +Patch781: 0183-sw-outline-SwViewOption-SetOnlineSpell.patch +Patch782: 0184-Disable-spellcheck-when-LOK-is-active.patch +Patch783: 0185-sw-extract-lcl_emitSearchResultCallbacks-from-SwView.patch +Patch784: 0186-sw-tiled-rendering-emit-LOK_CALLBACK_SEARCH_RESULT-f.patch +Patch785: 0187-libreofficekit-Werror-unused-macros.patch +Patch786: 0188-lokdocview-invalidate-after-selection-change.patch +Patch787: 0189-sc-tiled-rendering-fix-showing-all-search-results.patch +Patch788: 0190-Make-this-compile-for-iOS-again.patch +Patch789: 0191-comphelper-add-string-join.patch +Patch790: 0192-sc-tiled-rendering-no-need-to-show-this-dialog.patch +Patch791: 0193-lok-Document-initializeForRendering-handle-lack-of-l.patch +Patch792: 0194-CppunitTest_desktop_lib-add-Calc-find-all-testcase.patch +Patch793: 0195-editeng-sw-sc-use-comphelper-string-join.patch +Patch794: 0196-sc-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch +Patch795: 0197-LOK-CALLBACK_SEARCH_RESULT_COUNT-is-redundant.patch +Patch796: 0198-lokdocview-log-postUnoCommand-arguments.patch +Patch797: 0199-gtktiledviewer-drop-tiles-on-set-part-event.patch +Patch798: 0200-sd-tiled-rendering-make-invalidation-in-DrawViewShel.patch +Patch799: 0201-tdf-95002-sd-tiled-rendering-fix-handling-of-images-.patch +Patch800: 0202-disable-test-that-causes-inf.-loop.patch +Patch801: 0203-sd-tiled-rendering-implement-LOK_CALLBACK_SEARCH_RES.patch +Patch802: 0204-CppunitTest_sd_tiledrendering-CALLBACK_SEARCH_RESULT.patch +Patch803: 0205-Bump-gtk-version-to-2.18.patch +Patch804: 0206-sd-tiled-rendering-initial-search-all.patch +Patch805: 0207-sd-tiled-rendering-search-rectangle-is-part-specific.patch +Patch806: 0208-LOK-include-part-numbers-in-CALLBACK_SEARCH_RESULT_S.patch +Patch807: 0209-lok-Document-paintTile-fix-non-rectangular-tiles-wrt.patch +Patch808: 0210-sd-tiled-rendering-let-find-all-at-least-select-the-.patch +Patch809: 0211-sd-tiled-rendering-implement-CALLBACK_SET_PART-for-f.patch +Patch810: 0212-vcl-aAlphaBitmap.ImplGetImpBitmap-seen-as-0.patch +Patch811: 0213-editeng-tiled-rendering-avoid-selections-callbacks-i.patch +Patch812: 0214-sd-tiled-rendering-emit-CALLBACK_TEXT_SELECTION-on-m.patch +Patch813: 0215-editeng-add-EditView-GetSelectionRectangles.patch +Patch814: 0216-disable-failing-test.patch +Patch815: 0217-lok-svg-export-Default-to-exporting-all-slides-use-t.patch +Patch816: 0218-lok-Document-saveAs-add-Writer-Impress-Draw-png-mapp.patch +Patch817: 0219-Add-DLOPEN_LIBS-to-configure-for-some-cases-where-ld.patch +Patch818: 0220-sc-initial-png-export.patch +Patch819: 0221-lokdocview-Use-G_PARAM_STATIC_STRINGS.patch +Patch820: 0222-lok-Avoid-adding-to-recent-documents-completely.patch +Patch821: 0223-lokdocview-Emit-a-warning-after-error.patch +Patch822: 0224-vcl-add-ITiledRenderable-getWindow-and-implement-in-.patch +Patch823: 0225-LOK-add-Document-paste.patch +Patch824: 0226-gtktiledviewer-initial-paste-support.patch +Patch825: 0227-desktop-add-lok-Document-paste-testcase.patch +Patch826: 0228-loplugin-defaultparams.patch +Patch827: 0229-vcl-ITiledRenderable-getWindow-can-be-pure-virtual-n.patch +Patch828: 0230-lok-Document-paste-check-if-the-given-mime-type-is-s.patch +Patch829: 0231-sc-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch +Patch830: 0232-vcl-add-Window-SetClipboard.patch +Patch831: 0233-lok-clipboard-support-rich-text-paste.patch +Patch832: 0234-gtktiledviwer-try-to-paste-as-html-then-as-plain-tex.patch +Patch833: 0235-sw-tiled-rendering-don-t-offer-HTML-paste-for-shape-.patch +Patch834: 0236-fix-includes-that-are-not-stand-alone.patch +Patch835: 0237-sd-implement-vcl-ITiledRenderable-getWindow.patch +Patch836: 0238-sd-implement-vcl-ITiledRenderable-isMimeTypeSupporte.patch +Patch837: 0239-vcl-getWindow-setClipboard-in-ITiledRenderable.patch +Patch838: 0240-LOK-font-back-color-feedback.patch +Patch839: 0241-LOK-font-back-color-callback-use-sal_Int32-instead-o.patch +Patch840: 0242-lokdocview-ensure-private-structure-is-allocated-wit.patch +Patch841: 0243-LOK-initial-Document-getCommandValues-for-RowColumnH.patch +Patch842: 0244-gtktiledviewer-initial-row-headers-for-spreadsheet-d.patch +Patch843: 0245-loplugin-staticmethods.patch +Patch844: 0246-gtktiledviewer-initial-column-headers-for-spreadshee.patch +Patch845: 0247-gtktiledviewer-add-missing-spreadsheet-corner-button.patch +Patch846: 0248-loplugin-staticmethods.patch +Patch847: 0249-sc-lok-Always-provide-a-reasonable-document-size.patch +Patch848: 0250-lokdocview-Fix-memory-leaks.patch +Patch849: 0251-android-don-t-use-alpha-VDev-when-painting-tiles-on-.patch +Patch850: 0252-add-LOKit-interface-missing-description.patch +Patch851: 0253-gtktiledviewer-add-a-few-more-trivial-buttons-and-br.patch +Patch852: 0254-ScTabView-getRowColumnHeaders-include-info-about-col.patch +Patch853: 0255-ScTabView-getRowColumnHeaders-emit-info-about-last-f.patch +Patch854: 0256-sc-lok-emit-RowColumnHeader-info-in-twips.patch +Patch855: 0257-gtktiledviewer-show-zoom-in-the-status-bar.patch +Patch856: 0258-sc-lok-fix-rounding-errors-with-non-100-zoom.patch +Patch857: 0259-LOK-make-use-of-MOUSEMOVE-in-calc.patch +Patch858: 0260-gtktiledviewer-adjust-spreadsheet-row-column-headers.patch +Patch859: 0261-lokdocview-Separate-painting-and-saving-of-tiles.patch +Patch860: 0262-libreofficekit-Werror-unused-parameter.patch +Patch861: 0263-lok-Fix-typo-search-result_count-search-result-count.patch +Patch862: 0264-lok-Introduce-LOK_CALLBACK_UNO_COMMAND_RESULT-callba.patch +Patch863: 0265-build-fix.patch +Patch864: 0266-sc-lok-allow-requesting-row-headers-only-for-a-logic.patch +Patch865: 0267-sc-lok-allow-requesting-column-headers-only-for-a-lo.patch +Patch866: 0268-Werror-Wformat-security.patch +Patch867: 0269-sc-lok-avoid-placeholder-row-when-providing-all-head.patch +Patch868: 0270-lok-Unit-test-for-LOK_CALLBACK_UNO_COMMAND_RESULT.patch +Patch869: 0271-lok-Fix-crash-due-to-non-initialized-callback.patch +Patch870: 0272-Werror-Wformat-security.patch +Patch871: 0273-sc-lok-return-absolute-positions-for-row-column-head.patch +Patch872: 0274-CppunitTest_desktop_lib-test-absolute-positions-for-.patch +Patch873: 0275-lokdocview-Don-t-render-tiles-while-tile-buffer-has-.patch +Patch874: 0276-sc-lok-Cell-Cursor-callback.patch +Patch875: 0277-sc-lok-Cache-viewdata-zoom-and-reuse-for-cursor-call.patch +Patch876: 0278-sc-lok-make-cell-cursor-behaviour-consistent-with-de.patch +Patch877: 0279-sc-lok-tdf-94605-introduce-uno-CellCursor.patch +Patch878: 0280-sc-lok-update-parameter-syntax-for-.uno-CellCursor.patch +Patch879: 0281-sw-tiled-rendering-initial-annotation-support.patch +Patch880: 0282-sw-lok-annotations-paint-all-child-window.patch +Patch881: 0283-gtktiledviewer-larger-default-window-size.patch +Patch882: 0284-sw-lok-annotations-disable-the-scrollbar-for-now.patch +Patch883: 0285-sc-lok-annotations-paint-range-and-anchor-overlay.patch +Patch884: 0286-Revert-sc-lok-Cache-viewdata-zoom-and-reuse-for-curs.patch +Patch885: 0287-gtktiledviewer-add-Ctrl-Alt-Shift-shortcut-support.patch +Patch886: 0288-sc-lok-Add-initial-test-for-.uno-CellCursor.patch +Patch887: 0289-sc-lok-add-missing-commandName.patch +Patch888: 0290-lokdocview-assert-that-loading-of-handle-bitmaps-suc.patch +Patch889: 0291-loplugin-nullptr-automatic-rewrite.patch +Patch890: 0292-loplugin-nullptr-automatic-rewrite.patch +Patch891: 0293-Keep-LibreOfficeKit.hxx-compatible-with-C-03.patch +Patch892: 0294-Add-a-check-for-non-LIBO_INTERNAL_ONLY-C-03-compatib.patch +Patch893: 0295-Missing-include-for-NULL.patch +Patch894: 0296-gtktiledviewer-don-t-hide-cursor-after-doc-size-chan.patch +Patch895: 0297-sw-lok-fix-width-of-the-notes-sidebar.patch +Patch896: 0298-Avoid-Werror-pedantic-when-building-CppunitTest_libr.patch +Patch897: 0299-sw-lok-fix-length-of-the-line-overlay-above-the-note.patch +Patch898: 0300-This-PixelToLogic-call-can-be-conditional-in-SwSideb.patch +Patch899: 0301-sd-lok-ccu-1295-force-async-image-swap.patch +Patch900: 0302-Implement-LOK_CALLBACK_MOUSE_POINTER.patch +Patch901: 0303-lokdocview-support-LOK_CALLBACK_MOUSE_POINTER.patch +Patch902: 0304-sw-lok-fix-sidebarwindows-SwSidebarWin-pixel-positio.patch +Patch903: 0305-lok-add-Clear-formatting-to-getStyles.patch +Patch904: 0306-lok-sw-Place-default-styles-at-top-of-style-selector.patch +Patch905: 0307-sw-lok-route-SwEditWin-MouseButtonDown-to-SidebarTex.patch +Patch906: 0308-fix-build.patch +Patch907: 0309-fix-build.patch +Patch908: 0310-lok-send-list-of-commands-instead-of-ClearStyles.patch +Patch909: 0311-Use-std-vector-instead-of-an-array-of-strings.patch +Patch910: 0312-More-range-based-for.patch +Patch911: 0313-sw-lok-filter-out-defalt-styles-to-avoid-duplicates.patch +Patch912: 0314-sw-lok-forward-key-events-to-annotation-window-if-ne.patch +Patch913: 0315-lok-Use-reference-instead-of-copy-constructing-in-ra.patch +Patch914: 0316-LOK-setClientZoom-sets-the-client-zoom-level.patch +Patch915: 0317-LOK-calc-formula-callback-formula-bar-implementation.patch +Patch916: 0318-libreofficekit-loplugin-cstylecast.patch +Patch917: 0319-sw-don-t-show-main-cursor-when-editing-a-postit.patch +Patch918: 0320-loplugin-nullptr.patch +Patch919: 0321-sc-lok-during-tiled-rendering-the-cell-cursor-is-alw.patch +Patch920: 0322-editeng-lok-respect-origin-of-map-mode-for-INVALIDAT.patch +Patch921: 0323-sw-lok-fix-blinking-cursor-position-of-comments.patch +Patch922: 0324-editeng-lok-respect-origin-of-map-mode-for-TEXT_SELE.patch +Patch923: 0325-sw-lok-disable-comment-menu-button-for-now.patch +Patch924: 0326-sw-lok-comments-fix-position-of-blinking-cursor-afte.patch +Patch925: 0327-sw-lok-comments-emit-invalidation-events-in-SidebarT.patch +Patch926: 0328-sw-lok-comments-implement-setTextSelection-API.patch +Patch927: 0329-sw-lok-comments-fix-callback-of-newly-created-outlin.patch +Patch928: 0330-sw-lok-comments-fix-cursor-position-of-a-newly-creat.patch +Patch929: 0331-sw-lok-comments-implement-mouse-move-and-mouse-up.patch +Patch930: 0332-gtktiledviewer-the-formula-bar-is-calc-only.patch +Patch931: 0333-gtktiledviewer-add-toolbar-buttons-to-insert-delete-.patch +Patch932: 0334-CppunitTest_sw_tiledrendering-replace-various-ifdefs.patch +Patch933: 0335-CppunitTest_desktop_lib-add-Writer-comments-textcase.patch +Patch934: 0336-sc-lok-use-client-zoom-for-ViewRowColumnHeaders.patch +Patch935: 0337-sw-lok-comments-fix-sidebar-width-with-custom-zoom.patch +Patch936: 0338-sw-lok-comments-fix-text-selection-with-custom-zoom.patch +Patch937: 0339-sw-lok-comments-fix-comment-widget-width-with-custom.patch +Patch938: 0340-sw-lok-comments-fix-meta-author-data-size-with-custo.patch +Patch939: 0341-sw-lok-comments-implement-clipboard-copy.patch +Patch940: 0342-gtktiledviewer-set-author-name-when-inserting-a-comm.patch +Patch941: 0343-lok-Document-initializeForRendering-support-init.-ar.patch +Patch942: 0344-vcl-ITiledRenderable-initializeForTiledRendering-sup.patch +Patch943: 0345-gtktiledviewer-allow-passing-initializeForRendering-.patch +Patch944: 0346-sw-lok-comments-don-t-paint-hidden-comment-sub-widge.patch +Patch945: 0347-editeng-lok-invalidate-on-scroll.patch +Patch946: 0348-sw-lok-comments-optimize-sidebar-text-control-invali.patch +Patch947: 0349-gtktiledviewer-allow-setting-custom-background-color.patch +Patch948: 0350-Werror-Wdeprecated-declarations.patch +Patch949: 0351-sw-lok-comments-implement-painting-of-the-vertical-s.patch +Patch950: 0352-LOK-add-Document-getTileMode.patch +Patch951: 0353-sw-lok-comments-fix-vertical-scrollbar-with-custom-z.patch +Patch952: 0354-updae-getTileMode.patch +Patch953: 0355-vcl-lok-fix-scrollbar-to-accept-mouse-events-in-twip.patch +Patch954: 0356-sw-lok-comments-handle-mouse-up-down-events-on-the-v.patch +Patch955: 0357-desktop-fix-LOK_DEBUG-rectangle-painting.patch +Patch956: 0358-sw-lok-comments-fix-missing-invalidations-from-the-s.patch +Patch957: 0359-vcl-lok-handle-tracking-coordinates-which-are-in-twi.patch +Patch958: 0360-sw-lok-comments-implement-drag-of-the-scrollbar.patch +Patch959: 0361-sw-lok-comments-avoid-crash-an-exit-after-clicking-t.patch +Patch960: 0362-sw-lok-comments-fix-map-mode-state-after-changing-zo.patch +Patch961: 0363-tdf-96243-don-t-crash-if-LibO-install.-wasn-t-found.patch +Patch962: 0364-improve-error-message-for-nonexist.-path.patch +Patch963: 0365-tdf-96246-Make-pRenderingArguments-nullable.patch +Patch964: 0366-tdf-96250-desktop-empty-str-is-the-same-as-0-str-in-.patch +Patch965: 0367-tdf-96316-Decouple-view-only-editable-modes.patch +Patch966: 0368-tdf-96318-Add-searching-API.patch +Patch967: 0369-lokdocview-Set-a-default-path-for-LOK-init.patch +Patch968: 0370-tdf-96317-Add-API-for-copy-paste-from-to-the-widget.patch +Patch969: 0371-tdf-96384-Add-a-new-signal-text-selection-to-lokdocv.patch +Patch970: 0372-tdf-96250-LOK-guard-against-0-pRenderingArguments.patch +Patch971: 0373-lokdocview-Remove-an-easy-FIXME.patch +Patch972: 0374-lokdocview-Superfluous-_set_zoom-call-on-widget-init.patch +Patch973: 0375-lokdocview-Use-GLib-basic-types.patch +Patch974: 0376-lokdocview-Added-some-missing-comments-annotations.patch +Patch975: 0377-lokdocview-Return-if-no-document-is-set.patch +Patch976: 0378-coverity-1343631-Resource-leak.patch +Patch977: 0379-coverity-1343632-Resource-leak.patch +Patch978: 0380-coverity-1343633-Resource-leak.patch +Patch979: 0381-coverity-1315075-Uninitialized-scalar-field.patch +Patch980: 0382-lokdocview-Use-an-array-to-install-properties.patch +Patch981: 0383-tdf-96514-Emits-a-notify-signal-when-zoom-changes.patch +Patch982: 0384-lokdocview-Use-shared_ptr-to-fix-a-possible-memory-l.patch +Patch983: 0385-tdf-96421-Return-if-no-window-is-realized.patch +Patch984: 0386-lokdocview-Fix-WARNING-when-creating-an-error.patch +Patch985: 0387-tdf-96513-Limit-LOKDocView-s-zoom-in-0.25-5.0.patch +Patch986: 0388-lokdocview-Center-the-widget-inside-the-allocation.patch +Patch987: 0389-libreofficekit-password-interaction-optional-and-off.patch +Patch988: 0390-libreofficekit-fix-inverted-condition.patch +Patch989: 0391-Missing-include.patch +Patch990: 0392-lokdocview-Handle-password-protected-documents.patch +Patch991: 0393-lok-fix-saveAs-for-a-loaded-HTML-document.patch +Patch992: 0394-lokdocview-Center-the-widget-vertically-inside-the-a.patch +Patch993: 0395-WaE-buggy-warning-in-vs2015-r1.patch +Patch994: 0396-gtktiledviewer-needs-gtk3-not-gtk2.patch +Patch995: 0397-tdf-99314-lokdocview-add-new-userprofileurl-property.patch +Patch996: 0398-fix-build.patch +Patch997: 0001-sysui-g-ir-scanner-is-not-available-in-when-introspe.patch +Patch998: 0002-sysui-introspection-wants-INSTDIR-not-DESTDIR-INSTAL.patch +Patch999: 0001-vcl-assign-nullptr-after-deleting.patch +Patch1000: 0001-Move-SolarMutex-down-from-tools-to-comphelper-to-mak.patch +Patch1001: 0002-vcl-add-isInitVCL-to-not-initialize-twice.patch +Patch1002: 0003-gnome-documents-rework-SfxPickList-as-pimpl.patch +Patch1003: 0004-rhbz-1444437-gnome-documents-finalize-may-not-occur-.patch +Patch1004: 0005-gnome-documents-hold-solarmutex-on-dtor-patch-as-wel.patch +Patch1005: 0006-Resolves-rhbz-144437-make-gnome-documents-not-crash-.patch +Patch1006: 0001-gtktiledviewer-allow-testing-of-destroyView.patch +Patch1007: 0001-Resolves-rhbz-1454693-segv-on-interrupting-tiled-ren.patch +#end rebase + +%endif + +%define instdir %{_libdir} +%define baseinstdir %{instdir}/libreoffice +%define sdkinstdir %{baseinstdir}/sdk +%define fontname opensymbol + +%description +LibreOffice is an Open Source, community-developed, office productivity suite. +It includes the key desktop applications, such as a word processor, +spreadsheet, presentation manager, formula editor and drawing program, with a +user interface and feature set similar to other office suites. Sophisticated +and flexible, LibreOffice also works transparently with a variety of file +formats, including Microsoft Office File Formats. + +%package filters +Summary: All import / export filters +Group: Applications/Productivity +Requires: %{name}-calc = %{epoch}:%{version}-%{release} +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-draw = %{epoch}:%{version}-%{release} +Requires: %{name}-graphicfilter = %{epoch}:%{version}-%{release} +Requires: %{name}-impress = %{epoch}:%{version}-%{release} +Requires: %{name}-math = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Requires: %{name}-writer = %{epoch}:%{version}-%{release} +Requires: %{name}-xsltfilter = %{epoch}:%{version}-%{release} + +%description filters +Metapackage to pull in all subpackages that contain import or export +filters. + +%package core +Summary: Core modules for LibreOffice +Group: Applications/Productivity +Requires: %{name}-%{fontname}-fonts = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Requires: liberation-sans-fonts >= 1.0, liberation-serif-fonts >= 1.0, liberation-mono-fonts >= 1.0 +Requires: dejavu-sans-fonts, dejavu-serif-fonts, dejavu-sans-mono-fonts +Requires: google-crosextra-caladea-fonts, google-crosextra-carlito-fonts +Requires: hyphen-en, hyphen >= 2.4, autocorr-en +# rhbz#949106 libreoffice-core drags in both openjdk 1.7.0 and 1.8.0 +Requires: java-headless >= 1:1.6 +Requires: hunspell-en-US +Requires(pre): gtk2 >= 2.9.4 +Requires(post): gtk2 >= 2.9.4 +Requires(preun): gtk2 >= 2.9.4 +Requires(postun): gtk2 >= 2.9.4 +Obsoletes: libreoffice-appdata < 1:4.3.3.0 +Obsoletes: libreoffice-binfilter < 1:4.0.0.0 +Obsoletes: libreoffice-headless < 1:4.4.0.0 +Obsoletes: libreoffice-javafilter < 1:4.1.0.0 +Obsoletes: openoffice.org-core < 1:3.3.1 +Obsoletes: openoffice.org-brand < 1:3.3.1, broffice.org-brand < 1:3.3.1 +Obsoletes: openoffice.org-headless < 1:3.3.1 +Obsoletes: openoffice.org-javafilter < 1:3.3.1 +Obsoletes: openoffice.org-langpack-ms < 1:3.3.1, libreoffice-langpack-ms < 1:3.3.99.1 +Obsoletes: openoffice.org-langpack-ur < 1:3.3.1, libreoffice-langpack-ur < 1:3.3.99.1 +Obsoletes: openoffice.org-testtools < 1:3.3.1 +Obsoletes: libreoffice-testtools < 1:3.4.99.1 +Obsoletes: autocorr-eu < 1:4.0.1.2 +Provides: libreoffice-headless = %{epoch}:%{version}-%{release} + +%description core +The shared core libraries and support files for LibreOffice. + +%package pyuno +Summary: Python support for LibreOffice +Group: Development/Libraries +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Requires: %{libo_python} +Obsoletes: openoffice.org-pyuno < 1:3.3.1 + +%description pyuno +Python bindings for the LibreOffice UNO component model. Allows scripts both +external to LibreOffice and within the internal LibreOffice scripting framework +to be written in python. + +%package base +Summary: Database front-end for LibreOffice +Group: Applications/Productivity +Requires: pentaho-reporting-flow-engine +Requires: postgresql-jdbc +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-calc = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: %{name}-report-builder < 1:4.1.0.0 +Obsoletes: openoffice.org-base-core < 1:3.3.1 +Obsoletes: openoffice.org-base < 1:3.3.1, broffice.org-base < 1:3.3.1 +Obsoletes: openoffice.org-report-builder < 1:3.3.1 + +%description base +GUI database front-end for LibreOffice. Allows creation and management of +databases through a GUI. + +%package bsh +Summary: BeanShell support for LibreOffice +Group: Development/Libraries +Requires: bsh +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-bsh < 1:3.3.1 + +%description bsh +Support BeanShell scripts in LibreOffice. + +%package officebean +Summary: JavaBean for LibreOffice Components +Group: Development/Libraries +Requires: %{name}-core = %{epoch}:%{version}-%{release} + +%description officebean +Allows embedding of LibreOffice documents within the Java environment. It +provides a Java AWT window into which the backend LibreOffice process draws +its visual representation + +%package rhino +Summary: JavaScript support for LibreOffice +Group: Development/Libraries +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-rhino < 1:3.3.1 + +%description rhino +Support JavaScript scripts in LibreOffice. + +%package wiki-publisher +Summary: Create Wiki articles on MediaWiki servers with LibreOffice +Group: Applications/Productivity +Requires: apache-commons-codec, jakarta-commons-httpclient +Requires: apache-commons-lang, apache-commons-logging +Requires: %{name}-writer = %{epoch}:%{version}-%{release} +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-wiki-publisher < 1:3.3.1 + +%description wiki-publisher +The Wiki Publisher enables you to create Wiki articles on MediaWiki servers +without having to know the syntax of the MediaWiki markup language. Publish +your new and existing documents transparently with writer to a wiki page. + +%package nlpsolver +Summary: Non-linear solver engine for LibreOffice Calc +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-calc = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} + +%description nlpsolver +A non-linear solver engine for Calc as an alternative to the default linear +programming model when more complex, nonlinear programming is required. + +%package ogltrans +Summary: 3D OpenGL slide transitions for LibreOffice +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-impress = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-ogltrans < 1:3.3.1 + +%description ogltrans +OpenGL Transitions enable 3D slide transitions to be used in LibreOffice. +Requires good quality 3D support for your graphics card for best experience. + +%package pdfimport +Summary: PDF Importer for LibreOffice Draw +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-draw = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-pdfimport < 1:3.3.1 + +%description pdfimport +The PDF Importer imports PDF into drawing documents to preserve layout +and enable basic editing of PDF documents. + +%package %{fontname}-fonts +Summary: LibreOffice dingbats font +Group: User Interface/X +Requires: fontpackages-filesystem +Obsoletes: openoffice.org-fonts < 1:3.3.1 +Obsoletes: openoffice.org-opensymbol-fonts < 1:3.3.1 +BuildArch: noarch + +%description %{fontname}-fonts +A dingbats font, OpenSymbol, suitable for use by LibreOffice for bullets and +mathematical symbols. + +%package writer +Summary: LibreOffice Word Processor Application +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-writer-core < 1:3.3.1 +Obsoletes: openoffice.org-writer < 1:3.3.1, broffice.org-writer < 1:3.3.1 + +%description writer +The LibreOffice Word Processor application. + +%package emailmerge +Summary: Email mail-merge component for LibreOffice +Group: Applications/Productivity +Requires: %{name}-writer = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-emailmerge < 1:3.3.1 + +%description emailmerge +Enables the LibreOffice writer module to mail-merge to email. + +%package calc +Summary: LibreOffice Spreadsheet Application +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-calc-core < 1:3.3.1 +Obsoletes: openoffice.org-calc < 1:3.3.1, broffice.org-calc < 1:3.3.1 + +%description calc +The LibreOffice Spreadsheet application. + +%package draw +Summary: LibreOffice Drawing Application +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} +Requires: %{name}-pdfimport = %{epoch}:%{version}-%{release} +Requires: %{name}-graphicfilter = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-draw-core < 1:3.3.1 +Obsoletes: openoffice.org-draw < 1:3.3.1, broffice.org-draw < 1:3.3.1 + +%description draw +The LibreOffice Drawing Application. + +%package impress +Summary: LibreOffice Presentation Application +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: %{name}-presentation-minimizer < 2:4.2.0.0-1.alpha1 +Obsoletes: %{name}-presenter-screen < 2:4.0.0.0-1.beta1 +Obsoletes: openoffice.org-impress-core < 1:3.3.1 +Obsoletes: openoffice.org-impress < 1:3.3.1, broffice.org-impress < 1:3.3.1 +Obsoletes: openoffice.org-presentation-minimizer < 1:3.3.1 +Obsoletes: openoffice.org-presenter-screen < 1:3.3.1 +Provides: %{name}-presentation-minimizer%{?_isa} = %{epoch}:%{version}-%{release} +Provides: %{name}-presenter-screen%{?_isa} = %{epoch}:%{version}-%{release} + +%description impress +The LibreOffice Presentation Application. + +%package math +Summary: LibreOffice Equation Editor Application +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-math-core < 1:3.3.1 +Obsoletes: openoffice.org-math < 1:3.3.1, broffice.org-math < 1:3.3.1 + +%description math +The LibreOffice Equation Editor Application. + +%package graphicfilter +Summary: LibreOffice Extra Graphic filters +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-graphicfilter < 1:3.3.1 + +%description graphicfilter +The graphicfilter module for LibreOffice provides graphic filters, e.g. svg and +flash filters. + +%package xsltfilter +Summary: Optional xsltfilter module for LibreOffice +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-xsltfilter < 1:3.3.1 + +%description xsltfilter +The xsltfilter module for LibreOffice, provides additional docbook and +xhtml export transforms. Install this to enable docbook export. + +%package postgresql +Summary: PostgreSQL connector for LibreOffice +Group: Applications/Productivity +Requires: %{name}-base = %{epoch}:%{version}-%{release} +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Requires: postgresql-libs + +%description postgresql +A PostgreSQL connector for the database front-end for LibreOffice. Allows +creation and management of PostgreSQL databases through a GUI. + +%package ure +Summary: UNO Runtime Environment +Group: Development/Libraries +#rhbz#1164551 we want to ensure that a libjvm.so of this arch is available +%if 0%{?__isa_bits} == 64 +Requires: libjvm.so()(64bit) +%endif +Requires: unzip +Obsoletes: openoffice.org-ure < 1:3.3.1 + +%description ure +UNO is the component model of LibreOffice. UNO offers interoperability between +programming languages, other components models and hardware architectures, +either in process or over process boundaries, in the Intranet as well as in the +Internet. UNO components may be implemented in and accessed from any +programming language for which a UNO implementation (AKA language binding) and +an appropriate bridge or adapter exists + +%package sdk +Summary: Software Development Kit for LibreOffice +Group: Development/Libraries +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} +Requires: unzip, java-devel +Obsoletes: openoffice.org-sdk < 1:3.3.1, openoffice.org-devel < 1:3.3.1 + +%description sdk +The LibreOffice SDK is an add-on for the LibreOffice office suite. It provides +the necessary tools for programming using the LibreOffice APIs and for creating +extensions (UNO components) for LibreOffice. To set the build environment for +building against the sdk use %{sdkinstdir}/setsdkenv_unix.sh. + +%package sdk-doc +Summary: Software Development Kit documentation for LibreOffice +Group: Documentation +Requires: %{name}-sdk = %{epoch}:%{version}-%{release} +Obsoletes: openoffice.org-sdk-doc < 1:3.3.1 + +%description sdk-doc +This provides documentation for programming using the LibreOffice APIs +and examples of creating extensions (UNO components) for LibreOffice. + +%package glade +Summary: Support for creating LibreOffice dialogs in glade +Group: Development/Libraries +Requires: %{name}-core = %{epoch}:%{version}-%{release} +Requires: %{name}-ure = %{epoch}:%{version}-%{release} + +%description glade +%{name}-glade contains a catalog of LibreOffice-specific widgets for +glade and ui-previewer tool to check the visual appearance of dialogs. + +%package librelogo +Summary: LibreLogo scripting language +Group: Applications/Productivity +Requires: %{name}-writer = %{epoch}:%{version}-%{release} +Requires: %{name}-pyuno = %{epoch}:%{version}-%{release} + +%description librelogo +Enables LibreLogo scripting in Writer. LibreLogo is a Logo-like +programming language with interactive vectorgraphics for education and +DTP. + +%if 0%{?fedora} + +%package kde +Summary: LibreOffice KDE integration plug-in +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} + +%description kde +A plug-in for LibreOffice that enables integration into the KDE desktop environment. + +%package gtk3 +Summary: LibreOffice GTK+ 3 integration plug-in +Group: Applications/Productivity +Requires: %{name}-core = %{epoch}:%{version}-%{release} + +%description gtk3 +A plug-in for LibreOffice that enables integration into GTK+ 3 environment. +This plugin is experimental and it is not suggested for normal use. + +%endif + +%package -n libreofficekit +Summary: A library providing access to LibreOffice functionality +Requires: %{name}-core = %{epoch}:%{version}-%{release} +License: MPLv2.0 + +%description -n libreofficekit +LibreOfficeKit can be used to access LibreOffice functionality +through C/C++, without any need to use UNO. + +For now it only offers document conversion (in addition to an +experimental tiled rendering API). + +%package -n libreofficekit-devel +Summary: Development files for libreofficekit +Requires: libreofficekit%{?_isa} = %{epoch}:%{version}-%{release} +License: MPLv2.0 + +%description -n libreofficekit-devel +The libreofficekit-devel package contains libraries and header files for +developing applications that use libreofficekit. + +%if 0%{?_enable_debug_packages} + +%define debug_package %{nil} +%global __debug_package 1 + +%package debuginfo +Summary: Debug information for package %{name} +Group: Development/Debug +AutoReqProv: 0 +%if 0%{?fedora} +Requires: libreoffice-core = %{epoch}:%{version}-%{release} +Recommends: libreoffice-gdb-debug-support = %{epoch}:%{version}-%{release} +%endif + +%description debuginfo +This package provides debug information for package %{name}. +Debug information is useful when developing applications that use this +package or when debugging this package. + +%files debuginfo -f debugfiles.list + +%package gdb-debug-support +Summary: Additional support for debugging with gdb +Group: Development/Debug +Requires: gdb +Requires: %{libo_python}-six +AutoReqProv: 0 + +%description gdb-debug-support +This package provides gdb pretty printers for package %{name}. + +%files gdb-debug-support +%{_datadir}/gdb/auto-load%{baseinstdir} +%{_datadir}/libreoffice/gdb + +%endif + +%define _langpack_common() \ +%{baseinstdir}/program/resource/*%{1}.res \ +%{baseinstdir}/share/config/soffice.cfg/modules/*/ui/res/%{1}.zip \ +%{baseinstdir}/share/config/soffice.cfg/*/ui/res/%{1}.zip \ +%{baseinstdir}/share/template/%{1} \ +%{baseinstdir}/share/registry/Langpack-%{1}.xcd \ +%{baseinstdir}/share/registry/res/registry_%{1}.xcd \ +%{baseinstdir}/share/registry/res/fcfg_langpack_%{1}.xcd \ +%{nil} + +# Defines a language pack subpackage. +# +# It's necessary to define language code (-l) and language name (-n). +# Additionally, it's possible +# * to require autocorr, hunspell, hyphen or mythes package or font for +# given language, +# * to obsolete openoffice.org-langpack package, +# * to provide libreoffice-langpack-loc package, where loc is glibc +# locale--this is necessary for yum to pick it automatically, +# * to require other, unrelated, packages, +# * to specify file serving as file list. +# For these, lower case character argument takes an argument specifying +# language, upper case character argument uses language from -l. +# +# All remaining arguments are considered to be files and added to the file +# list. +# +# Aa: autocorr dependency +# c: additional config file (just the name stem) +# E the package does not contain any files (i.e., has empty filelist) +# Ff: font language dependency +# Hh: hunspell dependency +# i: additional language added to this package +# L: internal (LibreOffice) language code, used in file names +# l: language code, e.g., cs +# Mm: mythes dependency +# n: language name, e.g., Czech +# Oo: Obsoletes: of openoffice.org-langpack +# Vv: Very archaic Obsoletes: of openoffice.org-langpack +# Ww: Archaic Obsoletes: of openoffice.org2-langpack +# p: Provides: of libreoffice-langpack +# r: comma-separated list of additional requires +# S:s: script classification (cjk, ctl). -S is only a marker, as it does +# not add any .xcd into the package (the file does not exist for at +# least one CTL-using locale, si) +# T has help files +# Xx: has autotext definitions +# Yy: hyphen dependency +# +# Example: +# libreoffice-langpack-cs: langpack for Czech lang. requiring hyphen-cs, +# autocorr-cs, mythes-cs-CZ and suitable font, obsoleting +# openoffice.org-langpack-cs_CZ: +# %%langpack -l cs -n Czech -H -A -m cs-CZ +# b de g jk q tu z BCD G IJK N PQR U Z0123456789 +%define langpack(Aa:c:EFf:Hh:i:L:l:Mm:n:p:Oo:r:S:s:TVv:Ww:Xx:Yy:) \ +%define lang %{-l:%{-l*}}%{!-l:%{error:Language code not defined}} \ +%define _langpack_lang %{-L:%{-L*}}%{!-L:%{lang}} \ +%define pkgname langpack-%{lang} \ +%define langname %{-n:%{-n*}}%{!-n:%{error:Language name not defined}} \ +\ +%global langpack_langs %{langpack_langs} %{_langpack_lang} %{-i:%{-i*}} \ +\ +%package %{pkgname} \ +Summary: %{langname} language pack for LibreOffice \ +Group: Applications/Productivity \ +Requires: %{name}-core = %{epoch}:%{version}-%{release} \ +%{-a:Requires: autocorr-%{-a*}}%{!-a:%{-A:Requires: autocorr-%{lang}}} \ +%{-f:Requires: font(:lang=%{-f*})}%{!-f:%{-F:Requires: font(:lang=%{lang})}} \ +%{-h:Requires: hunspell-%{-h*}}%{!-h:%{-H:Requires: hunspell-%{lang}}} \ +%{-m:Requires: mythes-%{-m*}}%{!-m:%{-M:Requires: mythes-%{lang}}} \ +%{-y:Requires: hyphen-%{-y*}}%{!-y:%{-Y:Requires: hyphen-%{lang}}} \ +%{-r:Requires: %{-r*}} \ +%{-o:Obsoletes: openoffice.org-langpack-%{-o*} < 1:3.3.1}%{!-o:%{-O:Obsoletes: openoffice.org-langpack-%{lang} < 1:3.3.1}} \ +%{-w:Obsoletes: openoffice.org2-langpack-%{-x*} < 1:3.0.0}%{!-x:%{-W:Obsoletes: openoffice.org2-langpack-%{lang} < 1:3.0.0}} \ +%{-v:Obsoletes: openoffice.org-langpack-%{-v*} < 1:2.0.3}%{!-v:%{-V:Obsoletes: openoffice.org-langpack-%{lang} < 1:2.0.3}} \ +%{-p:Provides: %{name}-langpack-%{-p*}} \ +\ +%description %{pkgname} \ +Provides additional %{langname} translations and resources for LibreOffice. \ +\ +%files %{pkgname} \ +%{!-E: \ +%{expand:%%_langpack_common %{_langpack_lang}} \ +%{-x:%{baseinstdir}/share/autotext/%{-x*}}%{!-x:%{-X:%{baseinstdir}/share/autotext/%{_langpack_lang}}} \ +%{-c:%{baseinstdir}/share/registry/%{-c*}.xcd} \ +%{-s:%{baseinstdir}/share/registry/%{-s*}_%{_langpack_lang}.xcd} \ +%{-T: \ +%docdir %{baseinstdir}/help/%{_langpack_lang} \ +%{baseinstdir}/help/%{_langpack_lang} \ +} \ +%{-i:%{expand:%%_langpack_common %{-i*}}} \ +} \ +%{nil} + +# Defines an auto-correction subpackage. +# +# i: add autocorrections from additional language +# l: language code +# n: language name +# L the filename does not contain country code +# +# All remaining arguments are considered to be files and added to the file +# list. +%define autocorr(i:Ll:n:) \ +%define lang %{-l:%{-l*}}%{!-l:%{error:Language code not defined}} \ +%define pkgname autocorr-%{lang} \ +%define langname %{-n:%{-n*}}%{!-n:%{error:Language name not defined}} \ +\ +%package -n %{pkgname} \ +Summary: %{langname} auto-correction rules \ +Group: Applications/Text \ +BuildArch: noarch \ +\ +%description -n %{pkgname} \ +Rules for auto-correcting common %{langname} typing errors. \ +\ +%files -n %{pkgname} \ +%doc instdir/LICENSE \ +%dir %{_datadir}/autocorr \ +%{-L:%{_datadir}/autocorr/acor_%{lang}.dat} \ +%{!-L:%{_datadir}/autocorr/acor_%{lang}-*.dat} \ +%{-i:%{_datadir}/autocorr/acor_%{-i*}-*.dat} \ +%{nil} + +%langpack -l en -n English -F -H -Y -M -A -E -L en-US -O + +%if %{with langpacks} + +%langpack -l af -n Afrikaans -F -H -Y -A -o af_ZA -V -w af_ZA +%langpack -l ar -n Arabic -F -H -s ctl -O -W +%langpack -l as -n Assamese -F -H -Y -o as_IN -w as_IN +%langpack -l bg -n Bulgarian -F -H -Y -M -A -T -X -o bg_BG -V -w bg_BG +%langpack -l bn -n Bengali -F -H -Y -T -O -v bn_IN -W +%langpack -l br -n Breton -F -H +%langpack -l ca -n Catalan -F -H -Y -M -A -T -o ca_ES -V -w ca_ES -X +%langpack -l cs -n Czech -F -H -Y -M -A -T -X -o cs_CZ -V -w cs_CZ +%langpack -l cy -n Welsh -F -H -Y -o cy_GB -V -w cy_GB +%langpack -l da -n Danish -F -H -Y -M -A -T -X -o da_DK -V -w da_DK +%langpack -l de -n German -F -H -Y -M -A -T -X -O -W +%langpack -l dz -n Dzongkha -F -s ctl -T -O +%langpack -l el -n Greek -F -H -Y -M -T -o el_GR -V -w el_GR +%langpack -l es -n Spanish -F -H -Y -M -A -T -X -O -W +%langpack -l et -n Estonian -F -H -Y -T -o et_EE -V -w et_EE +%langpack -l eu -n Basque -F -H -Y -T -o eu_ES -V -w eu_ES +%langpack -l fa -n Farsi -A -H -Y -s ctl -X +%langpack -l fi -n Finnish -F -r libreoffice-voikko -A -T -o fi_FI -V -w fi_FI -X +%langpack -l fr -n French -F -H -Y -M -A -T -X -O -W +%langpack -l ga -n Irish -F -H -Y -M -A -o ga_IE -w ga_IE +%langpack -l gl -n Galician -F -H -Y -T -o gl_ES -V -w gl_ES +%langpack -l gu -n Gujarati -F -H -Y -s ctl -o gu_IN -w gu_IN -T +%langpack -l he -n Hebrew -F -H -s ctl -o he_IL -V -w he_IL -T +%langpack -l hi -n Hindi -F -H -Y -s ctl -T -o hi_IN -v hi-IN -w hi_IN -X +%langpack -l hr -n Croatian -F -H -Y -A -o hr_HR -V -w hr_HR -T -X +%langpack -l hu -n Hungarian -F -H -Y -M -A -T -X -o hu_HU -V -w hu_HU +%langpack -l it -n Italian -F -H -Y -M -A -T -X -O -W +%langpack -l ja -n Japanese -F -A -s cjk -T -X -o ja_JP -V -w ja_JP +%langpack -l kk -n Kazakh -F -H +%langpack -l kn -n Kannada -F -H -Y -o kn_IN -w ka_IN +%langpack -l ko -n Korean -F -H -A -s cjk -T -X -o ko_KR -V -w ko_KR +%langpack -l lt -n Lithuanian -F -H -Y -A -o lt_LT -V -w lt_LT -X +%langpack -l lv -n Latvian -F -H -Y -M +%langpack -l mai -n Maithili -F -o mai_IN +%langpack -l ml -n Malayalam -F -H -Y -o ml_IN -w ml_IN +%langpack -l mr -n Marathi -F -H -Y -o mr_IN -w mr_IN +%langpack -l nb -n Bokmal -F -H -Y -M -T -o nb_NO -V -w nb_NO +%langpack -l nl -n Dutch -F -H -Y -M -A -T -X -O -W +%langpack -l nn -n Nynorsk -F -H -Y -M -T -o nn_NO -V -w nn_NO +%define langpack_lang Southern Ndebele +%langpack -l nr -n %{langpack_lang} -F -H -o nr_ZA +%define langpack_lang Northern Sotho +%langpack -l nso -n %{langpack_lang} -F -H -o nso_ZA -w nso_ZA +%langpack -l or -n Odia -F -H -Y -s ctl -o or_IN -w or_IN +%langpack -l pa -n Punjabi -F -H -Y -s ctl -L pa-IN -O -v pa_IN -w pa_IN +%langpack -l pl -n Polish -F -H -Y -M -A -T -X -o pl_PL -V -w pl_PL +%define langpack_lang Brazilian Portuguese +%langpack -l pt-BR -n %{langpack_lang} -f pt -h pt -y pt -m pt -a pt -p pt_BR -T -X -o pt_BR -V -w pt_BR +%langpack -l pt-PT -n Portuguese -f pt -h pt -y pt -m pt -a pt -p pt_PT -T -L pt -x pt -o pt_PT -v pt -W +%langpack -l ro -n Romanian -A -F -H -Y -M -O -X +%langpack -l ru -n Russian -F -H -Y -M -A -T -X -O -W +%langpack -l si -n Sinhalese -F -H -S ctl -T -O +%langpack -l sk -n Slovak -F -H -Y -M -A -T -X -o sk_SK -V -w sk_SK +%langpack -l sl -n Slovenian -F -H -Y -M -A -T -X -o sl_SI -V -w sl_SI +%{baseinstdir}/share/wordbook/sl.dic + +#rhbz#452379 clump serbian translations together +%langpack -l sr -n Serbian -F -H -Y -A -i sr-Latn -O -v sr_CS -w sr_CS +%langpack -l ss -n Swati -F -H -o ss_ZA +%define langpack_lang Southern Sotho +%langpack -l st -n %{langpack_lang} -F -H -o st_ZA +%langpack -l sv -n Swedish -F -H -Y -M -A -T -X -O -W +%langpack -l ta -n Tamil -F -H -Y -s ctl -o ta_IN -w ta_IN +%langpack -l te -n Telugu -F -H -Y -o te_IN -w te_IN +%langpack -l th -n Thai -F -H -s ctl -c ctlseqcheck_th -o th_TH -V -w th_TH +%langpack -l tn -n Tswana -F -H -o tn_ZA -V -w tn_ZA +%langpack -l tr -n Turkish -F -A -T -X -o tr_TR -V -W +%langpack -l ts -n Tsonga -F -H -o ts_ZA -V -w ts_ZA +%langpack -l uk -n Ukrainian -F -H -Y -M -T -O +%langpack -l ve -n Venda -F -H -o ve_ZA +%langpack -l xh -n Xhosa -F -H -o xh_ZA +%define langpack_lang Simplified Chinese +%langpack -l zh-Hans -n %{langpack_lang} -f zh-cn -a zh -p zh_CN -s cjk -T -L zh-CN -x zh-CN -o zh_CN -v zh-CN -w zh_CN +%define langpack_lang Traditional Chinese +%langpack -l zh-Hant -n %{langpack_lang} -f zh-tw -a zh -p zh_TW -s cjk -T -L zh-TW -x zh-TW -o zh_TW -v zh-TW -w zh_TW +%langpack -l zu -n Zulu -F -H -Y -o zu_ZA -V -w zu_ZA +%undefine langpack_lang + +%endif + +%autocorr -l en -n English + +%if %{with langpacks} + +%autocorr -l af -n Afrikaans +%autocorr -l bg -n Bulgarian +%autocorr -l ca -n Catalan +%autocorr -l cs -n Czech +%autocorr -l da -n Danish +%autocorr -l de -n German -L +%autocorr -l es -n Spanish -L +%autocorr -l fa -n Farsi +%autocorr -l fi -n Finnish +%autocorr -l fr -n French -L +%autocorr -l ga -n Irish +%autocorr -l hr -n Croatian +%autocorr -l hu -n Hungarian +%autocorr -l is -n Icelandic +%autocorr -l it -n Italian -L +%autocorr -l ja -n Japanese +%autocorr -l ko -n Korean +%autocorr -l lb -n Luxembourgish +%autocorr -l lt -n Lithuanian +%autocorr -l mn -n Mongolian +%autocorr -l nl -n Dutch +%autocorr -l pl -n Polish +%autocorr -l pt -n Portuguese +%autocorr -l ro -n Romanian +%autocorr -l ru -n Russian +%autocorr -l sk -n Slovak +%autocorr -l sl -n Slovenian +#rhbz#452379 clump serbian autocorrections together +%autocorr -l sr -n Serbian -i sr-Latn +%autocorr -l sv -n Swedish +%autocorr -l tr -n Turkish +%autocorr -l vi -n Vietnamese +%autocorr -l zh -n Chinese + +%endif + +%define make_autocorr_aliases(l:) \ +%{?-l: \ +for lang in %{*}; do \ + ln -sf acor_%{-l*}.dat acor_$lang.dat \ +done \ +} \ +%{!?-l:%{error:-l must be present}} + +%prep +%setup -q -n %{name}-%{version}%{?libo_prerelease} -b 1 -b 2 +rm -rf git-hooks */git-hooks + +# set up git repo +git init +git config user.name rpmbuild +git config user.email rpmbuild@fedoraproject.org +git config gc.auto 0 # disable auto packing +git add -A +git commit -q -a -m %{name}-%{version} + +#Customize Palette to add Red Hat colours +(head -n -1 extras/source/palettes/standard.soc && \ + echo -e ' + + + + ' && \ + tail -n 1 extras/source/palettes/standard.soc) > redhat.soc +mv -f redhat.soc extras/source/palettes/standard.soc +git commit -q -a -m 'add Red Hat colors to palette' + +# apply patches +git am %{patches} + +sed -i -e /CppunitTest_sw_ooxmlimport/d sw/Module_sw.mk +# fails on all secondary platforms +sed -i -e /CppunitTest_vcl_outdev/d vcl/Module_vcl.mk +sed -i -e /CppunitTest_vcl_bitmap_test/d vcl/Module_vcl.mk +git commit -q -a -m 'temporarily disable failing tests' + +# Seeing .git dir makes some of the build tools change their behavior. +# We do not want that. Note: it is still possible to use +# git --git-dir=.git-rpm +mv .git .git-rpm + +%build +echo build start time is `date`, diskspace: `df -h . | tail -n 1` +echo building localizations: %{langpack_langs} +# path to external tarballs +EXTSRCDIR=`dirname %{SOURCE0}` + +%if 0%{?fedora} +# KDE bits +export QT4DIR=%{_qt4_prefix} +export KDE4DIR=%{_kde4_prefix} +export PATH=$QT4DIR/bin:$PATH +%endif + +#use the RPM_OPT_FLAGS but remove the OOo overridden ones +for i in $RPM_OPT_FLAGS; do + case "$i" in + -pipe|-Wall|-Werror*|-g|-fexceptions) continue;; + esac + ARCH_FLAGS="$ARCH_FLAGS $i" +done +%ifarch s390 aarch64 +# these builders typically do not have enough memory to link the big libs with -g2 +ARCH_FLAGS="$ARCH_FLAGS -g1" +%endif +export ARCH_FLAGS +export CFLAGS=$ARCH_FLAGS +export CXXFLAGS=$ARCH_FLAGS + +%if 0%{?rhel} +%define distrooptions --disable-eot --disable-gltf --disable-firebird-sdbc --enable-python=system +%else # fedora +%define distrooptions --enable-eot --enable-kde4 --with-system-opencollada --with-system-ucpp +export OPENCOLLADA_CFLAGS='-I/usr/include/COLLADABaseUtils -I/usr/include/COLLADAFramework -I/usr/include/COLLADASaxFrameworkLoader -I/usr/include/GeneratedSaxParser' +export OPENCOLLADA_LIBS='-lOpenCOLLADABaseUtils -lOpenCOLLADAFramework -lOpenCOLLADASaxFrameworkLoader -lGeneratedSaxParser' +%endif + +%if %{with langpacks} +%define with_lang --with-lang='%{langpack_langs}' +%endif + +%if ! 0%{libo_use_python3} +export PYTHON=%{_bindir}/python +export PYTHON_CFLAGS=`pkg-config --cflags python` +export PYTHON_LIBS=`pkg-config --libs python` +%endif + +# %%if 0%%{?rhel} && 0%%{?rhel} < 7 +aclocal -I m4 +autoconf +# %endif + +# TODO: enable coinmp? +# avoid running autogen.sh on make +touch autogen.lastrun +# NOTE: --enable-gtk3 is just for libreofficekit +%configure \ + %vendoroption \ + %{?with_lang} \ + %{?_smp_mflags:--with-parallelism=%{_smp_mflags}} \ + --disable-coinmp \ + --disable-fetch-external \ + --disable-gnome-vfs \ + --disable-openssl \ + --enable-evolution2 \ + --enable-ext-nlpsolver \ + --enable-ext-wiki-publisher \ + --enable-gtk3 \ + --enable-release-build \ + --enable-scripting-beanshell \ + --enable-scripting-javascript \ + --enable-symbols \ + --with-build-version="%{version}-%{release}" \ + --with-external-dict-dir=/usr/share/myspell \ + --with-external-tar="$EXTSRCDIR" \ + --with-help \ + --with-system-dicts \ + --with-system-libs \ + --without-fonts \ + --without-system-npapi-headers \ + --with-gdrive-client-secret="GYWrDtzyZQZ0_g5YoBCC6F0I" \ + --with-gdrive-client-id="457862564325.apps.googleusercontent.com" \ + %{distrooptions} \ + %{?bundling_options} \ + %{?archoptions} + +ulimit -c unlimited +# make VERBOSE=true +make verbose=true build-nocheck + +#generate the icons and mime type stuff +export DESTDIR=../output +export KDEMAINDIR=/usr +export GNOMEDIR=/usr +export GNOME_MIME_THEME=hicolor +export PREFIXDIR=/usr +# TODO use empty variables? Should make the renaming hacks in %%install +# unnecessary. +. ./bin/get_config_variables PRODUCTVERSIONSHORT PRODUCTVERSION SRCDIR WORKDIR PKG_CONFIG INSTDIR +pushd $WORKDIR/CustomTarget/sysui/share/libreoffice +./create_tree.sh +popd +mkdir $WORKDIR/os-integration +cp -pr $WORKDIR/CustomTarget/sysui/share/output/usr/share/* $WORKDIR/os-integration +cp -pr $WORKDIR/CustomTarget/sysui/share/output/girepository-1.0/LOKDocView-0.1.typelib $WORKDIR/os-integration + +%if %{with smallbuild} +# remove the biggest offenders +# NOTE: not removing complete LinkTarget, as some libs are needed for smoketest +rm -rf $WORKDIR/CxxObject $WORKDIR/GenCxxObject $WORKDIR/HelpTarget $WORKDIR/LinkTarget/CppunitTest +%endif + +echo build end time is `date`, diskspace: `df -h . | tail -n 1` + + +%install +# TODO investigate use of make distro-pack-install +#figure out the icon version +. ./bin/get_config_variables PRODUCTVERSIONSHORT PRODUCTVERSION SRCDIR WORKDIR +export PRODUCTVERSIONSHORT PRODUCTVERSION + +# installation + +install -m 0755 -d %{buildroot}%{instdir} +if ! make instsetoo_native PKGFORMAT=installed EPM=not-used-but-must-be-set; then + echo - ---dump log start--- + cat $WORKDIR/installation/LibreOffice/installed/logging/en-US/log_*_en-US.log + echo - ---dump log end--- + echo - ---dump log start -- SDK--- + cat $WORKDIR/installation/LibreOffice_SDK/installed/logging/en-US/log_*_en-US.log + echo - ---dump log end -- SDK--- + echo - ---dump log start -- languagepacks--- + cat $WORKDIR/installation/LibreOffice_languagepack/installed/logging/en-US/log_*_en-US.log + echo - ---dump log end -- languagepacks--- + exit 1 +fi +install -m 0755 -d %{buildroot}%{baseinstdir} +mv $WORKDIR/installation/LibreOffice/installed/install/en-US/* %{buildroot}%{baseinstdir} +%if %{with langpacks} +for langpack in $WORKDIR/installation/LibreOffice_languagepack/installed/install/*; do + [ `basename $langpack` = log ] && continue + cp -rp $langpack/* %{buildroot}%{baseinstdir} + rm -rf $langpack +done +%endif +mv $WORKDIR/installation/LibreOffice_SDK/installed/install/en-US/sdk %{buildroot}%{sdkinstdir} +chmod -R +w %{buildroot}%{baseinstdir} + +# postprocessing and tweaks + +# The installer currently sets UserInstallation to +# $ORIGIN/../libreoffice/4, which is of course total nonsense. Because I +# have no inclination to crawl through mountains of perl code to figure out +# where it comes from, I am just going to replace it by a sensible +# value here. +sed -i -e '/UserInstallation/s@\$ORIGIN/..@$SYSUSERCONFIG@' %{buildroot}%{baseinstdir}/program/bootstraprc + +#configure sdk +pushd %{buildroot}%{sdkinstdir} + sed -e "s,@OO_SDK_NAME@,sdk," \ + -e "s,@OO_SDK_HOME@,%{sdkinstdir}," \ + -e "s,@OFFICE_HOME@,%{baseinstdir}," \ + -e "s,@OO_SDK_MAKE_HOME@,/usr/bin," \ + -e "s,@OO_SDK_ZIP_HOME@,/usr/bin," \ + -e "s,@OO_SDK_CPP_HOME@,/usr/bin," \ + -e "s,@OO_SDK_CAT_HOME@,/usr/bin," \ + -e "s,@OO_SDK_SED_HOME@,/usr/bin," \ + -e "s,@OO_SDK_CC_55_OR_HIGHER@,," \ + -e "s,@OO_SDK_JAVA_HOME@,$JAVA_HOME," \ + -e "s,@OO_SDK_OUTPUT_DIR@,\$HOME," \ + -e "s,@SDK_AUTO_DEPLOYMENT@,NO," \ + setsdkenv_unix.sh.in > setsdkenv_unix.sh + # ensure no unexpanded vars sneaked in + grep '@[A_Z0-9_]\+@' setsdkenv_unix.sh && exit 1 + chmod 755 setsdkenv_unix.sh + # we don't want to install the input file + rm -f setsdkenv_unix.sh.in +# TODO: is this still necessary? +#fix permissions + find examples -type f -exec chmod -x {} \; +popd + +#ensure a template dir for each lang +pushd %{buildroot}%{baseinstdir}/share/template +for I in %{langpack_langs}; do + mkdir -p $I +done +popd + +#Set some aliases to canonical autocorrect language files for locales with matching languages +pushd %{buildroot}%{baseinstdir}/share/autocorr + +%make_autocorr_aliases -l en-GB en-AG en-AU en-BS en-BW en-BZ en-CA en-DK en-GH en-HK en-IE en-IN en-JM en-NG en-NZ en-SG en-TT +%make_autocorr_aliases -l en-US en-PH +#en-ZA exists and has a good autocorrect file with two or three extras that make sense for +#neighbouring english speaking territories +%make_autocorr_aliases -l en-ZA en-NA en-ZW +%if %{with langpacks} +%make_autocorr_aliases -l af-ZA af-NA +%make_autocorr_aliases -l nl-NL nl-AW +%make_autocorr_aliases -l sv-SE sv-FI +%else +rm -f acor_[a-df-z]*.dat acor_e[su]*.dat +%endif +popd +#rhbz#484055 make these shared across multiple applications +install -m 0755 -d %{buildroot}%{_datadir} +mv -f %{buildroot}%{baseinstdir}/share/autocorr %{buildroot}%{_datadir}/autocorr +chmod 755 %{buildroot}%{_datadir}/autocorr +ln -s %{_datadir}/autocorr %{buildroot}%{baseinstdir}/share/autocorr + +#remove it in case we didn't build with gcj +rm -f %{buildroot}%{baseinstdir}/program/classes/sandbox.jar + +#remove dummy .dat files +rm -f %{buildroot}%{baseinstdir}/program/root?.dat + +#set standard permissions for rpmlint +find %{buildroot}%{baseinstdir} -exec chmod +w {} \; +find %{buildroot}%{baseinstdir} -type d -exec chmod 0755 {} \; + +# move python bits into site-packages +install -m 0755 -d %{buildroot}%{libo_python_sitearch} +pushd %{buildroot}%{libo_python_sitearch} +echo "import sys, os" > uno.py +echo "sys.path.append('%{baseinstdir}/program')" >> uno.py +echo "os.putenv('URE_BOOTSTRAP', 'vnd.sun.star.pathname:%{baseinstdir}/program/fundamentalrc')" >> uno.py +cat %{buildroot}%{baseinstdir}/program/uno.py >> uno.py +rm -f %{buildroot}%{baseinstdir}/program/uno.py* +mv -f %{buildroot}%{baseinstdir}/program/unohelper.py* . +mv -f %{buildroot}%{baseinstdir}/program/officehelper.py* . +popd + +# rhbz#477435 package opensymbol separately +pushd %{buildroot}%{baseinstdir}/share/fonts/truetype +install -d -m 0755 %{buildroot}%{_fontdir} +install -p -m 0644 *.ttf %{buildroot}%{_fontdir} +popd +rm -rf %{buildroot}%{baseinstdir}/share/fonts + +%if 0%{?rhel} && 0%{?rhel} < 7 +#fix rpath for redland libs +chrpath -r '$ORIGIN:$ORIGIN/../ure-link/lib' \ + %{buildroot}%{baseinstdir}/program/libraptor2-lo.so.0 \ + %{buildroot}%{baseinstdir}/program/librasqal-lo.so.3 \ + %{buildroot}%{baseinstdir}/program/librdf-lo.so.0 +%endif + +#ensure that no sneaky un-prelinkable, un-fpic or non executable shared libs +#have snuck through +pic=0 +executable=0 +for foo in `find %{buildroot}%{instdir} -name "*" -exec file {} \;| grep ": ELF" | cut -d: -f 1` ; do + chmod +wx $foo + ls -asl $foo + result=`readelf -d $foo | grep TEXTREL` || true + if [ "$result" != "" ]; then + echo "TEXTREL Warning: $foo is b0rked (-fpic missing)" + pic=1 + fi + result=`readelf -l $foo | grep GNU_STACK | grep RWE` || true + if [ "$result" != "" ]; then + echo "GNU_STACK Warning: $foo is b0rked (-noexecstack missing)" + executable=1 + fi +done +if [ $pic == 1 ]; then false; fi +if [ $executable == 1 ]; then false; fi + +#make up some /usr/bin scripts +install -m 0755 -d %{buildroot}%{_bindir} + +pushd %{buildroot}%{_bindir} +echo \#\!/bin/sh > ooffice +echo exec libreoffice \"\$@\" >> ooffice +chmod a+x ooffice + +echo \#\!/bin/sh > ooviewdoc +echo exec libreoffice --view \"\$@\" >> ooviewdoc +chmod a+x ooviewdoc + +for app in base calc draw impress math writer; do + echo \#\!/bin/sh > oo$app + echo exec libreoffice --$app \"\$@\" >> oo$app + chmod a+x oo$app +done + +sed -e s/LAUNCHER/unopkg/g -e s/BRAND/libreoffice/g %{SOURCE4} > unopkg +chmod a+x unopkg + +sed -e s/LAUNCHER/soffice/g -e s/BRAND/libreoffice/g %{SOURCE4} > libreoffice +chmod a+x libreoffice + +# rhbz#499474 provide a /usr/bin/soffice for .recently-used.xbel +ln -s %{baseinstdir}/program/soffice soffice +# rhbz#499474 provide a /usr/bin/openoffice.org for backwards compat +ln -s libreoffice openoffice.org +popd + +pushd %{buildroot}%{baseinstdir}/share/xdg/ +chmod u+w *.desktop +ICONVERSION=`echo $PRODUCTVERSION | sed -e 's/\.//'` +for file in *.desktop; do + # rhbz#156677 remove the version from Name= + # rhbz#156067 don't version the icons + sed -i -e "s/ *$PRODUCTVERSION//g" \ + -e "s/$ICONVERSION//g" \ + -e "s/$PRODUCTVERSIONSHORT//g" \ + $file +done +# rhbz#156677 / rhbz#186515 do not show math and startcenter +sed -i -e /NoDisplay/s/false/true/ math.desktop startcenter.desktop +# relocate the .desktop and icon files +install -m 0755 -d %{buildroot}%{_datadir}/applications +for app in base calc draw impress math startcenter writer xsltfilter; do + sed -i -e 's/\${UNIXBASISROOTNAME}/%{name}/' $app.desktop + desktop-file-validate $app.desktop + install -m 0644 -p $app.desktop %{buildroot}%{_datadir}/applications/libreoffice-$app.desktop +done +popd + +pushd $WORKDIR/os-integration +#get rid of the gnome icons and other unneeded files +rm -rf icons/gnome applications application-registry + +#relocate the rest of them +# rhbz#901346 512x512 icons are not used by anything +for icon in `find icons -path '*/512x512' -prune -o -type f -print`; do + install -m 0755 -d %{buildroot}%{_datadir}/`dirname $icon` + install -m 0644 -p $icon %{buildroot}%{_datadir}/`echo $icon | sed -e s@libreoffice$ICONVERSION-@libreoffice-@ | sed -e s@libreoffice$PRODUCTVERSION-@libreoffice-@` +done +install -m 0755 -d %{buildroot}%{_datadir}/mime-info +install -m 0644 -p mime-info/libreoffice$PRODUCTVERSION.keys %{buildroot}%{_datadir}/mime-info/libreoffice.keys +install -m 0644 -p mime-info/libreoffice$PRODUCTVERSION.mime %{buildroot}%{_datadir}/mime-info/libreoffice.mime +#add our mime-types, e.g. for .oxt extensions +install -m 0755 -d %{buildroot}%{_datadir}/mime/packages +install -m 0644 -p mime/packages/libreoffice$PRODUCTVERSION.xml %{buildroot}%{_datadir}/mime/packages/libreoffice.xml + +# install LibreOfficeKit +install -m 0755 -d %{buildroot}%{_libdir}/girepository-1.0 +install -m 0644 -p LOKDocView-%{girapiversion}.typelib %{buildroot}%{_libdir}/girepository-1.0/LOKDocView-%{girapiversion}.typelib +install -m 0755 -d %{buildroot}%{_libdir}/gir-1.0 +install -m 0644 -p gir-1.0/LOKDocView-%{girapiversion}.gir %{buildroot}%{_libdir}/gir-1.0/LOKDocView-%{girapiversion}.gir +mv %{buildroot}%{baseinstdir}/program/liblibreofficekitgtk.so %{buildroot}%{_libdir} +popd + +%if 0%{?fedora} +# install LibreOfficeKit headers +install -m 0755 -d %{buildroot}%{_includedir}/LibreOfficeKit +install -m 0644 -p include/LibreOfficeKit/* %{buildroot}%{_includedir}/LibreOfficeKit +%endif + +# This is only a side effect of building LibreOfficeKit. The plugin +# itself is not usable yet in 5.0, so let's drop it. +rm -f %{buildroot}%{baseinstdir}/program/libvclplug_gtk3lo.so + +rm -rf %{buildroot}%{baseinstdir}/readmes +rm -rf %{buildroot}%{baseinstdir}/licenses + +# to-do, remove this in libreoffice 4.4 when --without-ppds is gone, it'll do the right thing on its own then +install -m 0755 -d %{buildroot}%{baseinstdir}/share/psprint/driver +install -m 0644 -p vcl/unx/generic/printer/configuration/ppds/SGENPRT.PS %{buildroot}%{baseinstdir}/share/psprint/driver/SGENPRT.PS + +# rhbz#452385 to auto have postgres in classpath if subsequently installed +sed -i -e "s#URE_MORE_JAVA_CLASSPATH_URLS.*#& file:///usr/share/java/postgresql-jdbc.jar#" %{buildroot}%{baseinstdir}/program/fundamentalrc + +# move glade catalog to system glade dir +install -m 0755 -d %{buildroot}%{_datadir}/glade/catalogs +mv %{buildroot}%{baseinstdir}/share/glade/libreoffice-catalog.xml %{buildroot}%{_datadir}/glade/catalogs +install -m 0755 -d %{buildroot}%{_datadir}/glade3/catalogs +ln -sr %{buildroot}%{_datadir}/glade/catalogs/libreoffice-catalog.xml %{buildroot}%{_datadir}/glade3/catalogs + +# rhbz#1049543 install appdata +install -m 0755 -d %{buildroot}%{_datadir}/appdata +install -m 0644 -p sysui/desktop/appstream-appdata/*.appdata.xml %{buildroot}%{_datadir}/appdata + +# rhbz#1215800 install symbolic icons +install -m 0755 -d %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +install -m 0644 -p %{SOURCE42} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +install -m 0644 -p %{SOURCE43} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +install -m 0644 -p %{SOURCE44} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +install -m 0644 -p %{SOURCE45} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +install -m 0644 -p %{SOURCE46} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +install -m 0644 -p %{SOURCE47} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +install -m 0644 -p %{SOURCE48} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps + +# install man pages +install -m 0755 -d %{buildroot}%{_mandir}/man1 +install -m 0644 -p sysui/desktop/man/*.1 %{buildroot}%{_mandir}/man1 +for app in oobase oocalc oodraw ooffice ooimpress oomath ooviewdoc oowriter openoffice.org soffice; do + echo '.so man1/libreoffice.1' > $app.1 + install -m 0644 -p $app.1 %{buildroot}%{_mandir}/man1 +done + +export DESTDIR=%{buildroot} +./solenv/bin/install-gdb-printers -a %{_datadir}/gdb/auto-load%{baseinstdir} -c -i %{baseinstdir} -p %{_datadir}/libreoffice/gdb +# tl.pyc is sligtly different on various platforms for some reason, breaking multilib +rm -f \ + %{buildroot}%{_datadir}/gdb/auto-load%{baseinstdir}/program/libtllo.so-gdb.py \ + %{buildroot}%{_datadir}/libreoffice/gdb/libreoffice/tl.py + +%if 0%{?fedora} +# Update the screenshot shown in the software center +# +# NOTE: It would be *awesome* if this file was pushed upstream. +# +# See http://people.freedesktop.org/~hughsient/appdata/#screenshots for more details. +# +appstream-util replace-screenshots %{buildroot}%{_datadir}/appdata/libreoffice-writer.appdata.xml \ + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/libreoffice-writer/a.png \ + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/libreoffice-writer/b.png +appstream-util replace-screenshots %{buildroot}%{_datadir}/appdata/libreoffice-calc.appdata.xml \ + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/libreoffice-calc/a.png +appstream-util replace-screenshots %{buildroot}%{_datadir}/appdata/libreoffice-draw.appdata.xml \ + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/libreoffice-draw/a.png +appstream-util replace-screenshots %{buildroot}%{_datadir}/appdata/libreoffice-impress.appdata.xml \ + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/libreoffice-impress/a.png +%endif + +%check +ulimit -c unlimited +unset WITH_LANG +# work around flawed accessibility check +export JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY="1" +export OOO_TEST_SOFFICE=path:%{buildroot}%{baseinstdir}/program/soffice +# we don't need this anymore +rm -f %{buildroot}%{baseinstdir}/program/classes/smoketest.jar + +%files + +%files filters + +%files core +%dir %{baseinstdir} +%dir %{baseinstdir}/help +%docdir %{baseinstdir}/help/en-US +%dir %{baseinstdir}/help/en-US +%{baseinstdir}/help/en-US/default.css +%{baseinstdir}/help/en-US/err.html +%{baseinstdir}/help/en-US/highcontrast1.css +%{baseinstdir}/help/en-US/highcontrast2.css +%{baseinstdir}/help/en-US/highcontrastblack.css +%{baseinstdir}/help/en-US/highcontrastwhite.css +%{baseinstdir}/help/en-US/sbasic.* +%{baseinstdir}/help/en-US/schart.* +%{baseinstdir}/help/en-US/shared.* +%{baseinstdir}/help/idxcaption.xsl +%{baseinstdir}/help/idxcontent.xsl +%{baseinstdir}/help/main_transform.xsl +%{baseinstdir}/presets +%dir %{baseinstdir}/program +%{baseinstdir}/program/libbasprovlo.so +%{baseinstdir}/program/libcairocanvaslo.so +%{baseinstdir}/program/libcanvasfactorylo.so +%dir %{baseinstdir}/program/classes +%{baseinstdir}/program/classes/commonwizards.jar +%{baseinstdir}/program/classes/form.jar +%{baseinstdir}/program/classes/query.jar +%{baseinstdir}/program/classes/report.jar +%{baseinstdir}/program/classes/ScriptFramework.jar +%{baseinstdir}/program/classes/ScriptProviderForJava.jar +%{baseinstdir}/program/classes/table.jar +%{baseinstdir}/program/classes/unoil.jar +%{baseinstdir}/program/classes/XMergeBridge.jar +%{baseinstdir}/program/classes/xmerge.jar +%{baseinstdir}/program/libcmdmaillo.so +%{baseinstdir}/program/libdeployment.so +%{baseinstdir}/program/libdeploymentgui.so +%{baseinstdir}/program/libdlgprovlo.so +%{baseinstdir}/program/libexpwraplo.so +%{baseinstdir}/program/flat_logo.svg +%{baseinstdir}/program/libfps_officelo.so +%{baseinstdir}/program/gdbtrace +%{baseinstdir}/program/gengal +%{baseinstdir}/program/gengal.bin +%{baseinstdir}/program/gnome-open-url +%{baseinstdir}/program/libi18nsearchlo.so +%{baseinstdir}/program/libldapbe2lo.so +%{baseinstdir}/program/libacclo.so +%{baseinstdir}/program/libavmedia*.so +%{baseinstdir}/program/libbasebmplo.so +%{baseinstdir}/program/libbasctllo.so +%{baseinstdir}/program/libbiblo.so +%{baseinstdir}/program/libcached1.so +%{baseinstdir}/program/libcanvastoolslo.so +%{baseinstdir}/program/libchart*lo.so +%{baseinstdir}/program/libclewlo.so +%{baseinstdir}/program/libcollator_data.so +%{baseinstdir}/program/libcppcanvaslo.so +%{baseinstdir}/program/libctllo.so +%{baseinstdir}/program/libcuilo.so +%{baseinstdir}/program/libdbalo.so +%{baseinstdir}/program/libdbaselo.so +%{baseinstdir}/program/libdbaxmllo.so +%{baseinstdir}/program/libdbmmlo.so +%{baseinstdir}/program/libdbpool2.so +%{baseinstdir}/program/libdbtoolslo.so +%{baseinstdir}/program/libdbulo.so +%{baseinstdir}/program/libdeploymentmisclo.so +%{baseinstdir}/program/libdesktop_detectorlo.so +%{baseinstdir}/program/libdict_ja.so +%{baseinstdir}/program/libdict_zh.so +%{baseinstdir}/program/libdrawinglayerlo.so +%{baseinstdir}/program/libeditenglo.so +%{baseinstdir}/program/libembobj.so +%{baseinstdir}/program/libemboleobj.so +%{baseinstdir}/program/libevoab*.so +%{baseinstdir}/program/libevtattlo.so +%{baseinstdir}/program/libegilo.so +%{baseinstdir}/program/libemelo.so +%{baseinstdir}/program/libepblo.so +%{baseinstdir}/program/libepglo.so +%{baseinstdir}/program/libepplo.so +%{baseinstdir}/program/libepslo.so +%{baseinstdir}/program/libeptlo.so +%{baseinstdir}/program/liberalo.so +%{baseinstdir}/program/libetilo.so +%{baseinstdir}/program/libexplo.so +%if 0%{?fedora} +%{baseinstdir}/program/libfirebird_sdbclo.so +%endif +%{baseinstdir}/program/libicdlo.so +%{baseinstdir}/program/libicglo.so +%{baseinstdir}/program/libidxlo.so +%{baseinstdir}/program/libimelo.so +%{baseinstdir}/program/libindex_data.so +%{baseinstdir}/program/libipblo.so +%{baseinstdir}/program/libipdlo.so +%{baseinstdir}/program/libipslo.so +%{baseinstdir}/program/libiptlo.so +%{baseinstdir}/program/libipxlo.so +%{baseinstdir}/program/libiralo.so +%{baseinstdir}/program/libitglo.so +%{baseinstdir}/program/libitilo.so +%{baseinstdir}/program/libfilelo.so +%{baseinstdir}/program/libfilterconfiglo.so +%{baseinstdir}/program/libflatlo.so +%{baseinstdir}/program/libfrmlo.so +%{baseinstdir}/program/libguesslanglo.so +%{baseinstdir}/program/libhelplinkerlo.so +%{baseinstdir}/program/libhyphenlo.so +%{baseinstdir}/program/libjdbclo.so +%{baseinstdir}/program/liblnglo.so +%{baseinstdir}/program/libloglo.so +%{baseinstdir}/program/liblocaledata_en.so +%{baseinstdir}/program/liblocaledata_es.so +%{baseinstdir}/program/liblocaledata_euro.so +%{baseinstdir}/program/liblocaledata_others.so +%{baseinstdir}/program/libmcnttype.so +%{baseinstdir}/program/libmorklo.so +%{baseinstdir}/program/libmozbootstraplo.so +%{baseinstdir}/program/libmsfilterlo.so +%{baseinstdir}/program/libmtfrendererlo.so +%{baseinstdir}/program/libmysqllo.so +%{baseinstdir}/program/libodbclo.so +%{baseinstdir}/program/liboglcanvaslo.so +%{baseinstdir}/program/liboffacclo.so +%{baseinstdir}/program/libooxlo.so +%{baseinstdir}/program/libopencllo.so +%{baseinstdir}/program/libpcrlo.so +%{baseinstdir}/program/libpdffilterlo.so +%{baseinstdir}/program/libpllo.so +%{baseinstdir}/program/libprotocolhandlerlo.so +%{baseinstdir}/program/libqstart_gtklo.so +%{baseinstdir}/program/librecentfile.so +%{baseinstdir}/program/libreslo.so +%{baseinstdir}/program/libsaxlo.so +%{baseinstdir}/program/libscnlo.so +%{baseinstdir}/program/libscriptframe.so +%{baseinstdir}/program/libsdlo.so +%{baseinstdir}/program/libsdfiltlo.so +%{baseinstdir}/program/libsdbc2.so +%{baseinstdir}/program/libsdbtlo.so +%{baseinstdir}/program/libsddlo.so +%{baseinstdir}/program/libsduilo.so +%{baseinstdir}/program/libspelllo.so +%{baseinstdir}/program/libsrtrs1.so +%{baseinstdir}/program/libstoragefdlo.so +%{baseinstdir}/program/libsvgiolo.so +%{baseinstdir}/program/libsvxlo.so +%{baseinstdir}/program/libsvxcorelo.so +%{baseinstdir}/program/libswdlo.so +%{baseinstdir}/program/libswlo.so +%{baseinstdir}/program/libtextconv_dict.so +%{baseinstdir}/program/libtextconversiondlgslo.so +%{baseinstdir}/program/libtextfdlo.so +%{baseinstdir}/program/libodfflatxmllo.so +# TODO: shouldn't it have lo suffix? +%{baseinstdir}/program/libucbhelper.so +%{baseinstdir}/program/libucpchelp1.so +%{baseinstdir}/program/libucpdav1.so +%{baseinstdir}/program/libucpftp1.so +%{baseinstdir}/program/libucphier1.so +%{baseinstdir}/program/libucppkg1.so +%{baseinstdir}/program/libunordflo.so +%{baseinstdir}/program/libunopkgapp.so +%{baseinstdir}/program/libunoxmllo.so +%{baseinstdir}/program/libuuilo.so +%{baseinstdir}/program/libvbahelperlo.so +%{baseinstdir}/program/libvclplug_genlo.so +%{baseinstdir}/program/libvclplug_gtklo.so +%{baseinstdir}/program/libxmlfalo.so +%{baseinstdir}/program/libxmlfdlo.so +%{baseinstdir}/program/libxoflo.so +%{baseinstdir}/program/libxsec_fw.so +%{baseinstdir}/program/libxsec_xmlsec.so +%{baseinstdir}/program/libxsltdlglo.so +%{baseinstdir}/program/libxsltfilterlo.so +%{baseinstdir}/program/libxstor.so +# TODO how useful this is in Fedora? +%{baseinstdir}/program/liblosessioninstalllo.so +%{baseinstdir}/program/libmigrationoo2lo.so +%{baseinstdir}/program/libmigrationoo3lo.so +%{baseinstdir}/program/libmsformslo.so +%dir %{baseinstdir}/program/opengl +%{baseinstdir}/program/opengl/areaHashCRC64TFragmentShader.glsl +%{baseinstdir}/program/opengl/areaScaleFragmentShader.glsl +%{baseinstdir}/program/opengl/areaScaleFastFragmentShader.glsl +%{baseinstdir}/program/opengl/backgroundFragmentShader.glsl +%{baseinstdir}/program/opengl/backgroundVertexShader.glsl +%{baseinstdir}/program/opengl/blendedTextureFragmentShader.glsl +%{baseinstdir}/program/opengl/blendedTextureVertexShader.glsl +%{baseinstdir}/program/opengl/commonFragmentShader.glsl +%{baseinstdir}/program/opengl/commonVertexShader.glsl +%{baseinstdir}/program/opengl/convolutionFragmentShader.glsl +%{baseinstdir}/program/opengl/debugFragmentShader.glsl +%{baseinstdir}/program/opengl/debugVertexShader.glsl +%{baseinstdir}/program/opengl/diffTextureFragmentShader.glsl +%{baseinstdir}/program/opengl/dumbVertexShader.glsl +%{baseinstdir}/program/opengl/dummyVertexShader.glsl +%{baseinstdir}/program/opengl/linearGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/linearMultiColorGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/linearTwoColorGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/maskedTextureFragmentShader.glsl +%{baseinstdir}/program/opengl/maskedTextureVertexShader.glsl +%{baseinstdir}/program/opengl/maskFragmentShader.glsl +%{baseinstdir}/program/opengl/pickingFragmentShader.glsl +%{baseinstdir}/program/opengl/pickingVertexShader.glsl +%{baseinstdir}/program/opengl/radialGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/radialMultiColorGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/radialTwoColorGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/rectangularMultiColorGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/rectangularTwoColorGradientFragmentShader.glsl +%{baseinstdir}/program/opengl/renderTextureFragmentShader.glsl +%{baseinstdir}/program/opengl/renderTextureVertexShader.glsl +%{baseinstdir}/program/opengl/replaceColorFragmentShader.glsl +%{baseinstdir}/program/opengl/screenTextFragmentShader.glsl +%{baseinstdir}/program/opengl/screenTextVertexShader.glsl +%{baseinstdir}/program/opengl/shape3DFragmentShader.glsl +%{baseinstdir}/program/opengl/shape3DFragmentShaderBatch.glsl +%{baseinstdir}/program/opengl/shape3DFragmentShaderBatchScroll.glsl +%{baseinstdir}/program/opengl/shape3DFragmentShaderV300.glsl +%{baseinstdir}/program/opengl/shape3DVertexShader.glsl +%{baseinstdir}/program/opengl/shape3DVertexShaderBatch.glsl +%{baseinstdir}/program/opengl/shape3DVertexShaderBatchScroll.glsl +%{baseinstdir}/program/opengl/shape3DVertexShaderV300.glsl +%{baseinstdir}/program/opengl/solidFragmentShader.glsl +%{baseinstdir}/program/opengl/symbolFragmentShader.glsl +%{baseinstdir}/program/opengl/symbolVertexShader.glsl +%{baseinstdir}/program/opengl/textFragmentShader.glsl +%{baseinstdir}/program/opengl/textFragmentShaderBatch.glsl +%{baseinstdir}/program/opengl/textVertexShader.glsl +%{baseinstdir}/program/opengl/textVertexShaderBatch.glsl +%{baseinstdir}/program/opengl/textureFragmentShader.glsl +%{baseinstdir}/program/opengl/textureVertexShader.glsl +%{baseinstdir}/program/opengl/transformedTextureVertexShader.glsl +%{baseinstdir}/program/open-url +%{baseinstdir}/program/types/offapi.rdb +%{baseinstdir}/program/libpasswordcontainerlo.so +%{baseinstdir}/program/pagein-common +%{baseinstdir}/program/pluginapp.bin +%dir %{baseinstdir}/program/resource +%{baseinstdir}/program/resource/avmediaen-US.res +%{baseinstdir}/program/resource/accen-US.res +%{baseinstdir}/program/resource/basctlen-US.res +%{baseinstdir}/program/resource/biben-US.res +%{baseinstdir}/program/resource/chartcontrolleren-US.res +%{baseinstdir}/program/resource/cuien-US.res +%{baseinstdir}/program/resource/dbaen-US.res +%{baseinstdir}/program/resource/dbmmen-US.res +%{baseinstdir}/program/resource/dbuen-US.res +%{baseinstdir}/program/resource/dbwen-US.res +%{baseinstdir}/program/resource/deploymenten-US.res +%{baseinstdir}/program/resource/deploymentguien-US.res +%{baseinstdir}/program/resource/dkten-US.res +%{baseinstdir}/program/resource/editengen-US.res +%{baseinstdir}/program/resource/epsen-US.res +%{baseinstdir}/program/resource/euren-US.res +%{baseinstdir}/program/resource/fps_officeen-US.res +%{baseinstdir}/program/resource/frmen-US.res +%{baseinstdir}/program/resource/fween-US.res +%{baseinstdir}/program/resource/galen-US.res +%{baseinstdir}/program/resource/impen-US.res +%{baseinstdir}/program/resource/ofaen-US.res +%{baseinstdir}/program/resource/pcren-US.res +%{baseinstdir}/program/resource/pdffilteren-US.res +%{baseinstdir}/program/resource/sben-US.res +%{baseinstdir}/program/resource/scnen-US.res +%{baseinstdir}/program/resource/sden-US.res +%{baseinstdir}/program/resource/sfxen-US.res +%{baseinstdir}/program/resource/sdbten-US.res +%{baseinstdir}/program/resource/svlen-US.res +%{baseinstdir}/program/resource/svten-US.res +%{baseinstdir}/program/resource/svxen-US.res +%{baseinstdir}/program/resource/swen-US.res +%{baseinstdir}/program/resource/tplen-US.res +%{baseinstdir}/program/resource/uuien-US.res +%{baseinstdir}/program/resource/upden-US.res +%{baseinstdir}/program/resource/vclen-US.res +%{baseinstdir}/program/resource/wzien-US.res +%{baseinstdir}/program/resource/xmlsecen-US.res +%{baseinstdir}/program/resource/xsltdlgen-US.res +%{baseinstdir}/program/senddoc +%dir %{baseinstdir}/program/services +%{baseinstdir}/program/services/services.rdb +%{baseinstdir}/program/libsimplecanvaslo.so +%{baseinstdir}/program/libslideshowlo.so +%{baseinstdir}/program/libsofficeapp.so +%{baseinstdir}/program/libstringresourcelo.so +%{baseinstdir}/program/libsysshlo.so +%{baseinstdir}/program/libucpcmis1lo.so +%{baseinstdir}/program/libucpexpand1lo.so +%{baseinstdir}/program/libucpextlo.so +%{baseinstdir}/program/libucpimagelo.so +%{baseinstdir}/program/libucptdoc1lo.so +%{baseinstdir}/program/lounorc +%{baseinstdir}/program/libupdatefeedlo.so +%{baseinstdir}/program/uri-encode +%{baseinstdir}/program/libvbaeventslo.so +%{baseinstdir}/program/libvclcanvaslo.so +%{baseinstdir}/program/versionrc +%{baseinstdir}/program/xid-fullscreen-on-all-monitors +%dir %{baseinstdir}/share +%dir %{baseinstdir}/share/Scripts +%{baseinstdir}/share/Scripts/java +%{baseinstdir}/share/autocorr +%dir %{_datadir}/autocorr +%dir %{baseinstdir}/share/autotext +%dir %{_datadir}/autocorr +%{baseinstdir}/share/autocorr +%{baseinstdir}/share/autotext/en-US +%{baseinstdir}/share/basic +%dir %{baseinstdir}/share/config +%{baseinstdir}/share/config/images_breeze.zip +%{baseinstdir}/share/config/images_galaxy.zip +%{baseinstdir}/share/config/images_hicontrast.zip +%{baseinstdir}/share/config/images_oxygen.zip +%{baseinstdir}/share/config/images_sifr.zip +%{baseinstdir}/share/config/images_tango.zip +%dir %{baseinstdir}/share/config/soffice.cfg +%{baseinstdir}/share/config/soffice.cfg/modules +%if %{with langpacks} +# UI translations go into langpacks +%exclude %{baseinstdir}/share/config/soffice.cfg/modules/*/ui/res +%endif +%{baseinstdir}/share/config/soffice.cfg/*/ui +%if %{with langpacks} +# UI translations go into langpacks +%exclude %{baseinstdir}/share/config/soffice.cfg/*/ui/res +%endif +%{baseinstdir}/share/palette +%{baseinstdir}/share/config/webcast +%{baseinstdir}/share/config/wizard +%dir %{baseinstdir}/share/dtd +%{baseinstdir}/share/dtd/officedocument +%{baseinstdir}/share/gallery +%dir %{baseinstdir}/share/labels +%{baseinstdir}/share/labels/labels.xml +%dir %{baseinstdir}/share/psprint +%config %{baseinstdir}/share/psprint/psprint.conf +%{baseinstdir}/share/psprint/driver +%dir %{baseinstdir}/share/registry +%{baseinstdir}/share/registry/gnome.xcd +%{baseinstdir}/share/registry/lingucomponent.xcd +%{baseinstdir}/share/registry/main.xcd +%{baseinstdir}/share/registry/oo-ad-ldap.xcd.sample +%{baseinstdir}/share/registry/oo-ldap.xcd.sample +%{baseinstdir}/share/registry/Langpack-en-US.xcd +%dir %{baseinstdir}/share/registry/res +%{baseinstdir}/share/registry/res/fcfg_langpack_en-US.xcd +%dir %{baseinstdir}/share/template +%{baseinstdir}/share/template/en-US +%dir %{baseinstdir}/share/template/common +%{baseinstdir}/share/template/common/internal +%{baseinstdir}/share/template/common/layout +%{baseinstdir}/share/template/common/officorr +%{baseinstdir}/share/template/common/offimisc +%{baseinstdir}/share/template/common/personal +%{baseinstdir}/share/template/common/presnt +%{baseinstdir}/share/template/common/styles +%{baseinstdir}/share/template/common/wizard +%{baseinstdir}/share/template/wizard +%dir %{baseinstdir}/share/wordbook +%{baseinstdir}/share/wordbook/en-GB.dic +%{baseinstdir}/share/wordbook/en-US.dic +%{baseinstdir}/share/wordbook/technical.dic +%{baseinstdir}/program/liblnthlo.so +%{_bindir}/unopkg +%{_mandir}/man1/unopkg.1* +#icons and mime +%{_datadir}/icons/*/*/*/libreoffice* +%{_datadir}/mime-info/libreoffice.* +%{baseinstdir}/program/libxmlsecurity.so +%{_datadir}/mime/packages/libreoffice.xml +%{baseinstdir}/program/libconfigmgrlo.so +%{baseinstdir}/program/libdesktopbe1lo.so +%{baseinstdir}/program/libfsstoragelo.so +%{baseinstdir}/program/libgconfbe1lo.so +%{baseinstdir}/program/libi18npoollo.so +%{baseinstdir}/program/libbasegfxlo.so +# TODO: shouldn't it have lo suffix? +%{baseinstdir}/program/libcomphelper.so +%{baseinstdir}/program/libfwelo.so +%{baseinstdir}/program/libfwilo.so +%{baseinstdir}/program/libfwklo.so +%{baseinstdir}/program/libfwllo.so +%{baseinstdir}/program/libfwmlo.so +%{baseinstdir}/program/libi18nlangtag.so +# TODO: shouldn't it have lo suffix? +%{baseinstdir}/program/libi18nutil.so +%{baseinstdir}/program/libpackage2.so +%{baseinstdir}/program/libsblo.so +%{baseinstdir}/program/libsfxlo.so +%{baseinstdir}/program/libsotlo.so +%{baseinstdir}/program/libspllo.so +%{baseinstdir}/program/libsvllo.so +%{baseinstdir}/program/libsvtlo.so +%{baseinstdir}/program/libtklo.so +%{baseinstdir}/program/libtllo.so +%{baseinstdir}/program/libucb1.so +%{baseinstdir}/program/libucpfile1.so +%{baseinstdir}/program/libutllo.so +%{baseinstdir}/program/libvcllo.so +%{baseinstdir}/program/libwriterperfectlo.so +%{baseinstdir}/program/libxmlscriptlo.so +%{baseinstdir}/program/libxolo.so +%{baseinstdir}/program/liblocalebe1lo.so +%{baseinstdir}/program/libucpgio1lo.so +%{baseinstdir}/program/types/oovbaapi.rdb +#share unopkg +%dir %{baseinstdir}/share/extensions +%{baseinstdir}/share/extensions/package.txt +%{baseinstdir}/program/unopkg +%{baseinstdir}/program/unopkg.bin +%{baseinstdir}/program/bootstraprc +%{baseinstdir}/program/fundamentalrc +%{baseinstdir}/program/setuprc +%doc %{baseinstdir}/CREDITS.fodt +%doc %{baseinstdir}/LICENSE +%doc %{baseinstdir}/LICENSE.html +%doc %{baseinstdir}/LICENSE.fodt +%doc %{baseinstdir}/NOTICE +%{baseinstdir}/program/intro.* +%{baseinstdir}/program/soffice +%{baseinstdir}/program/soffice.bin +%{baseinstdir}/program/sofficerc +%{baseinstdir}/program/unoinfo +%{baseinstdir}/program/oosplash +%{baseinstdir}/program/shell/ +%dir %{baseinstdir}/share/filter +%{baseinstdir}/share/filter/oox-drawingml-adj-names +%{baseinstdir}/share/filter/oox-drawingml-cs-presets +%{baseinstdir}/share/filter/vml-shape-types +%{baseinstdir}/share/xdg/ +%{baseinstdir}/program/redirectrc +%{_datadir}/applications/libreoffice-startcenter.desktop +#launchers +%{_bindir}/libreoffice +%{_bindir}/openoffice.org +%{_bindir}/soffice +%{_bindir}/ooffice +%{_bindir}/ooviewdoc +%{_mandir}/man1/libreoffice.1* +%{_mandir}/man1/openoffice.org.1* +%{_mandir}/man1/soffice.1* +%{_mandir}/man1/ooffice.1* +%{_mandir}/man1/ooviewdoc.1* + +%post core +update-desktop-database %{_datadir}/applications &> /dev/null || : +for theme in hicolor locolor; do + touch --no-create %{_datadir}/icons/$theme &>/dev/null || : +done +touch --no-create %{_datadir}/mime/packages &> /dev/null || : + +%postun core +update-desktop-database %{_datadir}/applications &> /dev/null || : +if [ $1 -eq 0 ] ; then + for theme in hicolor locolor; do + touch --no-create %{_datadir}/icons/$theme &>/dev/null || : + gtk-update-icon-cache -q %{_datadir}/icons/$theme &>/dev/null || : + done + touch --no-create %{_datadir}/mime/packages &> /dev/null || : + update-mime-database %{?fedora:-n} %{_datadir}/mime &> /dev/null || : +fi + +%posttrans core +for theme in hicolor locolor; do + gtk-update-icon-cache -q %{_datadir}/icons/$theme &>/dev/null || : +done +update-mime-database %{?fedora:-n} %{_datadir}/mime &> /dev/null || : + + +%files base +%{baseinstdir}/help/en-US/sdatabase.* +%{baseinstdir}/program/classes/hsqldb.jar +%{baseinstdir}/program/classes/reportbuilder.jar +%{baseinstdir}/program/classes/reportbuilderwizard.jar +%{baseinstdir}/program/classes/sdbc_hsqldb.jar +%{baseinstdir}/program/libabplo.so +%{baseinstdir}/program/libdbplo.so +%{baseinstdir}/program/libhsqldb.so +%{baseinstdir}/program/librptlo.so +%{baseinstdir}/program/librptuilo.so +%{baseinstdir}/program/librptxmllo.so +%{baseinstdir}/program/resource/abpen-US.res +%{baseinstdir}/program/resource/cnren-US.res +%{baseinstdir}/program/resource/dbpen-US.res +%{baseinstdir}/program/resource/rpten-US.res +%{baseinstdir}/program/resource/rptuien-US.res +%{baseinstdir}/program/resource/sdbclen-US.res +%{baseinstdir}/program/resource/sdberren-US.res +%{baseinstdir}/share/registry/base.xcd +%{baseinstdir}/share/registry/reportbuilder.xcd +%{baseinstdir}/program/sbase +%{_datadir}/appdata/libreoffice-base.appdata.xml +%{_datadir}/applications/libreoffice-base.desktop +%{_bindir}/oobase +%{_mandir}/man1/oobase.1* + +%post base +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%postun base +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%files bsh +%{baseinstdir}/program/classes/ScriptProviderForBeanShell.jar +%{baseinstdir}/program/services/scriptproviderforbeanshell.rdb +%{baseinstdir}/share/Scripts/beanshell + +%files rhino +%{baseinstdir}/program/classes/js.jar +%{baseinstdir}/program/classes/ScriptProviderForJavaScript.jar +%{baseinstdir}/program/services/scriptproviderforjavascript.rdb +%{baseinstdir}/share/Scripts/javascript + +%files wiki-publisher +%docdir %{baseinstdir}/share/extensions/wiki-publisher/license +%{baseinstdir}/share/extensions/wiki-publisher + +%files nlpsolver +%docdir %{baseinstdir}/share/extensions/nlpsolver/help +%{baseinstdir}/share/extensions/nlpsolver + +%files officebean +%{baseinstdir}/program/classes/officebean.jar +%{baseinstdir}/program/libofficebean.so + +%files ogltrans +%{baseinstdir}/program/libOGLTranslo.so +%{baseinstdir}/program/opengl/basicVertexShader.glsl +%{baseinstdir}/program/opengl/dissolveFragmentShader.glsl +%{baseinstdir}/program/opengl/staticFragmentShader.glsl +%{baseinstdir}/share/config/soffice.cfg/simpress/transitions-ogl.xml +%{baseinstdir}/share/registry/ogltrans.xcd + +%files pdfimport +%{baseinstdir}/program/libpdfimportlo.so +%{baseinstdir}/program/xpdfimport +%{baseinstdir}/share/registry/pdfimport.xcd +%dir %{baseinstdir}/share/xpdfimport +%{baseinstdir}/share/xpdfimport/xpdfimport_err.pdf + +%_font_pkg -n %{fontname} opens___.ttf +%doc instdir/LICENSE + +%files calc +%{baseinstdir}/help/en-US/scalc.* +%{baseinstdir}/program/libanalysislo.so +%{baseinstdir}/program/libcalclo.so +%{baseinstdir}/program/libdatelo.so +%{baseinstdir}/program/libforlo.so +%{baseinstdir}/program/libforuilo.so +%{baseinstdir}/program/libpricinglo.so +%{baseinstdir}/program/libsclo.so +%{baseinstdir}/program/libscdlo.so +%{baseinstdir}/program/libscfiltlo.so +%{baseinstdir}/program/libscuilo.so +%{baseinstdir}/program/libsolverlo.so +%{baseinstdir}/program/libwpftcalclo.so +%{baseinstdir}/program/resource/analysisen-US.res +%{baseinstdir}/program/resource/dateen-US.res +%{baseinstdir}/program/resource/foren-US.res +%{baseinstdir}/program/resource/foruien-US.res +%{baseinstdir}/program/resource/pricingen-US.res +%{baseinstdir}/program/resource/scen-US.res +%{baseinstdir}/program/resource/solveren-US.res +%{baseinstdir}/program/libvbaobjlo.so +%{baseinstdir}/share/registry/calc.xcd +%{baseinstdir}/program/pagein-calc +%{baseinstdir}/program/scalc +%{_datadir}/appdata/libreoffice-calc.appdata.xml +%{_datadir}/applications/libreoffice-calc.desktop +%{_bindir}/oocalc +%{_mandir}/man1/oocalc.1* + +%post calc +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%postun calc +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%files draw +%{baseinstdir}/help/en-US/sdraw.* +%{baseinstdir}/share/registry/draw.xcd +%{baseinstdir}/program/pagein-draw +%{baseinstdir}/program/sdraw +%{_datadir}/appdata/libreoffice-draw.appdata.xml +%{_datadir}/applications/libreoffice-draw.desktop +%{_bindir}/oodraw +%{_mandir}/man1/oodraw.1* + +%post draw +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%postun draw +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%files emailmerge +%{baseinstdir}/program/mailmerge.py* +%{baseinstdir}/program/msgbox.py* + +%files writer +%{baseinstdir}/help/en-US/swriter.* +%{baseinstdir}/program/libhwplo.so +%{baseinstdir}/program/liblwpftlo.so +%{baseinstdir}/program/libmswordlo.so +%{baseinstdir}/program/libswuilo.so +%{baseinstdir}/program/libt602filterlo.so +%{baseinstdir}/program/libwpftwriterlo.so +%{baseinstdir}/program/libwriterfilterlo.so +%{baseinstdir}/program/libvbaswobjlo.so +%{baseinstdir}/program/resource/t602filteren-US.res +%{baseinstdir}/share/registry/writer.xcd +%{baseinstdir}/program/pagein-writer +%{baseinstdir}/program/swriter +%{_datadir}/appdata/libreoffice-writer.appdata.xml +%{_datadir}/applications/libreoffice-writer.desktop +%{_bindir}/oowriter +%{_mandir}/man1/oowriter.1* + +%post writer +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%postun writer +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%files impress +%{baseinstdir}/help/en-US/simpress.* +%{baseinstdir}/program/libanimcorelo.so +%{baseinstdir}/program/libplacewarelo.so +%{baseinstdir}/program/libPresentationMinimizerlo.so +%{baseinstdir}/program/libPresenterScreenlo.so +%{baseinstdir}/program/libwpftimpresslo.so +%dir %{baseinstdir}/share/config/soffice.cfg/simpress +%{baseinstdir}/share/config/soffice.cfg/simpress/effects.xml +%{baseinstdir}/share/config/soffice.cfg/simpress/layoutlist.xml +%{baseinstdir}/share/config/soffice.cfg/simpress/objectlist.xml +%{baseinstdir}/share/config/soffice.cfg/simpress/transitions.xml +%{baseinstdir}/share/registry/impress.xcd +%{baseinstdir}/program/pagein-impress +%{baseinstdir}/program/simpress +%{_datadir}/appdata/libreoffice-impress.appdata.xml +%{_datadir}/applications/libreoffice-impress.desktop +%{_bindir}/ooimpress +%{_mandir}/man1/ooimpress.1* + +%post impress +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%postun impress +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%files math +%{baseinstdir}/help/en-US/smath.* +%{baseinstdir}/program/libsmlo.so +%{baseinstdir}/program/libsmdlo.so +%{baseinstdir}/program/resource/smen-US.res +%{baseinstdir}/share/registry/math.xcd +%{baseinstdir}/program/smath +%{_datadir}/applications/libreoffice-math.desktop +%{_bindir}/oomath +%{_mandir}/man1/oomath.1* + +%post math +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%postun math +update-desktop-database %{_datadir}/applications &> /dev/null || : + +%files graphicfilter +%{baseinstdir}/program/libflashlo.so +%{baseinstdir}/program/libgraphicfilterlo.so +%{baseinstdir}/program/libsvgfilterlo.so +%{baseinstdir}/program/libwpftdrawlo.so +%{baseinstdir}/share/registry/graphicfilter.xcd + +%files xsltfilter +%{baseinstdir}/share/xslt +%{baseinstdir}/share/registry/xsltfilter.xcd +%{_datadir}/applications/libreoffice-xsltfilter.desktop + +%files postgresql +%{baseinstdir}/program/libpostgresql-sdbclo.so +%{baseinstdir}/program/libpostgresql-sdbc-impllo.so +%{baseinstdir}/program/postgresql-sdbc.ini +%{baseinstdir}/program/services/postgresql-sdbc.rdb +%{baseinstdir}/share/registry/postgresql.xcd + +%files ure +%{baseinstdir}/program/classes/java_uno.jar +%{baseinstdir}/program/classes/juh.jar +%{baseinstdir}/program/classes/jurt.jar +%{baseinstdir}/program/classes/ridl.jar +%{baseinstdir}/program/classes/unoloader.jar +%{baseinstdir}/program/javaldx +%{baseinstdir}/program/javavendors.xml +%{baseinstdir}/program/jvmfwk3rc +%{baseinstdir}/program/JREProperties.class +%{baseinstdir}/program/libaffine_uno_uno.so +%{baseinstdir}/program/libbinaryurplo.so +%{baseinstdir}/program/libbootstraplo.so +%{baseinstdir}/program/libgcc3_uno.so +%{baseinstdir}/program/libintrospectionlo.so +%{baseinstdir}/program/libinvocadaptlo.so +%{baseinstdir}/program/libinvocationlo.so +%{baseinstdir}/program/libiolo.so +%{baseinstdir}/program/libjava_uno.so +%{baseinstdir}/program/libjavaloaderlo.so +%{baseinstdir}/program/libjavavmlo.so +%{baseinstdir}/program/libjpipe.so +%{baseinstdir}/program/libjuh.so +%{baseinstdir}/program/libjuhx.so +%{baseinstdir}/program/libjvmaccesslo.so +%{baseinstdir}/program/libjvmfwklo.so +%{baseinstdir}/program/liblog_uno_uno.so +%{baseinstdir}/program/libnamingservicelo.so +%{baseinstdir}/program/libproxyfaclo.so +%{baseinstdir}/program/libreflectionlo.so +%{baseinstdir}/program/libreglo.so +%{baseinstdir}/program/libsal_textenclo.so +%{baseinstdir}/program/libstocserviceslo.so +%{baseinstdir}/program/libstorelo.so +%{baseinstdir}/program/libuno_cppu.so.3 +%{baseinstdir}/program/libuno_cppuhelpergcc3.so.3 +%{baseinstdir}/program/libuno_purpenvhelpergcc3.so.3 +%{baseinstdir}/program/libuno_sal.so.3 +%{baseinstdir}/program/libuno_salhelpergcc3.so.3 +%{baseinstdir}/program/libunoidllo.so +%{baseinstdir}/program/libunsafe_uno_uno.so +%{baseinstdir}/program/libuuresolverlo.so +%{baseinstdir}/program/libxmlreaderlo.so +%{baseinstdir}/program/regmerge +%{baseinstdir}/program/regview +%{baseinstdir}/program/services.rdb +%{baseinstdir}/program/types.rdb +%{baseinstdir}/program/uno +%{baseinstdir}/program/uno.bin +%{baseinstdir}/program/unorc + +%files sdk +%{sdkinstdir}/ +%exclude %{sdkinstdir}/docs/ +%exclude %{sdkinstdir}/examples/ + +%files sdk-doc +%docdir %{sdkinstdir}/docs +%{sdkinstdir}/docs/ +%{sdkinstdir}/examples/ + +%files pyuno +%{baseinstdir}/program/libpyuno.so +%{baseinstdir}/program/pythonloader.py* +%{baseinstdir}/program/libpythonloaderlo.so +%{baseinstdir}/program/pythonloader.unorc +%{baseinstdir}/program/pythonscript.py* +%{baseinstdir}/program/pyuno.so +%{baseinstdir}/program/services/pyuno.rdb +%{baseinstdir}/program/services/scriptproviderforpython.rdb +%{baseinstdir}/program/wizards +%{baseinstdir}/share/Scripts/python +%exclude %{baseinstdir}/share/Scripts/python/LibreLogo +%{libo_python_sitearch}/uno.py* +%{libo_python_sitearch}/unohelper.py* +%{libo_python_sitearch}/officehelper.py* +%if 0%{libo_use_python3} +%{libo_python_sitearch}/__pycache__/uno.cpython-* +%{libo_python_sitearch}/__pycache__/unohelper.cpython-* +%{libo_python_sitearch}/__pycache__/officehelper.cpython-* +%endif +%{baseinstdir}/share/registry/pyuno.xcd + +%files librelogo +%{baseinstdir}/share/registry/librelogo.xcd +%{baseinstdir}/share/Scripts/python/LibreLogo + +%files glade +%{baseinstdir}/program/ui-previewer +%{_datadir}/glade +%{_datadir}/glade3 + +%if 0%{?fedora} + +%files kde +%{baseinstdir}/program/kde4-open-url +%{baseinstdir}/program/libkde4be1lo.so +%{baseinstdir}/program/libvclplug_kde4lo.so + +%files gtk3 +%{baseinstdir}/program/libvclplug_gtk3lo.so + +%endif + +%files -n libreofficekit +%{_libdir}/girepository-1.0/LOKDocView-%{girapiversion}.typelib +%{_libdir}/liblibreofficekitgtk.so + +%files -n libreofficekit-devel +%{_libdir}/gir-1.0/LOKDocView-%{girapiversion}.gir + +%changelog +* Wed Feb 14 2018 Caolán McNamara - 1:5.0.6.2-15 +- Resolves: rhbz#1545034 - CVE-2018-1055 CVE-2018-6871 + +* Fri Jun 16 2017 Caolán McNamara - 1:5.0.6.2-14 +- Resolves: rhbz#1454693 segv on interrupting tiled rendering + +* Thu Jun 15 2017 Caolán McNamara - 1:5.0.6.2-13 +- Related: rhbz#1444437 remove timer if document closed before it fires + +* Tue Jun 06 2017 Caolán McNamara - 1:5.0.6.2-12 +- Resolves: rhbz#1454598 crash on selecting bullet from toolbar + +* Thu May 25 2017 Caolán McNamara - 1:5.0.6.2-11 +- Related: rhbz#1444437 restart second instance cleanly + +* Wed May 10 2017 Caolán McNamara - 1:5.0.6.2-10 +- Resolves: rhbz#1444437 segv in gnome-documents integration + +* Wed Apr 26 2017 David Tardon - 1:5.0.6.2-9 +- Resolves: rhbz#1445635 CVE-2017-7870 Heap-buffer-overflow in + tools::Polygon::Insert + +* Fri Mar 31 2017 Caolán McNamara - 1:5.0.6.2-8 +- Resolves: rhbz#1437537 fix csv a11y + +* Sun Mar 26 2017 David Tardon - 1:5.0.6.2-7 +- Resolves: rhbz#1431539 gnome-documents needs libreofficekit +- Resolves: rhbz#1435535 CVE-2017-3157 Arbitrary file disclosure in + Calc and Writer + +* Tue Feb 21 2017 Caolán McNamara - 1:5.0.6.2-6 +- Resolves: rhbz#1401082 gnome hangs opening certain docx +- Resolves: rhbz#1421726 drop use of CAIRO_OPERATOR_DIFFERENCE + +* Thu Feb 09 2017 Michael Stahl - 1:5.0.6.2-5 +- Resolves: rhbz#1411327 Encrypted files opening as plain text after + cancelling password dialog + +* Fri Dec 02 2016 Caolán McNamara - 1:5.0.6.2-4 +- Resolves: rhbz#1378521 crash in calc on exit after using csv dialog with a11y enabled +- Resolves: rhbz#1397992 crash in calc on closing dialog with a11y enabled + +* Tue Aug 23 2016 David Tardon - 1:5.0.6.2-3 +- Resolves: rhbz#1364335 tooltips are truncated + +* Fri Jul 08 2016 David Tardon - 1:5.0.6.2-2 +- Resolves: rhbz#1353839 CVE-2016-4324 dereference of invalid STL iterator on + processing RTF file + +* Tue May 03 2016 David Tardon - 1:5.0.6.2-1 +- Related: rhbz#1290148 rebase to 5.0.6 +- Related: rhbz#1290148 include more fixes from F-23 + +* Fri Mar 04 2016 David Tardon - 1:5.0.5.2-2 +- Related: rhbz#1290148 remove unintentional dependency of libreoffice-core on + libreoffice-calc +- Related: rhbz#1290148 restore lost changelog entry +- Related: rhbz#1290148 add additional 5.0.6 patches + +* Tue Mar 01 2016 David Tardon - 1:5.0.5.2-1 +- Resolves: rhbz#1290148 rebase to 5.0.x + +* Wed Dec 02 2015 David Tardon - 1:4.3.7.2-5.1 +- Resolves: rhbz#1285820 various flaws +- CVE-2015-4551 Arbitrary file disclosure in Calc and Writer +- CVE-2015-5212 Integer underflow in PrinterSetup length +- CVE-2015-5213 Integer overflow in DOC files +- CVE-2015-5214 Bookmarks in DOC documents are insufficiently checked + causing memory corruption + +* Tue Jul 14 2015 David Tardon - 1:4.3.7.2-5 +- Related: rhbz#1205091 fix for ppc64 +- Related: rhbz#1205091 fix deps for gdb-debug-support subpackage + +* Mon May 25 2015 David Tardon - 1:4.3.7.2-4 +- Related: rhbz#1205091 add another bunch of fixes from Fedora +- rhbz#1219137 tweak ruler for happenchance side-effect +- Related: rhbz#1205091 do not filter out requires + +* Tue May 12 2015 David Tardon - 1:4.3.7.2-3 +- Related: rhbz#1205091 fix build on ppc64le + +* Mon May 11 2015 David Tardon - 1:4.3.7.2-2 +- Related: rhbz#1205091 add more fixes from f21 +- Resolves: tdf#91078 check also DBData modified, not only named expressions +- don't include red spelling underlines on bitmap copy/paste + +* Mon May 04 2015 David Tardon - 1:4.3.7.2-1 +- Resolves: rhbz#1205091 rebase to 4.3.7 + +* Mon Dec 01 2014 Stephan Bergmann - 1:4.2.6.3-5 +- Resolves: rhbz#1098973 crash on exit + +* Fri Nov 21 2014 David Tardon - 1:4.2.6.3-4 +- Resolves: rhbz#1111216 LibreOffice Calc: PDF export of an empty document fails + with Write Error + +* Mon Nov 17 2014 Caolán McNamara - 1:4.2.6.3-3 +- CVE-2014-3693: Disable sdremote by default and improve flow control + +* Fri Sep 05 2014 David Tardon - 1:4.2.6.3-2 +- Related: rhbz#1119709 port LibreOffice to aarch64 + +* Thu Aug 28 2014 David Tardon - 1:4.2.6.3-1 +- Resolves: rhbz#1119709 rebase to 4.2.6 + +* Fri Aug 22 2014 Caolán McNamara - 1:4.1.4.2-4 +- Resolves: rhbz#1125588 port LibreOffice to ppc64le + +* Fri Jan 24 2014 Daniel Mach - 1:4.1.4.2-3 +- Mass rebuild 2014-01-24 + +* Mon Jan 13 2014 Caolán McNamara - 1:4.1.4.2-2 +- Resolves: rhbz#1040777 rename "Oriya" to "Odia" + +* Wed Jan 08 2014 David Tardon - 1:4.1.4.2-1 +- Resolves: rhbz#1049791 rebase to 4.1.4 +- also add a load of 4.1.5 patches + +* Fri Dec 27 2013 Daniel Mach - 1:4.1.3.2-6 +- Mass rebuild 2013-12-27 + +* Wed Dec 11 2013 Caolán McNamara - 1:4.1.3.2-5 +- Resolves: rhbz#1035092 no shortcut key for Italian Tools + +* Tue Nov 12 2013 David Tardon - 1:4.1.3.2-4 +- Related: rhbz#1019277 fix rpmdiff problem + +* Fri Nov 01 2013 David Tardon - 1:4.1.3.2-3 +- Resolves: rhbz#1019277 rebase libreoffice to 4.1.3 + +* Mon Sep 16 2013 David Tardon - 1:4.1.0.4-6 +- rebuild for ICU ABI break + +* Tue Jul 30 2013 Stephan Bergmann - 1:4.1.0.4-5 +- Resolves: rhbz#989246 Honor user's JavaDriverClass override in mysql driver +- Resolves: fdo#67045 fix several nasty screen selection issues + +* Tue Jul 30 2013 Caolán McNamara - 1:4.1.0.4-4 +- Resolves: rhbz#989686 Fix crash with stripping whitespace from toc entries + +* Mon Jul 29 2013 David Tardon - 1:4.1.0.4-3 +- make libwpd-based filters work correctly with newest libwpd + +* Sun Jul 28 2013 Petr Machata - 1:4.1.0.4-2 +- Rebuild for boost 1.54.0 + +* Wed Jul 24 2013 David Tardon - 1:4.1.0.4-1 +- 4.1.0 rc4 + +* Mon Jul 22 2013 Eike Rathke - 1:4.1.0.3-2 +- force rebuild with icu-50.1.2-7 + +* Thu Jul 18 2013 David Tardon - 1:4.1.0.3-1 +- 4.1.0 rc3 +- Resolves: fdo#48835 GNOME3 app menu + +* Thu Jul 18 2013 Caolán McNamara - 1:4.1.0.2-5 +- silence scary gcc warning +- fdo#66924 switching to master view is broken + +* Tue Jul 16 2013 David Tardon - 1:4.1.0.2-4 +- bump release + +* Fri Jul 12 2013 David Tardon - 1:4.1.0.2-3 +- Resolves: rhbz#983809 libreoffice-base misses deps on needed java packages + +* Thu Jul 11 2013 David Tardon - 1:4.1.0.2-2 +- Resolves: rhbz#980387 Exporting a odg to jpg or tiff generates error + +* Thu Jul 04 2013 David Tardon - 1:4.1.0.2-1 +- 4.1.0 rc2 + +* Mon Jul 01 2013 Caolán McNamara - 1:4.1.0.1-8 +- Resolves: rhbz#979758 crash on Diagrammen in LibreOffice help page + +* Thu Jun 27 2013 David Tardon - 1:4.1.0.1-7 +- bump revision + +* Mon Jun 24 2013 Marek Kasik - 1:4.1.0.1-6 +- Rebuild (poppler-0.22.5) + +* Mon Jun 24 2013 David Tardon - 1:4.1.0.1-5 +- fix build on big endian archs + +* Mon Jun 24 2013 David Tardon - 1:4.1.0.1-4 +- put glade catalog into an extra packgae + +* Sun Jun 23 2013 Caolán McNamara - 1:4.1.0.1-3 +- Resolves: rhbz#976304 gallery elements may not insert + +* Wed Jun 19 2013 Dennis Gilmore - 1:4.1.0.1-2 +- fix _smp_mflags macro useage + +* Wed Jun 19 2013 David Tardon - 1:4.1.0.1-1 +- 4.1.0 rc1 +- Related: rhbz#971321 failing tests on ppc and s390 + +* Sun Jun 16 2013 David Tardon - 1:4.1.0.0-9.beta2 +- Resolves: rhbz#971321 failing tests on ppc and s390 +- Resolves: rhbz#974062 incorrect rendering of text in outline blocks in + Impress + +* Fri Jun 07 2013 David Tardon - 1:4.1.0.0-8.beta2 +- Related: rhbz#971795 go back to BR: harfbuzz-devel + +* Fri Jun 07 2013 David Tardon - 1:4.1.0.0-7.beta2 +- Resolves: rhbz#971230 Use BR: harfbuzz-icu-devel + +* Wed Jun 05 2013 David Tardon - 1:4.1.0.0-7.beta1 +- 4.1.0 beta2 + +* Wed Jun 05 2013 Caolán McNamara - 1:4.1.0.0-6.beta1 +- Related: rhbz#968892 discard impossible languages for Oriya script + +* Tue Jun 04 2013 Caolán McNamara - 1:4.1.0.0-5.beta1 +- Resolves: rhbz#968892 block entire grapheme together for glyph fallback +- Related: rhbz#968892 discard impossible languages for glyph fallback + +* Fri May 31 2013 Caolán McNamara - 1:4.1.0.0-4.beta1 +- Resolves: rhbz#968976 fix dropdown list autosizing + +* Thu May 30 2013 David Tardon - 1:4.1.0.0-3.beta1 +- build fix for s390 + +* Fri May 24 2013 David Tardon - 1:4.1.0.0-2.beta1 +- 4.1.0 beta1 + +* Fri May 24 2013 Stephan Bergmann - 1:4.0.3.3-3 +- Resolves: rhbz#961460 can't save WebDAV (davs) files + +* Thu May 16 2013 Caolán McNamara - 1:4.0.3.3-2 +- Resolves: rhbz#963276 font options cache crash + +* Fri May 03 2013 David Tardon - 1:4.0.3.3-1 +- 4.0.3 rc3 + +* Tue Apr 30 2013 David Tardon - 1:4.0.3.2-1 +- 4.0.3 rc2 + +* Mon Apr 22 2013 Stephan Bergmann - 1:4.0.3.1-2 +- Resolves: rhbz#954991 Avoid static data (causing trouble at exit) + +* Thu Apr 18 2013 David Tardon - 1:4.0.3.1-1 +- 4.0.3 rc1 +- Resolves: rhbz#867808 do not throw UNO exceptions by pointer in C++ + +* Tue Apr 16 2013 Caolán McNamara - 1:4.0.2.2-4 +- Resolves: rhbz#927223 syntax highlighting crash + +* Mon Apr 08 2013 Caolán McNamara - 1:4.0.2.2-3 +- Resolves: rhbz#949238 div by zero on pagedown in 0 width panel + +* Fri Apr 05 2013 Kalev Lember - 1:4.0.2.2-2 +- Resolves: rhbz#949106 libreoffice drags in both openjdk 1.7.0 and 1.8.0 + +* Thu Mar 28 2013 David Tardon - 1:4.0.2.2-1 +- 4.0.2 rc2 +- Resolves: rhbz#876742 manipulation with larger tables in impress is + very slow + +* Fri Mar 15 2013 Caolán McNamara - 1:4.0.2.1-2 +- Resolves: rhbz#906137 slide show inverts outputs + +* Fri Mar 15 2013 David Tardon - 1:4.0.2.1-1 +- 4.0.2 rc1 +- Resolves: rhbz#921716 Build Breton language pack + +* Wed Mar 13 2013 Stephan Bergmann - 1:4.0.1.2-4 +- Resolves: rhbz#895690 failure saving to gvfs mounts + +* Tue Mar 12 2013 Caolán McNamara - 1:4.0.1.2-3 +- Resolves: rhbz#920697 presentation not always full-screen + +* Thu Mar 07 2013 Caolán McNamara - 1:4.0.1.2-2 +- Related: rhbz#902884 check for NULL GetSelectedMasterPage +- Resolves: fdo#61241 force area page to size itself +- Resolves: fdo#61656 use order and orientation combobox +- Resolves: fdo#56031 RSID attr changes drop content changes + +* Thu Feb 28 2013 David Tardon - 1:4.0.1.2-1 +- 4.0.1 rc2 + +* Tue Feb 26 2013 Eike Rathke - 1:4.0.0.3-8 +- do not access vector elements beyond size, rhbz#847519 related +- Resolves: rhbz#742780 let make OPT_FLAGS=... override SDK flags +- Resolves: rhbz#907933 crash on removing second last para + +* Tue Feb 19 2013 Caolán McNamara - 1:4.0.0.3-7 +- Resolves: rhbz#895196 sc filter float a11y parent of itself + +* Tue Feb 19 2013 David Tardon - 1:4.0.0.3-6 +- Resolves: rhbz#911896 add Kazakh localization + +* Fri Feb 15 2013 Caolán McNamara - 1:4.0.0.3-5 +- make evolution 3.6 work with address book +- Resolves: rhbz#910176 cannot select directory with gtk folder picker +- fixes for building against Boost 1.53.0 + +* Fri Feb 15 2013 Stephan Bergmann - 1:4.0.0.3-4 +- Resolves: fdo#60491 missing libemboleobj.so +- Resolves: rhbz#908674 crash on start + +* Sat Feb 09 2013 Denis Arnaud - 1:4.0.0.3-3 +- Rebuild for Boost-1.53.0 + +* Wed Feb 06 2013 David Tardon - 1:4.0.0.3-2 +- fix parsing errors in translated help + +* Fri Feb 01 2013 David Tardon - 1:4.0.0.3-1 +- 4.0.0 rc3 + +* Wed Jan 23 2013 David Tardon - 1:4.0.0.2-1 +- 4.0.0 rc2 +- use ucpp again + +* Tue Jan 22 2013 David Tardon - 1:4.0.0.1-3 +- Resolves: rhbz#760765 Impress doesn't copy custom styles from one file + to another + +* Mon Jan 21 2013 David Tardon - 1:4.0.0.1-2 +- Resolves: rhbz#901346 do not install 512x512 icons + +* Tue Jan 15 2013 David Tardon - 1:4.0.0.1-1 +- 4.0.0 rc1 + +* Sat Dec 22 2012 David Tardon - 1:4.0.0.0-4.beta2 +- use system cpp instead of ucpp + +* Wed Dec 19 2012 David Tardon - 1:4.0.0.0-3.beta2 +- 4.0.0 beta2 + +* Thu Dec 06 2012 David Tardon - 1:4.0.0.0-2.beta1 +- 4.0.0 beta1 + +* Thu Nov 29 2012 David Tardon - 1:3.6.4.3-1 +- 3.6.4 rc3 + +* Wed Nov 28 2012 Caolán McNamara - 1:3.6.4.1-2 +- fix docx import on big endian + +* Sun Nov 18 2012 David Tardon - 1:3.6.4.1-1 +- 3.6.4 rc1 + +* Wed Nov 14 2012 Caolán McNamara - 1:3.6.3.2-8 +- Resolves: rhbz#872815 ogltrans effects still suboptimal + +* Tue Nov 13 2012 Caolán McNamara - 1:3.6.3.2-7 +- big endian test failure + +* Thu Nov 08 2012 Caolán McNamara - 1:3.6.3.2-6 +- Resolves: fdo#56198/rhbz#868002 honour gtk-scrollbar-warp-preference + +* Tue Nov 06 2012 Caolán McNamara - 1:3.6.3.2-5 +- bump for libexttextcat + +* Fri Nov 02 2012 David Tardon - 1:3.6.3.2-4 +- Resolves: rhbz#871929 add keywords to desktop files +- fix debuginfo + +* Wed Oct 31 2012 Eike Rathke - 1:3.6.3.2-3 +- Resolves: rhbz#865058 increase number of user-defined format codes + +* Fri Oct 26 2012 David Tardon - 1:3.6.3.2-2 +- Resolves: rhbz#824035 do not bundle saxon + +* Wed Oct 24 2012 David Tardon - 1:3.6.3.2-1 +- 3.6.3 rc2 +- drop integrated 0001-Resolves-rhbz-868479-fdo-56281-doubled-in-German-ok-.patch + +* Mon Oct 22 2012 Caolán McNamara - 1:3.6.3.1-3 +- Resolves: rhbz#868479 guard against duplicated ~ in OK/Cancel + +* Thu Oct 11 2012 David Tardon - 1:3.6.3.1-2 +- Resolves: rhbz#858641 backport gstreamer 1.0 support to F-18 + +* Thu Oct 11 2012 Caolán McNamara - 1:3.6.3.1-1 +- 3.6.3 rc1 +- drop integrated 0001-Resolves-rhbz-855972-crash-on-switching-to-outline-v.patch +- drop integrated 0001-fdo-52022-Simple-LargeControlPoints-actually-can-hav.patch +- drop integrated 0001-fdo-46071-Do-not-hide-windows-based-on-nil-Visible-p.patch + +* Fri Oct 05 2012 Stephan Bergmann - 1:3.6.2.2-3 +- Resolves: fdo#46071 Do not hide windows based on nil Visible property + +* Fri Oct 05 2012 Stephan Bergmann - 1:3.6.2.2-2 +- Resolves: fdo#52022 Part of data in userdir is lost on upgrade + +* Wed Sep 26 2012 David Tardon - 1:3.6.2.2-1 +- 3.6.2 rc2 + +* Wed Sep 12 2012 Caolán McNamara - 1:3.6.2.1-2 +- Resolves: rhbz#855541 XIOError handler multithread woes + +* Wed Sep 12 2012 David Tardon - 1:3.6.2.1-1 +- 3.6.2 rc1 + +* Tue Sep 11 2012 Caolán McNamara - 1:3.6.1.2-4 +- Resolves: rhbz#855507 large ole2 compound files fail to load + +* Mon Sep 10 2012 Caolán McNamara - 1:3.6.1.2-3 +- Resolves: rhbz#855972 crash on switching to outline view + +* Wed Aug 29 2012 Caolán McNamara - 1:3.6.1.2-2 +- Related: rhbz#850709 hunspell en-US available standalone so + make English langpack require hunspell-en and core just + bare bones hunspell-en-US + +* Sun Aug 26 2012 David Tardon - 1:3.6.1.2-1 +- 3.6.1 rc2 + +* Wed Aug 22 2012 Caolán McNamara - 1:3.6.1.1-2 +- Resolves: rhbz#846775 Clipboard must be disposed before selection +- Resolves: rhbz#842292 crash in scrolling multiselection in draw + +* Wed Aug 15 2012 David Tardon - 1:3.6.1.1-1 +- 3.6.1 rc1 + +* Sun Aug 12 2012 Kevin Fenzi - 1:3.6.0.4-3 +- Rebuild for new boost + +* Sat Jul 28 2012 David Tardon - 1:3.6.0.4-2 +- rebuilt for boost 1.50 + +* Fri Jul 27 2012 David Tardon - 1:3.6.0.4-1 +- 3.6.0 rc4 + +* Thu Jul 26 2012 David Tardon - 1:3.6.0.3-2 +- Resolves: rhbz#842552 crash in pptx import + +* Wed Jul 25 2012 David Tardon - 1:3.6.0.3-1 +- 3.6.0 rc3 + +* Tue Jul 17 2012 David Tardon - 1:3.6.0.2-1 +- 3.6.0 rc2 + +* Mon Jul 16 2012 Caolán McNamara - 1:3.6.0.1-3 +- Resolves: rhbz#836937 insanely slow with Zemberek + +* Mon Jul 16 2012 David Tardon - 1:3.6.0.1-2 +- rebuild for new libexttextcat + +* Thu Jul 12 2012 David Tardon - 3.6.0.1-1 +- 3.6.0 rc1 + +* Mon Jul 09 2012 Caolán McNamara - 3.6.0.0-4 +- Resolves: rhbz#838368 --view ignored while -view accepted + +* Thu Jul 05 2012 David Tardon - 3.6.0.0-3 +- 3.6.0 beta3 + +* Mon Jul 2 2012 Marek Kasik - 3.6.0.0-2 +- Rebuild (poppler-0.20.1) + +* Wed Jun 27 2012 David Tardon - 3.6.0.0-1 +- 3.6.0 beta2 +- drop integrated 0001-move-binfilter-mime-types-into-extra-.desktop-file.patch +- drop integrated 0001-Resolves-rhbz-788042-skip-splashscreen-with-quicksta.patch +- drop integrated libreoffice-ensure-non-broken-xml-tree.patch +- drop integrated 0001-preserve-timestamps-for-.py-files.patch +- drop integrated 0001-Resolves-rhbz-788045-swriter-help-etc-doesn-t-show-h.patch +- drop integrated 0001-Resolves-rhbz-799525-put-flat-odf-mimetypes-in-xsltf.patch +- drop integrated 0001-Resolves-rhbz-800272-complain-about-unknown-command-.patch +- drop integrated 0001-Resolves-rhbz-806663-SlideshowImpl-can-outlive-SdMod.patch +- drop integrated 0001-desktop-do-not-complain-about-soffice-command-line-o.patch +- drop integrated 0001-Resolves-fdo-48096-torn-off-popups-trigger-keyboard-.patch +- drop integrated 0001-fdo-38088-better-CSV-import-default-separators.patch +- drop integrated 0001-save-register-arguments-first.patch +- drop integrated 0001-do-not-let-gcc-use-registers-we-are-setting-ourselve.patch +- drop integrated 0001-wrong-types-used-here-breaks-64bit-bigendian.patch +- drop integrated 0001-Resolves-rhbz-805743-a11y-call-doShow-after-we-have-.patch +- drop integrated 0001-Resolves-fdo-49849-implement-Unicode-6.1-hebrew-line.patch +- drop integrated 0001-use-ure-instead-of-ure-link.patch +- drop broken 0001-fix-setting-of-paper-tray-from-print-dialog-fdo-4393.patch + +* Mon Jun 18 2012 Caolán McNamara - 3.5.5.1-2 +- Resolves: rhbz#830810 missing dependency on lucene-contrib + +* Thu Jun 14 2012 David Tardon - 3.5.5.1-1 +- 3.5.5 rc1 +- drop integrated 0001-make-hsqldb-build-with-java-1.7.patch +- drop integrated 0001-Related-rhbz-799628-crash-with-chewing-IM-with-g3g.patch +- drop integrated 0001-silence-SolarMutex-not-locked-spew.patch +- drop integrated 0001-gcc-trunk-fix-unable-to-find-string-literal-operator.patch +- drop integrated 0001-ppc-yyinput-returns-a-int-truncating-to-unsigned-cha.patch +- drop integrated 0001-Resolves-rhbz-826609-rhbz-820554-fix-smoketest-on-pp.patch + +* Mon Jun 11 2012 David Tardon - 3.5.4.2-3 +- make gdb pretty printers for URE libs usable again + +* Fri Jun 08 2012 Caolán McNamara - 3.5.4.2-2 +- Resolves: rhbz#826609, rhbz#820554 fix smoketest on ppc[64] and s390[x] + +* Wed May 23 2012 David Tardon - 3.5.4.2-1 +- 3.5.4 rc2 + +* Thu May 17 2012 Caolán McNamara - 3.5.4.1-2 +- Resolves: rhbz#811226 ARM FTBFS + +* Wed May 16 2012 David Tardon - 3.5.4.1-1 +- 3.5.4 rc1 +- drop integrated 0001-do-not-prepend-n-twice-it-confuses-KFileDialog-rhbz-.patch +- drop integrated 0001-incrementing-index-twice-in-one-run-seems-wrong.patch +- drop integrated 0001-fdo-49365-correctly-map-monitor-index-back-to-screen.patch +- drop integrated 0001-rhbz-809019-count-mirrored-monitors-as-one.patch + +* Sun May 13 2012 Caolán McNamara - 3.5.3.2-5 +- Resolves: fdo#49849 line breaking fixes for Hebrew + +* Fri May 11 2012 David Tardon - 3.5.3.2-4 +- Resolves: rhbz#820439 KDE export dialog broken for most formats +- Resolves: fdo#49365 Libreoffice fails to start on second screen with + gtk vcl plugin +- Resolves: rhbz#809019 Impress thinks a machine with 2 monitors in + clone mode is multihead + +* Wed May 09 2012 Caolán McNamara - 3.5.3.2-3 +- Resolves: rhbz#805743 a11y crash in impress/draw +- Resolves: rhbz#813202 opengl slide transitions still a bit + problematic in Fedora 17 + +* Thu May 03 2012 David Tardon - 3.5.3.2-2 +- rebuild for changed dependencies + +* Wed Apr 25 2012 David Tardon - 3.5.3.2-1 +- 3.5.3 rc2 +- fix broken test on 64bit big endian + +* Mon Apr 23 2012 David Tardon - 3.5.3.1-2 +- rebuild for icu +- fix UNO bridges for ppc and ppc64 + +* Thu Apr 19 2012 David Tardon - 3.5.3.1-1 +- 3.5.3 rc1 +- drop integrated 0001-Introduced-SystemShellExecuteFlags-URIS_ONLY.patch +- drop integrated 0001-Simplify-code-and-use-proper-register-names-for-linu.patch +- drop integrated 0001-resolved-rhbz-813280-the-current-document-is-not-alw.patch + +* Wed Apr 18 2012 Eike Rathke - 3.5.2.1-7 +- Resolves: rhbz#813280 sheets cannot be moved in Calc + +* Wed Apr 11 2012 Eike Rathke - 3.5.2.1-6 +- Resolves: fdo#38088 rhbz#810267 better CSV import default separators + +* Tue Apr 10 2012 Caolán McNamara - 3.5.2.1-5 +- Resolves: rhbz#811226 FTBFS ARM + +* Thu Apr 05 2012 Stephan Bergmann - 3.5.2.1-4 +- Fix URIS_ONLY flag issue +- rebuild for db4 + +* Mon Apr 02 2012 Caolán McNamara - 3.5.2.1-3 +- Resolves: rhbz#708041 focus problems with tearable menus + +* Mon Mar 26 2012 Caolán McNamara - 3.5.2.1-2 +- Resolves: rhbz#806663 SlideshowImpl can outlive SdModule + +* Sun Mar 25 2012 David Tardon - 3.5.2.1-1 +- 3.5.2 rc1 +-drop integrated 0001-yet-another-clash-with-macro-name.patch + +* Wed Mar 14 2012 David Tardon - 3.5.1.2-2 +- Resolves: rhbz#770209 can't change paper tray setting while printing + +* Thu Mar 08 2012 David Tardon - 3.5.1.2-1 +- 3.5.1 rc2 + +* Tue Mar 06 2012 Caolán McNamara - 3.5.1.1-3 +- Resolves: rhbz#799628 crash with chewing IM with g3g +- Resolves: rhbz#799525 put flat odf mimetypes into xsltfilter.desktop +- Resolves: rhbz#800272 complain about unknown commandline options + +* Wed Feb 29 2012 Caolán McNamara - 3.5.1.1-2 +- Resolves: rhbz#788045 swriter --help doesn't show help +- Resolves: rhbz#798667 missing .desktop icons + +* Sun Feb 26 2012 David Tardon - 3.5.1.1-1 +- 3.5.1 rc1 +- drop 0001-Resolves-fdo-43644-survive-registered-but-unavailabl.patch +- drop 0001-Resolves-rhbz-789622-Adapt-SDK-to-changed-paths-in-L.patch +- drop 0001-Fix-fdo-45177-avoid-linked-undo-for-the-while.patch +- drop 0001-Fix-some-apparent-misuses-of-RTL_CONSTASCII_USTRINGP.patch +- drop binfilter-Fix-some-apparent-misuses-of-RTL_CONSTASCII_USTRINGP.patch +- Resolves: fdo#45177 avoid linked undo crash +- Fix some apparent misuses of RTL_CONSTASCII_USTRINGPARAM (cherry-picked from + upstream libreoffice-3-5 branch) + +* Tue Feb 14 2012 Stephan Bergmann - 3.5.0.3-5 +- Resolves rhbz#789622: Adapt SDK to changed paths in LO installation + +* Mon Feb 13 2012 Caolán McNamara - 3.5.0.3-4 +- ensure gdb .py files have the same timstamps so that multilib + .pyc's and .pyo's have the same content (timestamp in binary cache) + +* Sat Feb 11 2012 Caolán McNamara - 3.5.0.3-3 +- make sure .tree files don't get busted again + +* Tue Feb 07 2012 Stephan Bergmann - 3.5.0.3-2 +- junit4 -> junit +- Resolves: rhbz#788042 skip splashscreen with quickstarter +- with split binfilter we need fix for fdo#43644 + +* Thu Feb 02 2012 David Tardon - 3.5.0.3-1 +- 3.5.0 rc3 +- Resolves: rhbz#786328 add nlpsolver subpackage +- split legacy binary filters into subpackage + +* Thu Jan 26 2012 Stephan Bergmann - 3.5.0.2-2 +- add libreoffice-postgresql subpackage + +* Wed Jan 25 2012 David Tardon - 3.5.0.2-1 +- 3.5.0 rc2 + +* Thu Jan 19 2012 David Tardon - 3.5.0.1-1 +- 3.5.0 rc1 +- drop integrated 0001-workaround-internal-compiler-error-with-gcc-4.7.patch +- drop integrated 0001-fix-for-gcc-4.7-C-11-these-are-not-string-literal-op.patch +- drop integrated 0001-fix-for-gcc-4.7-C-11-this-is-not-string-literal-oper.patch +- drop integrated 0001-Revert-fast_merge-fix-mis-merge-of-first-module-s-st.patch +- drop integrated 0001-fix-writing-of-strings-from-the-first-module.patch +- drop integrated 0001-refactor-slightly-to-avoid-link-problems-with-gcc-4..patch + +* Fri Jan 13 2012 David Tardon - 3.4.99.3-1 +- 3.5.0 beta3 +- drop integrated 0001-fix-syntactic-error.patch +- drop integrated 0001-gcc-trunk-fix-error-unable-to-find-string-literal-op.patch +- drop integrated 0001-gcc-trunk-avoid-confusion.patch +- drop integrated 0001-workaround-for-LO-namespace-pollution-breaking-KDE4-.patch +- drop integrated 0001-smath-does-not-handle-accents-in-MathML.patch +- Resolves: rhbz#533318 smath does not handle accents in MathML +- Resolves: rhbz#771108 English menu in writer despite installation of + libreoffice-langpack-de + +* Fri Jan 06 2012 David Tardon - 3.4.99.2-2 +- rebuild with gcc 4.7 + +* Wed Dec 21 2011 David Tardon - 3.4.99.2-1 +- 3.5.0 beta2 +- drop integrated 0001-Resolves-rhbz-761009-IFSD_Equal-is-asymmetrical.patch +- drop integrated 0001-Resolves-rhbz-767708-avoid-SIGBUS-writing-to-overcom.patch +- drop integrated 0001-force-gbuild-stage-for-CustomTargets.patch +- drop integrated 0001-these-translations-do-already-exist-in-translations-.patch +- drop integrated 0001-Fix-typo-and-clean-up.patch +- use system mysql-connector-c++ + +* Sun Dec 18 2011 David Tardon - 3.4.99.1-1 +- 3.5.0 beta1 +- drop integrated 0001-Related-fdo-37195-migrationoo3-not-registered.patch +- drop integrated 0001-Related-i58612-don-t-crash-anyway.patch +- drop integrated 0001-Related-rhbz-652604-better-survive-exceptions-thrown.patch +- drop integrated 0001-Related-rhbz-702833-addEventListener-without-removeE.patch +- drop integrated 0001-Related-rhbz-711087-band-aid.patch +- drop integrated 0001-Related-rhbz-718976-crash-in-SwTxtSizeInfo-GetMultiC.patch +- drop integrated 0001-Related-rhbz-730225-avoid-segv-in-ld-this-was-set-to.patch +- drop integrated 0001-Related-rhbz-753201-fedora-ant-java-1.5.0-gcj-won-t-.patch +- drop integrated 0001-Resolves-fdo-32665-handle-that-FreeSerif-lacks-some-.patch +- drop integrated 0001-Resolves-rhbz-693265-fix-crash-from-unhandled-except.patch +- drop integrated 0001-Resolves-rhbz-695509-crash-in-RefreshDocumentLB.patch +- drop integrated 0001-Resolves-rhbz-713154-pdf-export-dialog-too-tall-to-f.patch +- drop integrated 0001-Resolves-rhbz-715549-use-fontconfig-s-detected-forma.patch +- drop integrated 0001-Resolves-rhbz-738255-avoid-crash-on-NULL-pointer.patch +- drop integrated 0001-Resolves-rhbz-751290-KDE-black-on-dark-tooltips.patch +- drop integrated 0001-add-Oracle-Java-1.7.0-recognition.patch +- drop integrated 0001-avoid-using-com.sun.org-apis.patch +- drop integrated 0001-bubble-down-configure-test-findings-on-visibility.patch +- drop integrated 0001-fix-horizontal-scrollbars-with-KDE-oxygen-style-bnc-.patch +- drop integrated 0001-gtk3-fix-cairo-canvas-crash-for-non-X-or-svp-backend.patch +- drop integrated 0001-helgrind-Related-rhbz-655686-get-order-of-shutdown-c.patch +- drop integrated 0001-rhbz-667082-do-not-crash-importing-section-containin.patch +- drop integrated 0001-rhbz-702635-set-correct-page-number-when-exporting-s.patch +- drop integrated Backport-reading-AES-encrypted-ODF-1.2-documents.patch +- drop integrated gdb-pretty-printers.patch +- drop integrated kde4configure.patch +- drop integrated libreoffice-ppc64.patch +- drop integrated openoffice.org-3.3.0.ooo108637.sfx2.uisavedir.patch +- drop integrated openoffice.org-3.3.0.ooo113273.desktop.resolvelinks.patch +- drop integrated vbahelper.visibility.patch +- drop libreoffice-testtools subpackage, because testtool has been + removed by upstream + +* Thu Dec 15 2011 Caolán McNamara - 3.4.4.2-6 +- Resolves: rhbz#761009 IFSD_Equal is asymmetrical +- Resolves: rhbz#767708 write to mmap'ed file w/o disk space: SIGBUS + +* Tue Nov 29 2011 Caolán McNamara - 3.4.4.2-5 +- Resolves: rhbz#757653 fix headless crash with cairo canvas + +* Tue Nov 22 2011 Lukas Tinkl - 3.4.4.2-4 +- Resolves: rhbz#751290 - [kde] LibreOffice has black on dark-grey tooltip-texts + +* Fri Nov 11 2011 Caolán McNamara - 3.4.4.2-3 +- Related: fdo#42534 0001-Related-i58612-don-t-crash-anyway.patch +- Resolves: fdo#42749 KDE oxygen theme and scrollbars + +* Thu Nov 10 2011 Stephan Bergmann - 3.4.4.2-2 +- Patch to backport reading AES-encrypted ODF 1.2 documents + +* Thu Nov 03 2011 David Tardon - 3.4.4.2-1 +- 3.4.4 rc2 + +* Fri Oct 28 2011 Rex Dieter - 1:3.4.4.1-4 +- rebuild(poppler) + +* Thu Oct 27 2011 Caolán McNamara - 3.4.4.1-3 +- Resolves: rhbz#665800 missing glyph symbol shown when toggling bold/italic + for Sinhala text + +* Thu Oct 27 2011 Caolán McNamara - 3.4.4.1-2 +- possible fix for java 1.7.0 detection + + +* Wed Oct 26 2011 David Tardon - 3.4.4.1-1 +- 3.4.4 rc1 + +* Tue Oct 25 2011 Caolán McNamara - 3.4.3.2-16 +- allow building with gcj + +* Fri Oct 21 2011 Caolán McNamara - 3.4.3.2-15 +- Resolves: rhbz#747356 let Qt call XInitThreads +- fix .sdw import + +* Wed Oct 19 2011 Caolán McNamara - 3.4.3.2-14 +- Related: rhbz#743750 addXineramaScreenUnique issue + +* Fri Oct 07 2011 Stephan Bergmann - 3.4.3.2-13 +- Patches to build with GCC 6.4.1 + +* Fri Sep 30 2011 Marek Kasik - 3.4.3.2-12 +- Rebuild (poppler-0.18.0) + +* Tue Sep 20 2011 Caolán McNamara - 3.4.3.2-11 +- Resolves: rhbz#738133 fix bn discard string +- Resolves: fdo#35513 avoid crash while processing incorrect print range + +* Mon Sep 19 2011 Marek Kasik - 3.4.3.2-10 +- Rebuild (poppler-0.17.3) + +* Thu Sep 15 2011 Caolán McNamara - 3.4.3.2-9 +- Resolves: rhbz#738255 avoid crash on sc inputhdl + +* Tue Sep 13 2011 Caolán McNamara - 3.4.3.2-8 +- Resolves: rhbz#274631 remove NoDisplay from -math.desktop + +* Thu Sep 08 2011 David Tardon - 3.4.3.2-7 +- rebuild for new icu + +* Tue Sep 06 2011 David Tardon - 3.4.3.2-6 +- Resolves: rhbz#734976 libreoffice-langpack-*-* not pulled in by + yum install libreoffice + +* Fri Sep 02 2011 Caolán McNamara - 3.4.3.2-5 +- Resolves: rhbz#735182 be able to rebuild against poppler 0.17.3 + +* Tue Aug 30 2011 David Tardon - 3.4.3.2-4 +- Resolves: rhbz#734432 openoffice.org symlink broken + +* Mon Aug 29 2011 David Tardon - 3.4.3.2-3 +- add Latvian langpack + +* Fri Aug 26 2011 Caolán McNamara - 3.4.3.2-2 +- Resolves: rhbz#733564 graphite2 now packaged into fedora +- Related: fdo#37195 migrationoo3 not registered + +* Thu Aug 25 2011 David Tardon - 3.4.3.2-1 +- 3.4.3 rc2 + +* Mon Aug 22 2011 David Tardon - 3.4.3.1-2 +- add gdb pretty printers + +* Tue Aug 16 2011 David Tardon - 3.4.3.1-1 +- 3.4.3 rc1 +- drop integrated 0001-Resolves-rhbz-725144-wrong-csh-syntax.patch + +* Fri Aug 12 2011 Caolán McNamara - 3.4.2.3-3 +- Related: rhbz#730225 avoid segv in ld + +* Tue Aug 02 2011 Caolán McNamara - 3.4.2.3-2 +- Resolves: rhbz#693265 fix crash from unhandled exception + +* Fri Jul 29 2011 David Tardon - 3.4.2.3-1 +- 3.4.2 rc3 + +* Mon Jul 25 2011 Caolán McNamara - 3.4.2.2-2 +- Resolves: rhbz#725144 wrong csh syntax + +* Wed Jul 20 2011 David Tardon - 3.4.2.2-1 +- 3.4.2 rc2 +- fix breakage in KDE4 plugin + +* Tue Jul 19 2011 Caolán McNamara - 3.4.2.1-3 +- Resolves: rhbz#715549 use fontconfig's detected format + +* Mon Jul 18 2011 Caolán McNamara - 3.4.2.1-2 +- Rebuild (poppler-0.17.0), add libreoffice-poppler-0.17.0.patch + seeing as the API changed for some reason or other + +* Wed Jul 13 2011 David Tardon - 3.4.2.1-1 +- 3.4.2 rc1 +- drop 0001-bad-merge-fix-to-enable-extensions-to-build-again.patch +- drop 0001-fix-regression-in-SvGlobalName-operator.patch + +* Tue Jul 12 2011 Caolán McNamara - 3.4.1.3-3 +- fix regression in SvGlobalName operator + +* Tue Jul 05 2011 Caolán McNamara - 3.4.1.3-2 +- Related: rhbz#718976 crash in SwTxtSizeInfo::GetMultiCreator + +* Fri Jul 01 2011 David Tardon - 3.4.1.3-1 +- 3.4.1 rc3 + +* Thu Jun 23 2011 Caolán McNamara - 3.4.1.2-1 +- 3.4.1 rc2 +- drop integrated 0001-correctly-build-GTK-systray-icon.patch + +* Tue Jun 21 2011 David Tardon - 3.4.1.1-5 +- Resolves: rhbz#714781 add Persian langpack +- Resolves: rhbz#667082 do not crash importing section containing just + an empty paragraph + +* Mon Jun 20 2011 Caolán McNamara - 3.4.1.1-4 +- Related: rhbz#711087 band aid for crash in sc undo +- Resolves: rhbz#714338 add a metapackage to install standard bits + +* Fri Jun 17 2011 Caolán McNamara - 3.4.1.1-3 +- Related: rhbz#702833 addEventListener without removeEventListener + +* Thu Jun 16 2011 Caolán McNamara - 3.4.1.1-2 +- Resolves: rhbz#713154 pdf export dialog too tall to fit + +* Wed Jun 15 2011 David Tardon - 3.4.1.1-1 +- 3.4.1 RC1 +- drop integrated 0001-Resolves-rhbz-707317-avoid-crash-in-getRowSpan.patch +- drop integrated 0001-Resolves-rhbz-710004-band-aid-for-immediate-crash-in.patch +- drop integrated 0001-Resolves-rhbz-710556-don-t-crash-on-missing-graphics.patch +- drop integrated 0001-Resolves-rhbz-699909-crash-in-export-of-.doc-in-lcl_.patch +- drop integrated 0001-fdo-37584-Make-a-real-copy-of-the-text-where-to-coun.patch +- drop integrated 0001-Resolves-fdo-37668-bitwise-operations-on-signed-numb.patch + +* Thu Jun 09 2011 Caolán McNamara - 3.4.0.2-5 +- Resolves: rhbz#699909 crash in export of .doc in lcl_getField +- Resolves: fdo#37584 Make a real copy of the text +- Resolves: rhbz#709503/fdo#37668 bitwise operations on signed values + +* Tue Jun 07 2011 Caolán McNamara - 3.4.0.2-4 +- Resolves: rhbz#710556 't crash on missing graphics .pptx export +- Resolves: rhbz#652604 better survive exceptions in autorecovery + +* Thu Jun 02 2011 Caolán McNamara - 3.4.0.2-3 +- Resolves: rhbz#710004 band aid for crash + +* Mon May 30 2011 Caolán McNamara - 3.4.0.2-2 +- Resolves: rhbz#707317 avoid crash in getRowSpan + +* Fri May 27 2011 David Tardon - 3.4.0.2-1 +- 3.4.0 RC2 +- drop integrated 0001-fix-build-with-system-bsh.patch + +* Wed May 25 2011 Caolán McNamara - 3.4.0.1-3 +- rebuild for new hunspell + +* Tue May 24 2011 David Tardon - 3.4.0.1-2 +- Resolves: rhbz#706110 oosplash.bin segfault on every login + +* Fri May 20 2011 David Tardon - 3.4.0.1-1 +- 3.4 RC1 +- Resolves: rhbz#702635 set correct page number when exporting selected + pages + +* Sat May 07 2011 Christopher Aillon - 3.3.99.4-2 +- Update icon cache scriptlet + +* Sat May 07 2011 David Tardon 3.3.99.4-1 +- 3.4 beta4 +- drop integrated 0001-Removed-duplicate-code-block-mis-merge-prolly.patch +- drop integrated 7de0b88ce2dd932915894385b54be1897d5ee053.zip + +* Mon Apr 18 2011 Caolán McNamara 3.3.99.1-2 +- Resolves: rhbz#695509 crash in RefreshDocumentLB +- bubble down configure test findings on visibility + +* Mon Apr 11 2011 Caolán McNamara 3.3.99.1-1 +- 3.4 beta1 +- drop openoffice.org-1.9.123.ooo53397.prelinkoptimize.desktop.patch + in favour of ooosplash +- drop openoffice.org-2.2.0.gccXXXXX.solenv.javaregistration.patch + because components are passively registered now +- drop integrated openoffice.org-3.1.0.ooo102061.sc.cellanchoring.patch +- drop integrated turn-script-providers-into-extensions.patch +- drop integrated 0001-tidy-this-up-and-don-t-bail-out-on-mislength-records.patch +- drop integrated 0001-free-ctxt-after-taking-lastError-details.patch +- drop integrated 0001-Removed-suspect-hack.-Cursor-on-post-it-now-scrolls-.patch +- drop integrated libreoffice-gcc4.6.0.patch +- drop integrated 0001-fexceptions-fexceptions.patch +- drop integrated 0001-Related-rhbz-672872-cancel-gtk-file-dialog-on-deskto.patch +- drop vbahelper.visibility.patch +- drop integrated 0001-Resolves-fdo-33509-i62414-out-by-one-breaks-CTL-spel.patch +- drop integrated 0001-Resolves-rhbz-670020-crash-in-slidesorting.patch +- drop integrated 0001-Resolves-rhbz-676539-handle-missing-pWindows-from-xW.patch +- drop integrated 0001-Resolves-fdo-33750-i94623-use-optimal-border-width-w.patch +- drop integrated 0001-rhbz-649310-don-t-crash-deregistering-diff.-platform.patch +- drop integrated 0001-Resolves-rhbz-674330-dereference-of-NULL-mpBase.patch +- drop integrated 0001-rhbz-678284-Get-correct-current-position-when-shift-page-up-and-.patch +- drop integrated 0001-Resolves-rhbz-681159-bandaid-for-crash.patch +- drop integrated 0001-Resolves-rhbz-672818-bandaid-for-crash-in-SwTxtNode-.patch +- drop integrated 0001-install-high-resolution-icons.patch +- drop integrated 0001-Resolves-rhbz-682716-pa-IN-isn-t-handled-by-fontconf.patch +- drop integrated 0001-Related-rhbz-684477-make-sure-this-is-thread-safe.patch +- drop integrated 0001-Resolves-rhbz-682621-better-resizing-of-overtall-gly.patch +- drop integrated 0001-Resolves-rhbz-684620-crash-with-NULL-pTableBox.patch +- drop integrated libreoffice-fdo33947.sd.print.crash.patch +- drop integrated 0001-add-cairo_ft_font_face_create_for_pattern-wrapper.patch +- drop integrated 0001-Related-rhbz-680460-reorganize-this-to-make-it-inher.patch +- drop integrated 0001-Related-rhbz-680460-don-t-bother-with-an-interim-Fon.patch +- drop integrated 0001-Resolves-rhbz-680460-honour-lcdfilter-subpixeling-et.patch +- drop integrated 0001-Cut-Gordian-Knot-of-who-owns-the-font-options.patch +- drop integrated 0001-beware-of-invalidated-iterator.patch +- drop integrated rhbz680766.fix-mdds-crash.patch +- drop integrated 0001-Resolves-rhbz-684580-X-and-strike-through-escapes-ra.patch +- drop integrated 0001-set-mime-types-on-flat-xml-filters.patch +- drop integrated 0001-add-flat-xml-types-to-.desktop-files-etc.patch +- drop integrated libreoffice-fdo31271.icu.patch + +* Tue Apr 05 2011 Caolán McNamara 3.3.2.2-6 +- Resolves: rhbz#655686 get order of shutdown correct + +* Wed Mar 30 2011 Caolán McNamara 3.3.2.2-5 +- Add application/vnd.oasis.opendocument.text-flat-xml, etc. to + .desktop files for mcepl + +* Tue Mar 29 2011 Caolán McNamara 3.3.2.2-4 +- Resolves: rhbz#684580 improve X and / strike-through + +* Thu Mar 24 2011 David Tardon 3.3.2.2-3 +- Resolves: rhbz#680766 crash in mdds + +* Wed Mar 23 2011 David Tardon 3.3.2.2-2 +- Related: rhbz#689268 versioned deps need to contain epoch + +* Tue Mar 22 2011 Caolán McNamara 3.3.2.2-1 +- latest version +- drop integrated 0001-Resolves-fdo-33701-ensure-node-outlives-path.patch +- drop integrated 0001-valgrind-don-t-leave-an-evil-thread-running-after-ma.patch + +* Tue Mar 22 2011 Caolán McNamara 3.3.1.2-12 +- Fix fontoptions cache +- avoid crash in calc on changing size of rows (dtardon) + +* Mon Mar 21 2011 Caolán McNamara 3.3.1.2-11 +- Resolves: rhbz#689268 autocorrs from OOo F14 not upgraded + +* Wed Mar 16 2011 Caolán McNamara 3.3.1.2-10 +- Resolves: rhbz#680460 honour lcdfilter and subpixeling + +* Tue Mar 15 2011 Caolán McNamara 3.3.1.2-9 +- Resolves: fdo#33947 sd print crash + +* Mon Mar 14 2011 Caolán McNamara 3.3.1.2-8 +- Related: rhbz#684477 make sure this is thread safe +- Resolves: rhbz#684620 crash with NULL pTableBox + +* Sun Mar 13 2011 Marek Kasik 3.3.1.2-7 +- Rebuild (poppler-0.16.3) + +* Wed Mar 09 2011 Caolán McNamara 3.3.1.2-6 +- Resolves: rhbz#682621 better resizing of overtall glyphsubs + +* Tue Mar 08 2011 Caolán McNamara 3.3.1.2-5 +- Resolves: rhbz#682716 pa-IN isn't handled well by fontconfig + +* Tue Mar 08 2011 David Tardon 3.3.1.2-4 +- install 128x128 px icons + +* Wed Mar 02 2011 Caolán McNamara 3.3.1.2-3 +- Resolves: rhbz#681159 crash in writer +- Resolves: rhbz#672818 crash in writer +- Resolves: fdo#33701 ensure node outlives path +- Resolves: rhbz#681738 crash on writing config post-main + +* Thu Feb 17 2011 Caolán McNamara 3.3.1.2-2 +- Resolves: rhbz#678284 Calc crashes during cell select with keys + (dtardon) + +* Thu Feb 17 2011 Caolán McNamara 3.3.1.2-1 +- RC2 + +* Wed Feb 16 2011 Caolán McNamara 3.3.1.1-2 +- Resolves: rhbz#674330 dereference of NULL mpBase + +* Fri Feb 11 2011 Caolán McNamara 3.3.1.1-1 +- 3.3.1 rc1 +- drop integrated 0001-don-t-pushback-and-process-a-corrupt-extension.patch +- drop integrated libreoffice-fdo32561.comphelper.patch +- drop integrated 0001-Related-rhbz-610103-more-woes-on-rpm-upgrade-vs-rpm-.patch +- drop integrated 0001-Resolves-rhbz-673819-crash-on-changing-position-of-d.patch +- drop integrated 0001-rhbz-666440-don-t-pushback-and-process-a-corrupt-extension.patch + +* Thu Feb 10 2011 Caolán McNamara 3.3.0.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild +- Related: rhbz#610103 make this even more robust +- Related: rhbz#672872 cancel gtk file dialog on terminate +- Resolves: fdo#33509/ooo#62414 fix CTL spelling popup +- Resolves: rhbz#673819 crash on changing position of header/footer object +- Resolves: rhbz#670020 crash in slidesorting +- Resolves: rhbz#676539 handle missing pWindows from xWindows +- Resolves: rhbz#649310 don't crash deregistering diff. platform ext. + (dtardon) +- Resolves: rhbz#666440 don't pushback and process a corrupt extension + +* Mon Jan 24 2011 Caolán McNamara 3.3.0.4-2 +- Resolves: rhbz#671540 fix lonely ) + +* Thu Jan 20 2011 Caolán McNamara 3.3.0.4-1 +- next release candidate +- drop integrated 0001-fix-presenter-screens-description.xml-build.patch + +* Tue Jan 18 2011 Caolán McNamara 3.3.0.3-2 +- backport fix to get presenter screen working +- make handling busted extensions more robust + +* Wed Jan 12 2011 Caolán McNamara 3.3.0.3-1 +- latest version +- drop integrated 0001-Resoves-rhbz-663857-font-color-missing-C-FAQ-10.3-do.patch +- drop integrated 0001-Avoid-double-paste-when-pasting-text-into-cell-comme.patch +- drop integrated 0001-Resolves-rhbz-660342-Undo-Redo-crash-with-postits.patch +- drop integrated 0001-Resolves-rhbz-666088-clean-up-search-cache-singleton.patch + +* Thu Jan 06 2011 Caolán McNamara 3.3.0.2-5 +- Resolves: rhbz#666088 don't crash on clean up of search cache + +* Wed Jan 05 2011 Lukas Tinkl 3.3.0.2-4 +- create a KDE integration subpackage + +* Mon Jan 03 2011 David Tardon 3.3.0.2-3 +- rebuild with new poppler + +* Wed Dec 22 2010 Caolán McNamara 3.3.0.2-2 +- Resolves: rhbz#663724 fdo32572-sc-dont-double-paste.patch +- Resolves: rhbz#660342 Undo/Redo crash with postits + +* Tue Dec 21 2010 Caolán McNamara 3.3.0.2-1 +- latest version + +* Sat Dec 18 2010 Caolán McNamara 3.3.0.1-4 +- Resolves: rhbz#663857 font color missing in transitions + +* Wed Dec 15 2010 Rex Dieter - 3.3.0.1-3 +- rebuild (poppler) + +* Wed Dec 15 2010 Caolán McNamara 3.3.0.1-2 +- Fix up some doc imports + +* Sun Dec 05 2010 Caolán McNamara 3.3.0.1-1 +- release candidate 1 +- drop integrated qstart.dont-forceenabled-on-post-reg-restart.patch +- drop integrated exit.quickstarter.when.deleted.patch +- drop integrated 0001-destroydesktop.in.timeout.patch +- drop integrated openoffice.org-3.3.0.rhbz657541.join-paragraphs.patch + +* Sat Nov 27 2010 Caolán McNamara 3.2.99.3-2 +- Resolves: rhbz#610103 exit quickstarter when libs deleted +- Resolves: rhbz#652695 release desktop in timeout +- Resolves: rhbz#657541 don't crash during processing of auto. styles + when joining paragraphs (dtardon) + +* Thu Nov 18 2010 Caolán McNamara 3.2.99.2-5 +- Resolves: rhbz#649210 add Sinhalese langpack + +* Sat Oct 30 2010 Caolán McNamara 3.2.99.2-4 +- langpack macro hard-coded version number + +* Fri Oct 22 2010 Caolán McNamara 3.2.99.2-3 +- Resolves: xdg632229 gnomeshell app tracking + +* Tue Oct 12 2010 David Tardon 3.2.99.2-2 +- use macros to define auto-correction and language pack subpackages + +* Mon Oct 11 2010 Caolán McNamara 3.2.99.2-1 +- next LibreOffice milestone +- drop integrated openoffice.org-2.3.0.ooo76649.httpencoding.patch +- drop integrated workspace.dtardon03.patch +- drop integrated openoffice.org-3.1.0.ooo61927.sw.ww6.unicodefontencoding.patch +- drop integrated workspace.impress195.patch +- drop integrated workspace.srb1.patch +- drop integrated openoffice.org-3.2.0.ooo106502.svx.fixspelltimer.patch +- drop integrated openoffice.org-3.3.0.ooo108246.svx.hide-sql-group-when-inactive.patch +- drop integrated openoffice.org-3.2.0.ooo95369.sw.sortedobjs.patch +- drop integrated openoffice.org-3.2.0.ooo110142.svx.safercolornames.patch +- drop integrated openoffice.org-3.3.0.ooo111758.sd.xerror.patch +- drop integrated openoffice.org-3.2.0.ooo111741.extras.malformed-xml-file.patch +- drop integrated openoffice.org-3.3.0.ooo112059.sw.avoid-null-ptr-deref.patch +- drop integrated openoffice.org-3.3.0.ooo100686.wizards.types.not.mediatypes.patch +- drop integrated workspace.vcl113.patch +- drop integrated openoffice.org-3.3.0.ooo112384.sw.export.doc.styledoesntexist.patch +- drop integrated workspace.cmcfixes77.patch +- drop integrated workspace.vcl114.patch +- drop integrated openoffice.org-3.3.0.ooo106591.sal.tradcopy.patch +- drop integrated workspace.vcl115.patch +- drop integrated workspace.cmcfixes78.patch +- drop integrated openoffice.org-3.3.0.ooo114012.sd.bada11ychain.patch +- drop integrated workspace.cmcfixes79.patch +- drop integrated openoffice.org-3.3.0.ooo114703.vcl.betterlocalize.font.patch +- drop integrated openoffice.org-3.3.0.rh638185.editeng.cjkctlhtmlsizes.patch +- drop integrated openoffice.org-3.3.0.rh637738.libgcrypt.addmutex.patch +- drop integrated openoffice.org-3.2.0.rh632236.writerfilter.cleanup-cell-props.patch +- drop workspace.gtk3.patch + +* Wed Oct 06 2010 Caolán McNamara 3.2.99.1-2 +- Related: rhbz#639945 pull in review changes + + redland build-fix + + replace awk script + + validate .destop files + +* Wed Sep 29 2010 Caolán McNamara 3.2.99.1-1 +- initial import of the leviathan