[Libreoffice-commits] core.git: Branch 'private/tml/splitgroup' - 67 commits - avmedia/source bridges/source canvas/source configure.ac connectivity/source dictionaries editeng/source external/boost external/hunspell external/libebook external/libmspub external/liborcus external/libpagemaker external/librevenge filter/qa filter/source fpicker/source framework/source icon-themes/sifr include/clew include/oox include/opencl include/svl include/svx include/vcl oox/source opencl/source sc/inc sc/source sc/uiconfig sd/qa sd/source sfx2/uiconfig slideshow/source solenv/gbuild svl/source svtools/source svx/inc svx/source sw/inc sw/qa sw/source vcl/inc vcl/opengl vcl/qa vcl/source vcl/unx vcl/win vcl/workben
Tor Lillqvist
tml at collabora.com
Tue Sep 15 05:35:37 PDT 2015
Rebased ref, commits from common ancestor:
commit 3671c5124dc9de37be3cf4c65afde5f9d3bb8406
Author: Tor Lillqvist <tml at collabora.com>
Date: Tue Sep 15 13:27:18 2015 +0300
Use heuristic to find out whether to split formula groups for OpenCL
It is necessary to not perform too large OpenCL computations on some
low-end devices on Windows as the driver will be unresponsive too
long. On these devices, the CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT is
4, while for more performant devices it is 1 or 8.
diff --git a/include/clew/clew.h b/include/clew/clew.h
index 94b6c29..e5cfaf0 100644
--- a/include/clew/clew.h
+++ b/include/clew/clew.h
@@ -416,6 +416,7 @@ typedef struct _cl_image_format {
// cl_device_info
#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002
+#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A
#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C
#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F
#define CL_DEVICE_NAME 0x102B
diff --git a/include/opencl/openclwrapper.hxx b/include/opencl/openclwrapper.hxx
index 75ecbc8..e3f967e 100644
--- a/include/opencl/openclwrapper.hxx
+++ b/include/opencl/openclwrapper.hxx
@@ -52,6 +52,7 @@ struct GPUEnv
int mnCmdQueuePos;
bool mnKhrFp64Flag;
bool mnAmdFp64Flag;
+ cl_uint mnPreferredVectorWidthFloat;
};
extern OPENCL_DLLPUBLIC GPUEnv gpuEnv;
diff --git a/opencl/source/openclwrapper.cxx b/opencl/source/openclwrapper.cxx
index 5574d2c..9d03a27 100644
--- a/opencl/source/openclwrapper.cxx
+++ b/opencl/source/openclwrapper.cxx
@@ -501,6 +501,11 @@ bool initOpenCLRunEnv( GPUEnv *gpuInfo )
gpuInfo->mnKhrFp64Flag = bKhrFp64;
gpuInfo->mnAmdFp64Flag = bAmdFp64;
+ gpuInfo->mnPreferredVectorWidthFloat = 0;
+
+ clGetDeviceInfo(gpuInfo->mpArryDevsID[0], CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(cl_uint),
+ &gpuInfo->mnPreferredVectorWidthFloat, NULL);
+
return false;
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 774aed3..7f8180f 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -55,6 +55,7 @@
#include "types.hxx"
#include "scopetools.hxx"
#include "refupdatecontext.hxx"
+#include <opencl/openclwrapper.hxx>
#include <tokenstringcontext.hxx>
#include <refhint.hxx>
#include <listenerquery.hxx>
@@ -3838,10 +3839,21 @@ bool ScFormulaCell::InterpretFormulaGroup()
// Should obviously be based on some heuristics based on the kind
// of OpenCL device or some of its properties.
- const int MAXGROUPLENGTH = (std::getenv("MAXGROUPLENGTH") ? std::atoi(std::getenv("MAXGROUPLENGTH")) : 1000);
+ int nMaxGroupLength = INT_MAX;
+
+#ifdef WNT
+ // Heuristic: Certain old low-end OpenCL implementations don't
+ // work for us with too large group lengths. 1000 was determined
+ // empirically to be a good compromise.
+ if (opencl::gpuEnv.mnPreferredVectorWidthFloat == 4)
+ nMaxGroupLength = 1000;
+#endif
+
+ if (std::getenv("SC_MAX_GROUP_LENGTH"))
+ nMaxGroupLength = std::atoi(std::getenv("SC_MAX_GROUP_LENGTH"));
int nNumOnePlus;
- const int nNumParts = splitup(GetSharedLength(), MAXGROUPLENGTH, nNumOnePlus);
+ const int nNumParts = splitup(GetSharedLength(), nMaxGroupLength, nNumOnePlus);
int nOffset = 0;
int nCurChunkSize;
@@ -3856,7 +3868,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
xGroup = mxGroup;
else
{
- // Possibly incorrect hack
+ // Ugly hack
xGroup = new ScFormulaCellGroup();
xGroup->mpTopCell = mxGroup->mpTopCell;
xGroup->mpTopCell->aPos = aOrigPos;
commit 6c27bc9b90deff8b110f6add51c9cd230d32e8bf
Author: Tor Lillqvist <tml at collabora.com>
Date: Thu Sep 10 21:58:28 2015 +0300
Replace with real commit message if/when going into public branch
Change-Id: Iec1416441e0323724c9b64589310faa61a7da5f0
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index eb2b374..774aed3 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -20,6 +20,7 @@
#include <sal/config.h>
#include <cassert>
+#include <cstdlib>
#include "formulacell.hxx"
#include "grouptokenconverter.hxx"
@@ -3770,6 +3771,36 @@ ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& r
return bInvariant ? EqualInvariant : EqualRelativeRef;
}
+namespace {
+
+// Split N into optimally equal-sized pieces, each not larger than K.
+// Return value P is number of pieces. A returns the number of pieces
+// one larger than N/P, 0..P-1.
+
+int splitup(int N, int K, int& A)
+{
+ assert(N > 0);
+ assert(K > 0);
+
+ A = 0;
+
+ if (N <= K)
+ return 1;
+
+ const int ideal_num_parts = N / K;
+ if (ideal_num_parts * K == N)
+ return ideal_num_parts;
+
+ const int num_parts = ideal_num_parts + 1;
+ const int nominal_part_size = N / num_parts;
+
+ A = N - num_parts * nominal_part_size;
+
+ return num_parts;
+}
+
+} // anonymous namespace
+
bool ScFormulaCell::InterpretFormulaGroup()
{
if (!officecfg::Office::Common::Misc::UseOpenCL::get())
@@ -3805,30 +3836,84 @@ bool ScFormulaCell::InterpretFormulaGroup()
if (mxGroup->mbInvariant && false)
return InterpretInvariantFormulaGroup();
- ScTokenArray aCode;
- ScAddress aTopPos = aPos;
- aTopPos.SetRow(mxGroup->mpTopCell->aPos.Row());
- ScGroupTokenConverter aConverter(aCode, *pDocument, *this, mxGroup->mpTopCell->aPos);
- std::vector<ScTokenArray*> aLoopControl;
- if (!aConverter.convert(*pCode, aLoopControl))
- {
- SAL_INFO("sc.opencl", "conversion of group " << this << " failed, disabling");
- mxGroup->meCalcState = sc::GroupCalcDisabled;
- return false;
- }
+ // Should obviously be based on some heuristics based on the kind
+ // of OpenCL device or some of its properties.
+ const int MAXGROUPLENGTH = (std::getenv("MAXGROUPLENGTH") ? std::atoi(std::getenv("MAXGROUPLENGTH")) : 1000);
- // The converted code does not have RPN tokens yet. The interpreter will
- // generate them.
- mxGroup->meCalcState = sc::GroupCalcRunning;
- sc::FormulaGroupInterpreter *pInterpreter = sc::FormulaGroupInterpreter::getStatic();
- if (pInterpreter == NULL ||
- !pInterpreter->interpret(*pDocument, mxGroup->mpTopCell->aPos, mxGroup, aCode))
+ int nNumOnePlus;
+ const int nNumParts = splitup(GetSharedLength(), MAXGROUPLENGTH, nNumOnePlus);
+
+ int nOffset = 0;
+ int nCurChunkSize;
+ ScAddress aOrigPos = mxGroup->mpTopCell->aPos;
+ for (int i = 0; i < nNumParts; i++, nOffset += nCurChunkSize)
{
- SAL_INFO("sc.opencl", "interpreting group " << mxGroup << " (state " << (int) mxGroup->meCalcState << ") failed, disabling");
- mxGroup->meCalcState = sc::GroupCalcDisabled;
- return false;
+ nCurChunkSize = GetSharedLength()/nNumParts + (i < nNumOnePlus ? 1 : 0);
+
+ ScFormulaCellGroupRef xGroup;
+
+ if (nNumParts == 1)
+ xGroup = mxGroup;
+ else
+ {
+ // Possibly incorrect hack
+ xGroup = new ScFormulaCellGroup();
+ xGroup->mpTopCell = mxGroup->mpTopCell;
+ xGroup->mpTopCell->aPos = aOrigPos;
+ xGroup->mpTopCell->aPos.IncRow(nOffset);
+ xGroup->mbInvariant = mxGroup->mbInvariant;
+ xGroup->mnLength = nCurChunkSize;
+ xGroup->mpCode = mxGroup->mpCode;
+ }
+
+ ScTokenArray aCode;
+ ScGroupTokenConverter aConverter(aCode, *pDocument, *this, xGroup->mpTopCell->aPos);
+ std::vector<ScTokenArray*> aLoopControl;
+ if (!aConverter.convert(*pCode, aLoopControl))
+ {
+ SAL_INFO("sc.opencl", "conversion of group " << this << " failed, disabling");
+ mxGroup->meCalcState = sc::GroupCalcDisabled;
+
+ // Undo the hack above
+ if (nNumParts > 1)
+ {
+ mxGroup->mpTopCell->aPos = aOrigPos;
+ xGroup->mpTopCell = NULL;
+ xGroup->mpCode = NULL;
+ }
+
+ return false;
+ }
+
+ // The converted code does not have RPN tokens yet. The interpreter will
+ // generate them.
+ xGroup->meCalcState = mxGroup->meCalcState = sc::GroupCalcRunning;
+ sc::FormulaGroupInterpreter *pInterpreter = sc::FormulaGroupInterpreter::getStatic();
+ if (pInterpreter == NULL ||
+ !pInterpreter->interpret(*pDocument, xGroup->mpTopCell->aPos, xGroup, aCode))
+ {
+ SAL_INFO("sc.opencl", "interpreting group " << mxGroup << " (state " << (int) mxGroup->meCalcState << ") failed, disabling");
+ mxGroup->meCalcState = sc::GroupCalcDisabled;
+
+ // Undo the hack above
+ if (nNumParts > 1)
+ {
+ mxGroup->mpTopCell->aPos = aOrigPos;
+ xGroup->mpTopCell = NULL;
+ xGroup->mpCode = NULL;
+ }
+
+ return false;
+ }
+ if (nNumParts > 1)
+ {
+ xGroup->mpTopCell = NULL;
+ xGroup->mpCode = NULL;
+ }
}
+ if (nNumParts > 1)
+ mxGroup->mpTopCell->aPos = aOrigPos;
mxGroup->meCalcState = sc::GroupCalcEnabled;
return true;
}
commit 788fb4a0152d64c431c0c6062045a742ef80f40b
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date: Tue Sep 15 11:47:20 2015 +0200
tdf#94198 Printer missing from tooltip
Need to update the tooltip also on state change.
This partially reverts the fix for tdf#83558, 1fb8724f9834dbc07b741eeed31b31347bc0c2a1
Verified that the fix for tdf#83558 still works.
Change-Id: I023a5e4b101dc91522f19b0d3ed2ed0c4a47e64b
Reviewed-on: https://gerrit.libreoffice.org/18586
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>
diff --git a/framework/source/uielement/generictoolbarcontroller.cxx b/framework/source/uielement/generictoolbarcontroller.cxx
index 8b37282..183da37 100644
--- a/framework/source/uielement/generictoolbarcontroller.cxx
+++ b/framework/source/uielement/generictoolbarcontroller.cxx
@@ -244,6 +244,7 @@ throw ( RuntimeException, std::exception )
aStrValue = aTmp;
}
m_pToolbar->SetItemText( m_nID, aStrValue );
+ m_pToolbar->SetQuickHelpText( m_nID, aStrValue );
}
if ( m_bMadeInvisible )
commit eea951d8de4ababb6e81d28221501e7bc3060b57
Author: Tomáš Chvátal <tchvatal at suse.com>
Date: Tue Sep 15 11:43:45 2015 +0200
KDE4Filedialog check should include cstdlib
Otherwise this would needlessly fail on some compilers.
Change-Id: I4e46e9e452de0703b6556cd55e4606b02be5c41c
Reviewed-on: https://gerrit.libreoffice.org/18584
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Michael Stahl <mstahl at redhat.com>
diff --git a/configure.ac b/configure.ac
index c6f7b8d..afd48d64 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11318,6 +11318,7 @@ int main(int argc, char **argv) {
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#define SAL_OVERRIDE
+#include <cstdlib>
#include "tst_exclude_socket_notifiers.moc"
int main(int argc, char *argv[])
@@ -11351,6 +11352,7 @@ int main(int argc, char *argv[])
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#define SAL_OVERRIDE
+#include <cstdlib>
#include "tst_exclude_posted_events.moc"
int main(int argc, char *argv[])
commit 93e82fa537362eb5a10b46035772c3a016fba53a
Author: Caolán McNamara <caolanm at redhat.com>
Date: Fri Sep 11 13:46:39 2015 +0100
Resolves: rhbz#1261421 crash on mashing hangul korean keyboard
Change-Id: Ie066c7f83ad15bec198f2091a3b084468c502766
(cherry picked from commit 064fd8342111bc62ba646e439c235bd495587a4a)
Reviewed-on: https://gerrit.libreoffice.org/18499
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>
diff --git a/external/hunspell/UnpackedTarball_hunspell.mk b/external/hunspell/UnpackedTarball_hunspell.mk
index ecf7856..6ad31dd 100644
--- a/external/hunspell/UnpackedTarball_hunspell.mk
+++ b/external/hunspell/UnpackedTarball_hunspell.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,hunspell,\
external/hunspell/hunspell-fdo48017-wfopen.patch \
external/hunspell/hunspell-morph-overflow.patch \
external/hunspell/ubsan.patch.0 \
+ external/hunspell/hunspell-1.3.3-rhbz1261421.patch \
))
ifeq ($(COM),MSC)
diff --git a/external/hunspell/hunspell-1.3.3-rhbz1261421.patch b/external/hunspell/hunspell-1.3.3-rhbz1261421.patch
new file mode 100644
index 0000000..4354dd0
--- /dev/null
+++ b/external/hunspell/hunspell-1.3.3-rhbz1261421.patch
@@ -0,0 +1,191 @@
+From 97e079a23d459aeb6e64435350d7710c90dbca85 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm at redhat.com>
+Date: Fri, 11 Sep 2015 13:28:52 +0100
+Subject: [PATCH] Resolves: rhbz#1261421 crash on mashing hangul korean
+ keyboard
+
+---
+ src/hunspell/hunspell.cxx | 69 +++++++++++++++++++++++++++++++++++------------
+ src/hunspell/hunspell.hxx | 4 ++-
+ src/hunspell/replist.cxx | 18 ++++++++++---
+ src/hunspell/replist.hxx | 2 ++
+ src/tools/hunspell.cxx | 2 +-
+ 6 files changed, 78 insertions(+), 24 deletions(-)
+
+diff --git a/src/hunspell/hunspell.cxx b/src/hunspell/hunspell.cxx
+index 7fae54b..d8ef357 100644
+--- misc/hunspell-1.3.3/src/hunspell/hunspell.cxx
++++ misc/build/hunspell-1.3.3/src/hunspell/hunspell.cxx
+@@ -12,6 +12,7 @@
+ #endif
+ #include "csutil.hxx"
+
++#include <limits>
+ #include <string>
+
+ Hunspell::Hunspell(const char * affpath, const char * dpath, const char * key)
+@@ -349,8 +350,13 @@ int Hunspell::spell(const char * word, int * info, char ** root)
+
+ // input conversion
+ RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+- if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
+- else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
++ int convstatus = rl ? rl->conv(word, wspace, MAXWORDUTF8LEN) : 0;
++ if (convstatus < 0)
++ return 0;
++ else if (convstatus > 0)
++ wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
++ else
++ wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
+
+ if (wl == 0 || maxdic == 0) return 1;
+ if (root) *root = NULL;
+@@ -702,8 +708,13 @@ int Hunspell::suggest(char*** slst, const char * word)
+
+ // input conversion
+ RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+- if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
+- else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
++ int convstatus = rl ? rl->conv(word, wspace, MAXWORDUTF8LEN) : 0;
++ if (convstatus < 0)
++ return 0;
++ else if (convstatus > 0)
++ wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
++ else
++ wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
+
+ if (wl == 0) return 0;
+ int ns = 0;
+@@ -1020,7 +1031,7 @@ int Hunspell::suggest(char*** slst, const char * word)
+ // output conversion
+ rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL;
+ for (int j = 0; rl && j < ns; j++) {
+- if (rl->conv((*slst)[j], wspace)) {
++ if (rl->conv((*slst)[j], wspace, MAXWORDUTF8LEN) > 0) {
+ free((*slst)[j]);
+ (*slst)[j] = mystrdup(wspace);
+ }
+@@ -1395,8 +1406,13 @@ int Hunspell::analyze(char*** slst, const char * word)
+
+ // input conversion
+ RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+- if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
+- else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
++ int convstatus = rl ? rl->conv(word, wspace, MAXWORDUTF8LEN) : 0;
++ if (convstatus < 0)
++ return 0;
++ else if (convstatus > 0)
++ wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
++ else
++ wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
+
+ if (wl == 0) {
+ if (abbv) {
+@@ -1684,12 +1700,16 @@ int Hunspell::get_langnum() const
+ return langnum;
+ }
+
+-int Hunspell::input_conv(const char * word, char * dest)
++int Hunspell::input_conv(const char * word, char * dest, size_t destsize)
+ {
+ RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+- return (rl && rl->conv(word, dest));
++ return (rl && rl->conv(word, dest, destsize) > 0);
+ }
+
++int Hunspell::input_conv(const char * word, char * dest)
++{
++ return input_conv(word, dest, std::numeric_limits<std::size_t>::max());
++}
+
+ // return the beginning of the element (attr == NULL) or the attribute
+ const char * Hunspell::get_xml_pos(const char * s, const char * attr)
+diff --git a/src/hunspell/hunspell.hxx b/src/hunspell/hunspell.hxx
+index e62f0dd..0b5ad2e 100644
+--- misc/hunspell-1.3.3/src/hunspell/hunspell.hxx
++++ misc/build/hunspell-1.3.3/src/hunspell/hunspell.hxx
+@@ -226,7 +226,9 @@ public:
+
+ /* need for putdic */
+ int input_conv(const char * word, char * dest);
+-
++ // ^^-deprecated, use this-vv"
++ int input_conv(const char * word, char * dest, size_t destsize);
++
+ /* experimental and deprecated functions */
+
+ #ifdef HUNSPELL_EXPERIMENTAL
+diff --git a/src/hunspell/replist.cxx b/src/hunspell/replist.cxx
+index b9b1255..bac3e06 100644
+--- misc/hunspell-1.3.3/src/hunspell/replist.cxx
++++ misc/build/hunspell-1.3.3/src/hunspell/replist.cxx
+@@ -74,6 +74,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdio.h>
++#include <limits>
+
+ #include "replist.hxx"
+ #include "csutil.hxx"
+@@ -139,19 +140,30 @@ int RepList::add(char * pat1, char * pat2) {
+ return 0;
+ }
+
+-int RepList::conv(const char * word, char * dest) {
++int RepList::conv(const char * word, char * dest, size_t destsize) {
+ int stl = 0;
+ int change = 0;
+ for (size_t i = 0; i < strlen(word); i++) {
+ int n = near(word + i);
+ int l = match(word + i, n);
+ if (l) {
++ size_t replen = strlen(dat[n]->pattern2);
++ if (stl+replen >= destsize)
++ return -1;
+ strcpy(dest + stl, dat[n]->pattern2);
+- stl += strlen(dat[n]->pattern2);
++ stl += replen;
+ i += l - 1;
+ change = 1;
+- } else dest[stl++] = word[i];
++ } else {
++ if (stl+1 >= destsize)
++ return -1;
++ dest[stl++] = word[i];
++ }
+ }
+ dest[stl] = '\0';
+ return change;
+ }
++
++int RepList::conv(const char * word, char * dest) {
++ return conv(word, dest, std::numeric_limits<std::size_t>::max());
++}
+diff --git a/src/hunspell/replist.hxx b/src/hunspell/replist.hxx
+index 1e3d6e4..e418298 100644
+--- misc/hunspell-1.3.3/src/hunspell/replist.hxx
++++ misc/build/hunspell-1.3.3/src/hunspell/replist.hxx
+@@ -99,5 +99,7 @@ public:
+ int near(const char * word);
+ int match(const char * word, int n);
+ int conv(const char * word, char * dest);
++ // ^^-deprecated, use this-vv"
++ int conv(const char * word, char * dest, size_t destsize);
+ };
+ #endif
+diff --git a/src/tools/hunspell.cxx b/src/tools/hunspell.cxx
+index 6124ac4..1b50fe1 100644
+--- misc/hunspell-1.3.3/src/tools/hunspell.cxx
++++ misc/build/hunspell-1.3.3/src/tools/hunspell.cxx
+@@ -524,7 +524,7 @@ int putdic(char * word, Hunspell * pMS)
+
+ word = chenc(word, ui_enc, dic_enc[0]);
+
+- if(pMS->input_conv(word, buf)) word = buf;
++ if(pMS->input_conv(word, buf, MAXLNLEN)) word = buf;
+
+ int ret;
+
+--
+2.4.0
+
commit 5b9501f6da42ba5b9d1b3c702d527bf8795cdd7c
Author: Caolán McNamara <caolanm at redhat.com>
Date: Wed Sep 9 09:45:58 2015 +0100
Resolves: tdf#93887 distinguish between empty selection lost selection
Change-Id: Id0be728602b3c58b2853ff464336d68303531efe
(cherry picked from commit f3f1919aa4eca2f6180649eda43bcb813b1f0450)
Reviewed-on: https://gerrit.libreoffice.org/18434
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
Tested-by: Miklos Vajna <vmiklos at collabora.co.uk>
diff --git a/vcl/unx/gtk3/app/gtk3gtkinst.cxx b/vcl/unx/gtk3/app/gtk3gtkinst.cxx
index d8614df..f8fd6a6 100644
--- a/vcl/unx/gtk3/app/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/app/gtk3gtkinst.cxx
@@ -372,8 +372,11 @@ sal_Bool VclGtkClipboard::supportsService( const OUString& ServiceName ) throw(
Reference< css::datatransfer::XTransferable > VclGtkClipboard::getContents() throw( RuntimeException, std::exception )
{
- if (!m_aContents.is())
+ 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;
commit 5eb91d291d383c519c5b931bc6218c0c5caa8f3d
Author: Szymon Kłos <eszkadev at gmail.com>
Date: Thu Jul 23 10:54:44 2015 +0200
Resolves: tdf#93778 fixed crash
While opening folders in SvtFileView using doubleclick,
sometimes GtkSalFrame::gestureLongPress method is
executed with a null frame pointer and LO crashes.
I noticed this only with remote dirs, probably this
bug occurs only when the doubleclick handler routine
takes a lot of time.
(cherry picked from commit db33c7853e12e9593a530ce2327e9662bcab1480)
Change-Id: I432046994b3e1662bd7e499681bd20e9696b2d52
Reviewed-on: https://gerrit.libreoffice.org/18571
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/unx/gtk/window/gtksalframe.cxx b/vcl/unx/gtk/window/gtksalframe.cxx
index 7f8570e..347497c 100644
--- a/vcl/unx/gtk/window/gtksalframe.cxx
+++ b/vcl/unx/gtk/window/gtksalframe.cxx
@@ -3541,15 +3541,18 @@ void GtkSalFrame::gestureLongPress(GtkGestureLongPress* gesture, gpointer frame)
{
GtkSalFrame* pThis = static_cast<GtkSalFrame*>(frame);
- SalLongPressEvent aEvent;
+ 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;
+ 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);
+ pThis->CallCallback(SALEVENT_LONGPRESS, &aEvent);
+ }
}
#endif
commit 868ddebc1ad874ca17e0b7bee873dfeb5f6521ea
Author: Julien Nabet <serval2412 at yahoo.fr>
Date: Thu Sep 3 22:37:31 2015 +0200
tdf#92794: '$' should be replaced in error dialog of addressbook
Change-Id: Ic57611be96f160037fbff2e9452f9206083c80e4
Reviewed-on: https://gerrit.libreoffice.org/18324
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit 01547985ceee8c199dc189071845ef5fcda11782)
Reviewed-on: https://gerrit.libreoffice.org/18520
diff --git a/connectivity/source/drivers/mork/MConnection.cxx b/connectivity/source/drivers/mork/MConnection.cxx
index 8112a16..3f8baaf 100644
--- a/connectivity/source/drivers/mork/MConnection.cxx
+++ b/connectivity/source/drivers/mork/MConnection.cxx
@@ -143,7 +143,9 @@ void OConnection::construct(const OUString& url,const Sequence< PropertyValue >&
if (!m_pBook->open(strPath.getStr()))
{
SAL_WARN("connectivity.mork", "Can not parse abook mork file: " << strPath);
- throwGenericSQLException( STR_COULD_NOT_LOAD_FILE, *this );
+ const OUString sError( getResources().getResourceStringWithSubstitution(
+ STR_COULD_NOT_LOAD_FILE, "$filename$", abook));
+ ::dbtools::throwGenericSQLException( sError, *this );
}
// read history only in production
@@ -153,7 +155,9 @@ void OConnection::construct(const OUString& url,const Sequence< PropertyValue >&
if (!m_pHistory->open(strPath.getStr()))
{
SAL_WARN("connectivity.mork", "Can not parse history mork file: " << strPath);
- throwGenericSQLException( STR_COULD_NOT_LOAD_FILE, *this );
+ const OUString sError( getResources().getResourceStringWithSubstitution(
+ STR_COULD_NOT_LOAD_FILE, "$filename$", history));
+ ::dbtools::throwGenericSQLException( sError, *this );
}
}
commit 7108b46723750dd390d28afda37ecf1e85581f6a
Author: Katarina Behrens <Katarina.Behrens at cib.de>
Date: Thu Sep 10 13:22:03 2015 +0200
tdf#94037: Don't try to manipulate non-existent widget container
Regression from commit 8b7799972a95da50e1e92748, which replaced
named GtkFrame with GtkBox, but didn't rename the box accordingly.
Change-Id: I321dbee05faded81dbf575bca3c578ecb09f1a3e
Reviewed-on: https://gerrit.libreoffice.org/18562
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sc/uiconfig/scalc/ui/protectsheetdlg.ui b/sc/uiconfig/scalc/ui/protectsheetdlg.ui
index 388c289..ee0d7c3 100644
--- a/sc/uiconfig/scalc/ui/protectsheetdlg.ui
+++ b/sc/uiconfig/scalc/ui/protectsheetdlg.ui
@@ -180,7 +180,7 @@
</packing>
</child>
<child>
- <object class="GtkBox" id="box3">
+ <object class="GtkBox" id="options">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
commit 07e60c9fe65002f698524a838150c457daef2d77
Author: Caolán McNamara <caolanm at redhat.com>
Date: Fri Sep 11 15:38:01 2015 +0100
check stream status more often
Change-Id: I233c2fff9c06a81117f8114ccee83b53ea4026db
(cherry picked from commit b43e03353aeb04ed74a272d98df03dd7c20f3478)
Reviewed-on: https://gerrit.libreoffice.org/18505
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: David Tardon <dtardon at redhat.com>
diff --git a/filter/qa/cppunit/data/ras/fail/hang-1.ras b/filter/qa/cppunit/data/ras/fail/hang-1.ras
new file mode 100644
index 0000000..44dec67
Binary files /dev/null and b/filter/qa/cppunit/data/ras/fail/hang-1.ras differ
diff --git a/filter/source/graphicfilter/iras/iras.cxx b/filter/source/graphicfilter/iras/iras.cxx
index 5877fa2..e3209bd 100644
--- a/filter/source/graphicfilter/iras/iras.cxx
+++ b/filter/source/graphicfilter/iras/iras.cxx
@@ -222,31 +222,43 @@ bool RASReader::ImplReadBody(BitmapWriteAccess * pAcc)
case 1 :
for (y = 0; y < mnHeight && mbStatus; ++y)
{
- for ( x = 0; x < mnWidth; x++ )
+ for (x = 0; x < mnWidth && mbStatus; ++x)
{
if (!(x & 7))
+ {
nDat = ImplGetByte();
+ if (!m_rRAS.good())
+ mbStatus = false;
+ }
pAcc->SetPixelIndex( y, x,
sal::static_int_cast< sal_uInt8 >(
nDat >> ( ( x & 7 ) ^ 7 )) );
}
- if (!( ( x - 1 ) & 0x8 ) ) ImplGetByte(); // WORD ALIGNMENT ???
- if (!m_rRAS.good())
- mbStatus = false;
+ if (!( ( x - 1 ) & 0x8 ) )
+ {
+ ImplGetByte(); // WORD ALIGNMENT ???
+ if (!m_rRAS.good())
+ mbStatus = false;
+ }
}
break;
case 8 :
for (y = 0; y < mnHeight && mbStatus; ++y)
{
- for ( x = 0; x < mnWidth; x++ )
+ for (x = 0; x < mnWidth && mbStatus; ++x)
{
nDat = ImplGetByte();
pAcc->SetPixelIndex( y, x, nDat );
+ if (!m_rRAS.good())
+ mbStatus = false;
+ }
+ if ( x & 1 )
+ {
+ ImplGetByte(); // WORD ALIGNMENT ???
+ if (!m_rRAS.good())
+ mbStatus = false;
}
- if ( x & 1 ) ImplGetByte(); // WORD ALIGNMENT ???
- if (!m_rRAS.good())
- mbStatus = false;
}
break;
@@ -257,7 +269,7 @@ bool RASReader::ImplReadBody(BitmapWriteAccess * pAcc)
case 24 :
for (y = 0; y < mnHeight && mbStatus; ++y)
{
- for ( x = 0; x < mnWidth; x++ )
+ for (x = 0; x < mnWidth && mbStatus; ++x)
{
if ( mnType == RAS_TYPE_RGB_FORMAT )
{
@@ -272,17 +284,22 @@ bool RASReader::ImplReadBody(BitmapWriteAccess * pAcc)
nRed = ImplGetByte();
}
pAcc->SetPixel ( y, x, BitmapColor( nRed, nGreen, nBlue ) );
+ if (!m_rRAS.good())
+ mbStatus = false;
+ }
+ if ( x & 1 )
+ {
+ ImplGetByte(); // WORD ALIGNMENT ???
+ if (!m_rRAS.good())
+ mbStatus = false;
}
- if ( x & 1 ) ImplGetByte(); // WORD ALIGNMENT ???
- if (!m_rRAS.good())
- mbStatus = false;
}
break;
case 32 :
for (y = 0; y < mnHeight && mbStatus; ++y)
{
- for ( x = 0; x < mnWidth; x++ )
+ for (x = 0; x < mnWidth && mbStatus; ++x)
{
nDat = ImplGetByte(); // pad byte > nil
if ( mnType == RAS_TYPE_RGB_FORMAT )
@@ -298,9 +315,9 @@ bool RASReader::ImplReadBody(BitmapWriteAccess * pAcc)
nRed = ImplGetByte();
}
pAcc->SetPixel ( y, x, BitmapColor( nRed, nGreen, nBlue ) );
+ if (!m_rRAS.good())
+ mbStatus = false;
}
- if (!m_rRAS.good())
- mbStatus = false;
}
break;
}
commit c9e824687521ef2c3a90ba969627178b372d885c
Author: Caolán McNamara <caolanm at redhat.com>
Date: Thu Sep 10 09:24:13 2015 +0100
fix size check related hang
Change-Id: I3e8aa5c48ba802cd363688502b44e27bfdf67f01
(cherry picked from commit b02f1c58e7bb8b6c9381107431557d3f39794fe0)
Reviewed-on: https://gerrit.libreoffice.org/18464
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: David Tardon <dtardon at redhat.com>
Tested-by: David Tardon <dtardon at redhat.com>
diff --git a/filter/qa/cppunit/data/psd/pass/hang-1.psd b/filter/qa/cppunit/data/psd/pass/hang-1.psd
new file mode 100644
index 0000000..8f557dd
Binary files /dev/null and b/filter/qa/cppunit/data/psd/pass/hang-1.psd differ
diff --git a/filter/source/graphicfilter/ipsd/ipsd.cxx b/filter/source/graphicfilter/ipsd/ipsd.cxx
index 7fbd5ab..a5bea9f 100644
--- a/filter/source/graphicfilter/ipsd/ipsd.cxx
+++ b/filter/source/graphicfilter/ipsd/ipsd.cxx
@@ -172,9 +172,6 @@ bool PSDReader::ReadPSD(Graphic & rGraphic )
bool PSDReader::ImplReadHeader()
{
- sal_uInt16 nCompression;
- sal_uInt32 nColorLength, nResourceLength, nLayerMaskLength;
-
mpFileHeader = new PSDFileHeader;
m_rPSD.ReadUInt32( mpFileHeader->nSignature ).ReadUInt16( mpFileHeader->nVersion ).ReadUInt32( mpFileHeader->nPad1 ). ReadUInt16( mpFileHeader->nPad2 ).ReadUInt16( mpFileHeader->nChannels ).ReadUInt32( mpFileHeader->nRows ). ReadUInt32( mpFileHeader->nColumns ).ReadUInt16( mpFileHeader->nDepth ).ReadUInt16( mpFileHeader->nMode );
@@ -194,6 +191,7 @@ bool PSDReader::ImplReadHeader()
mnDestBitDepth = ( nDepth == 16 ) ? 8 : nDepth;
+ sal_uInt32 nColorLength(0);
m_rPSD.ReadUInt32( nColorLength );
if ( mpFileHeader->nMode == PSD_CMYK )
{
@@ -270,7 +268,10 @@ bool PSDReader::ImplReadHeader()
default:
return false;
}
- m_rPSD.ReadUInt32( nResourceLength );
+ sal_uInt32 nResourceLength(0);
+ m_rPSD.ReadUInt32(nResourceLength);
+ if (nResourceLength > m_rPSD.remainingSize())
+ return false;
sal_uInt32 nLayerPos = m_rPSD.Tell() + nResourceLength;
// this is a loop over the resource entries to get the resolution info
@@ -291,8 +292,8 @@ bool PSDReader::ImplReadHeader()
if ( nResEntryLen & 1 )
nResEntryLen++; // the resource entries are padded
sal_uInt32 nCurrentPos = m_rPSD.Tell();
- if ( ( nResEntryLen + nCurrentPos ) > nLayerPos ) // check if size
- break; // is possible
+ if (nResEntryLen > (nLayerPos - nCurrentPos)) // check if size
+ break; // is possible
switch( nUniqueID )
{
case 0x3ed : // UID for the resolution info
@@ -307,10 +308,12 @@ bool PSDReader::ImplReadHeader()
m_rPSD.Seek( nCurrentPos + nResEntryLen ); // set the stream to the next
} // resource entry
m_rPSD.Seek( nLayerPos );
+ sal_uInt32 nLayerMaskLength(0);
m_rPSD.ReadUInt32( nLayerMaskLength );
m_rPSD.SeekRel( nLayerMaskLength );
- m_rPSD.ReadUInt16( nCompression );
+ sal_uInt16 nCompression(0);
+ m_rPSD.ReadUInt16(nCompression);
if ( nCompression == 0 )
{
mbCompression = false;
@@ -326,8 +329,6 @@ bool PSDReader::ImplReadHeader()
return true;
}
-
-
bool PSDReader::ImplReadBody()
{
sal_uLong nX, nY;
commit 313037a7ed10e979a3af8ffac801dd6b6bdb7615
Author: Julien Nabet <serval2412 at yahoo.fr>
Date: Sun Sep 13 09:42:01 2015 +0200
cppcheck: Mismatching allocation and deallocation
+ Typo: excecptionTypeSizeArray->exceptionTypeSizeArray
Cherry-picked from 81d62c5f48f3bf341c4c7bdaef5a5ce5941f3e62
Change-Id: I6fac3bea1eba094e87717d20a08ec7cf6151e2df
Reviewed-on: https://gerrit.libreoffice.org/18527
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Noel Grandin <noelgrandin at gmail.com>
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
index f95a045..321a168 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
@@ -609,8 +609,8 @@ RaiseInfo::RaiseInfo(typelib_TypeDescription * pTD)throw ()
// 2.Pass: Get the total needed memory for class ExceptionType
// (with embedded type_info) and keep the sizes for each instance
- // is stored in alloced int array
- int *excecptionTypeSizeArray = new int[nLen];
+ // is stored in allocated int array
+ int *exceptionTypeSizeArray = new int[nLen];
nLen = 0;
for (pCompTD = (typelib_CompoundTypeDescription*)pTD;
@@ -625,14 +625,14 @@ RaiseInfo::RaiseInfo(typelib_TypeDescription * pTD)throw ()
n++;
typeInfoLen = n*4;
}
- excecptionTypeSizeArray[nLen++] = typeInfoLen + sizeof(ExceptionType);
+ exceptionTypeSizeArray[nLen++] = typeInfoLen + sizeof(ExceptionType);
}
// Total ExceptionType related mem
int excTypeAddLen = 0;
for (int i = 0; i < nLen; i++)
{
- excTypeAddLen += excecptionTypeSizeArray[i];
+ excTypeAddLen += exceptionTypeSizeArray[i];
}
// Allocate mem for code and all dynamic data in one chunk to guarantee
@@ -684,7 +684,7 @@ RaiseInfo::RaiseInfo(typelib_TypeDescription * pTD)throw ()
// Next trampoline entry offset
pCodeOffset += codeSnippetSize;
// Next ExceptionType placement offset
- etMemOffset += excecptionTypeSizeArray[nPos - 1];
+ etMemOffset += exceptionTypeSizeArray[nPos - 1];
// Keep offset of addresses of ET for D-Tor call in ~RaiseInfo
types[nPos++]
@@ -694,7 +694,7 @@ RaiseInfo::RaiseInfo(typelib_TypeDescription * pTD)throw ()
assert(etMem + etMemOffset == pCode + totalSize);
// remove array
- delete excecptionTypeSizeArray;
+ delete[] exceptionTypeSizeArray;
}
RaiseInfo::~RaiseInfo() throw ()
commit 00379a83cad8a016c54b3d90fef472a2ca6aeb96
Author: László Németh <laszlo.nemeth at collabora.com>
Date: Fri Sep 11 17:20:29 2015 +0200
tdf#92145: Writer table rows/columns can't be resized
with disabled rulers. (This fix was suggested by Tomaž Vajngerl.)
(Cherry-picked from the commit ed031895f6f5b361cccc6811b53c6f2b9cfc3e23)
Conflicts:
svtools/source/control/ruler.cxx
Change-Id: I161237cdb4941c0eaf934223b078acd94d72e21d
Reviewed-on: https://gerrit.libreoffice.org/18507
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
diff --git a/svtools/source/control/ruler.cxx b/svtools/source/control/ruler.cxx
index d4b9374..2d4486c 100644
--- a/svtools/source/control/ruler.cxx
+++ b/svtools/source/control/ruler.cxx
@@ -2344,6 +2344,12 @@ bool Ruler::StartDocDrag( const MouseEvent& rMEvt, RulerType eDragType )
// update ruler
if ( mbFormat )
{
+ if (!IsReallyVisible())
+ {
+ // set mpData for ImplDocHitTest()
+ ImplFormat(*this);
+ }
+
Invalidate(INVALIDATE_NOERASE);
}
commit ce80d8374938952a38e9fb2149ddae23b09a0b53
Author: Niklas Johansson <sleeping.pillow at gmail.com>
Date: Sat Sep 12 09:10:35 2015 +0200
Updated core
Project: dictionaries 1a7a5f8de5e79e1f96095acf98bc5541a0cbac8f
Update the Swedish spelling dictionary
Change-Id: I5ae96f88587f5eeb0811290ab24bba28d3bc5013
Reviewed-on: https://gerrit.libreoffice.org/18514
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/dictionaries b/dictionaries
index 71f54e9..1a7a5f8 160000
--- a/dictionaries
+++ b/dictionaries
@@ -1 +1 @@
-Subproject commit 71f54e95a0b443c673f924c71e23d04b540cc441
+Subproject commit 1a7a5f8de5e79e1f96095acf98bc5541a0cbac8f
commit e5544e485f8b82612a909568174b8ad142bed54e
Author: Michael Stahl <mstahl at redhat.com>
Date: Wed Sep 9 10:30:04 2015 +0200
tdf#92036: sw: fix idle spelling loop
There is a sort of intentional infinite loop in the idle spell checking
handler: while the user is typing a word, it should not be marked as
invalid yet, in order not to annoy them with red underlines.
So the word where the cursor is positioned always remained dirty, unless
you happen to have a grammar checker enabled, which clears the
paragraph's dirty flag from a separate thread.
To avoid the infinite loop, add another spell checking state "PENDING"
which is the same as dirty except that it should cancel the idle spell
checking.
The idle spell checking will run again when the user does the next
editing operation. Notably this means if the user just moves the cursor
out of the wrongly spelled word, it won't be underlined yet, but that
appears a minor issue, and checking when the cursor leaves the word
appears too hard to implement.
(cherry picked from commit 4c91e94e892943ef5e031d65f6f42864233cb4cd)
Change-Id: Ifb3d6d17f94f9f1cfad82e70dfa79f1594c38647
Reviewed-on: https://gerrit.libreoffice.org/18511
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 94ffd6a..87abad9 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -184,13 +184,16 @@ class SW_DLLPUBLIC SwTextNode: public SwContentNode, public ::sfx2::Metadatable
void DelFrms_TextNodePart();
public:
+ enum class WrongState { TODO, PENDING, DONE };
+
bool IsWordCountDirty() const;
+ WrongState GetWrongDirty() const;
bool IsWrongDirty() const;
bool IsGrammarCheckDirty() const;
bool IsSmartTagDirty() const;
bool IsAutoCompleteWordDirty() const;
void SetWordCountDirty( bool bNew ) const;
- void SetWrongDirty( bool bNew ) const;
+ void SetWrongDirty(WrongState eNew) const;
void SetGrammarCheckDirty( bool bNew ) const;
void SetSmartTagDirty( bool bNew ) const;
void SetAutoCompleteWordDirty( bool bNew ) const;
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 2b82850..3d7497d 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -1100,14 +1100,14 @@ static bool lcl_SpellAndGrammarAgain( const SwNodePtr& rpNd, void* pArgs )
{
if( pTextNode->GetWrong() &&
pTextNode->GetWrong()->InvalidateWrong() )
- pTextNode->SetWrongDirty( true );
+ pTextNode->SetWrongDirty(SwTextNode::WrongState::TODO);
if( pTextNode->GetGrammarCheck() &&
pTextNode->GetGrammarCheck()->InvalidateWrong() )
pTextNode->SetGrammarCheckDirty( true );
}
else
{
- pTextNode->SetWrongDirty( true );
+ pTextNode->SetWrongDirty(SwTextNode::WrongState::TODO);
if( pTextNode->GetWrong() )
pTextNode->GetWrong()->SetInvalid( 0, COMPLETE_STRING );
pTextNode->SetGrammarCheckDirty( true );
diff --git a/sw/source/core/inc/wrong.hxx b/sw/source/core/inc/wrong.hxx
index 10a0309..cd9da5c 100644
--- a/sw/source/core/inc/wrong.hxx
+++ b/sw/source/core/inc/wrong.hxx
@@ -211,7 +211,8 @@ public:
inline void Validate(){ nBeginInvalid = nEndInvalid = COMPLETE_STRING; }
void Invalidate( sal_Int32 nBegin, sal_Int32 nEnd );
bool InvalidateWrong();
- bool Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
+ enum class FreshState { FRESH, CURSOR, NOTHING };
+ FreshState Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
sal_Int32 nLen, sal_uInt16 nIndex, sal_Int32 nCursorPos );
sal_uInt16 GetWrongPos( sal_Int32 nValue ) const;
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index d1c5cd4..3c61e30 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -1931,7 +1931,8 @@ bool SwLayIdle::_DoIdleJob( const SwContentFrm *pCnt, IdleJobType eJob )
case ONLINE_SPELLING :
{
SwRect aRepaint( const_cast<SwTextFrm*>(static_cast<const SwTextFrm*>(pCnt))->_AutoSpell( pContentNode, nTextPos ) );
- bPageValid = bPageValid && !pTextNode->IsWrongDirty();
+ // tdf#92036 PENDING should stop idle spell checking
+ bPageValid = bPageValid && (SwTextNode::WrongState::TODO != pTextNode->GetWrongDirty());
if( !bPageValid )
bAllValid = false;
if ( aRepaint.HasArea() )
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 886cec5..a4a707f 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -845,7 +845,7 @@ static void lcl_SetWrong( SwTextFrm& rFrm, sal_Int32 nPos, sal_Int32 nCnt, bool
pTextNode->SetSmartTags( new SwWrongList( WRONGLIST_SMARTTAG ) );
pTextNode->GetSmartTags()->SetInvalid( nPos, nEnd );
}
- pTextNode->SetWrongDirty( true );
+ pTextNode->SetWrongDirty(SwTextNode::WrongState::TODO);
pTextNode->SetGrammarCheckDirty( true );
pTextNode->SetWordCountDirty( true );
pTextNode->SetAutoCompleteWordDirty( true );
diff --git a/sw/source/core/text/wrong.cxx b/sw/source/core/text/wrong.cxx
index 0ea4c52..1fb87d9 100644
--- a/sw/source/core/text/wrong.cxx
+++ b/sw/source/core/text/wrong.cxx
@@ -356,11 +356,17 @@ void SwWrongList::Move( sal_Int32 nPos, sal_Int32 nDiff )
@return <true> if ???
*/
-bool SwWrongList::Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
- sal_Int32 nLen, sal_uInt16 nIndex, sal_Int32 nCursorPos )
+auto SwWrongList::Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
+ sal_Int32 nLen, sal_uInt16 nIndex, sal_Int32 nCursorPos ) -> FreshState
{
- // length of word must be greater than 0 and cursor position must be outside the word
- bool bRet = nLen && ( nCursorPos > nPos + nLen || nCursorPos < nPos );
+ // length of word must be greater than 0
+ // only report a spelling error if the cursor position is outside the word,
+ // so that the user is not annoyed while typing
+ FreshState eRet = (nLen)
+ ? (nCursorPos > nPos + nLen || nCursorPos < nPos)
+ ? FreshState::FRESH
+ : FreshState::CURSOR
+ : FreshState::NOTHING;
sal_Int32 nWrPos = 0;
sal_Int32 nWrEnd = rEnd;
@@ -383,11 +389,11 @@ bool SwWrongList::Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
if( nCnt < Count() && nWrPos == nPos && Len( nCnt ) == nLen )
{
++nCnt;
- bRet = true;
+ eRet = FreshState::FRESH;
}
else
{
- if( bRet )
+ if (FreshState::FRESH == eRet)
{
if( rStart > nPos )
rStart = nPos;
@@ -417,7 +423,7 @@ bool SwWrongList::Fresh( sal_Int32 &rStart, sal_Int32 &rEnd, sal_Int32 nPos,
Remove( nIndex, nCnt - nIndex );
- return bRet;
+ return eRet;
}
void SwWrongList::Invalidate( sal_Int32 nBegin, sal_Int32 nEnd )
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index a56d675..9606c12 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -424,7 +424,7 @@ SwContentNode *SwTextNode::SplitContentNode( const SwPosition &rPos )
{
pNode->SetWrong( GetWrong()->SplitList( nSplitPos ) );
}
- SetWrongDirty( true );
+ SetWrongDirty(WrongState::TODO);
if( GetGrammarCheck() )
{
@@ -527,7 +527,7 @@ SwContentNode *SwTextNode::SplitContentNode( const SwPosition &rPos )
{
SwWrongList *pList = GetWrong();
SetWrong( 0, false );
- SetWrongDirty( true );
+ SetWrongDirty(WrongState::TODO);
SwGrammarMarkUp *pList3 = GetGrammarCheck();
SetGrammarCheck( 0, false );
@@ -648,7 +648,7 @@ SwContentNode *SwTextNode::JoinNext()
if( pList )
{
pList->JoinList( pTextNode->GetWrong(), nOldLen );
- SetWrongDirty( true );
+ SetWrongDirty(WrongState::TODO);
SetWrong( 0, false );
}
else
@@ -657,7 +657,7 @@ SwContentNode *SwTextNode::JoinNext()
if( pList )
{
pList->Move( 0, nOldLen );
- SetWrongDirty( true );
+ SetWrongDirty(WrongState::TODO);
pTextNode->SetWrong( 0, false );
}
}
@@ -739,7 +739,7 @@ SwContentNode *SwTextNode::JoinPrev()
if( pList )
{
pList->JoinList( GetWrong(), Len() );
- SetWrongDirty( true );
+ SetWrongDirty(WrongState::TODO);
pTextNode->SetWrong( 0, false );
SetWrong( NULL );
}
@@ -749,7 +749,7 @@ SwContentNode *SwTextNode::JoinPrev()
if( pList )
{
pList->Move( 0, nLen );
- SetWrongDirty( true );
+ SetWrongDirty(WrongState::TODO);
SetWrong( 0, false );
}
}
@@ -1383,7 +1383,7 @@ const SwTextInputField* SwTextNode::GetOverlappingInputField( const SwTextAttr&
void SwTextNode::DelFrms_TextNodePart()
{
SetWrong( NULL );
- SetWrongDirty( true );
+ SetWrongDirty(WrongState::TODO);
SetGrammarCheck( NULL );
SetGrammarCheckDirty( true );
diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx
index 0c42a76..adcbf5c 100644
--- a/sw/source/core/txtnode/txtedt.cxx
+++ b/sw/source/core/txtnode/txtedt.cxx
@@ -1311,6 +1311,7 @@ SwRect SwTextFrm::_AutoSpell( const SwContentNode* pActNode, sal_Int32 nActPos )
}
bool bFresh = nBegin < nEnd;
+ bool bPending(false);
if( bFresh )
{
@@ -1353,13 +1354,19 @@ SwRect SwTextFrm::_AutoSpell( const SwContentNode* pActNode, sal_Int32 nActPos )
pNode->SetWrong( new SwWrongList( WRONGLIST_SPELL ) );
pNode->GetWrong()->SetInvalid( 0, nEnd );
}
- if( pNode->GetWrong()->Fresh( nChgStart, nChgEnd,
- nBegin, nLen, nInsertPos, nActPos ) )
- pNode->GetWrong()->Insert( OUString(), 0, nBegin, nLen, nInsertPos++ );
- else
+ SwWrongList::FreshState const eState(pNode->GetWrong()->Fresh(
+ nChgStart, nChgEnd, nBegin, nLen, nInsertPos, nActPos));
+ switch (eState)
{
- nInvStart = nBegin;
- nInvEnd = nBegin + nLen;
+ case SwWrongList::FreshState::FRESH:
+ pNode->GetWrong()->Insert(OUString(), 0, nBegin, nLen, nInsertPos++);
+ break;
+ case SwWrongList::FreshState::CURSOR:
+ bPending = true; // fall-through to mark as invalid
+ case SwWrongList::FreshState::NOTHING:
+ nInvStart = nBegin;
+ nInvEnd = nBegin + nLen;
+ break;
}
}
}
@@ -1402,12 +1409,17 @@ SwRect SwTextFrm::_AutoSpell( const SwContentNode* pActNode, sal_Int32 nActPos )
}
pNode->GetWrong()->SetInvalid( nInvStart, nInvEnd );
- pNode->SetWrongDirty( COMPLETE_STRING != pNode->GetWrong()->GetBeginInv() );
+ pNode->SetWrongDirty(
+ (COMPLETE_STRING != pNode->GetWrong()->GetBeginInv())
+ ? ((bPending)
+ ? SwTextNode::WrongState::PENDING
+ : SwTextNode::WrongState::TODO)
+ : SwTextNode::WrongState::DONE);
if( !pNode->GetWrong()->Count() && ! pNode->IsWrongDirty() )
pNode->SetWrong( NULL );
}
else
- pNode->SetWrongDirty( false );
+ pNode->SetWrongDirty(SwTextNode::WrongState::DONE);
if( bAddAutoCmpl )
pNode->SetAutoCompleteWordDirty( false );
@@ -2115,7 +2127,7 @@ struct SwParaIdleData_Impl
sal_uLong nNumberOfChars;
sal_uLong nNumberOfCharsExcludingSpaces;
bool bWordCountDirty;
- bool bWrongDirty; // Ist das Wrong-Feld auf invalid?
+ SwTextNode::WrongState eWrongDirty; ///< online spell checking needed/done?
bool bGrammarCheckDirty;
bool bSmartTagDirty;
bool bAutoComplDirty; // die ACompl-Liste muss angepasst werden
@@ -2129,7 +2141,7 @@ struct SwParaIdleData_Impl
nNumberOfChars ( 0 ),
nNumberOfCharsExcludingSpaces ( 0 ),
bWordCountDirty ( true ),
- bWrongDirty ( true ),
+ eWrongDirty ( SwTextNode::WrongState::TODO ),
bGrammarCheckDirty ( true ),
bSmartTagDirty ( true ),
bAutoComplDirty ( true ) {};
@@ -2276,17 +2288,22 @@ bool SwTextNode::IsWordCountDirty() const
return m_pParaIdleData_Impl && m_pParaIdleData_Impl->bWordCountDirty;
}
-void SwTextNode::SetWrongDirty( bool bNew ) const
+void SwTextNode::SetWrongDirty(WrongState eNew) const
{
if ( m_pParaIdleData_Impl )
{
- m_pParaIdleData_Impl->bWrongDirty = bNew;
+ m_pParaIdleData_Impl->eWrongDirty = eNew;
}
}
+auto SwTextNode::GetWrongDirty() const -> WrongState
+{
+ return (m_pParaIdleData_Impl) ? m_pParaIdleData_Impl->eWrongDirty : WrongState::DONE;
+}
+
bool SwTextNode::IsWrongDirty() const
{
- return m_pParaIdleData_Impl && m_pParaIdleData_Impl->bWrongDirty;
+ return m_pParaIdleData_Impl && m_pParaIdleData_Impl->eWrongDirty != WrongState::DONE;
}
void SwTextNode::SetGrammarCheckDirty( bool bNew ) const
diff --git a/sw/source/core/unocore/unoflatpara.cxx b/sw/source/core/unocore/unoflatpara.cxx
index bec164a..8bda7b7 100644
--- a/sw/source/core/unocore/unoflatpara.cxx
+++ b/sw/source/core/unocore/unoflatpara.cxx
@@ -199,7 +199,10 @@ void SAL_CALL SwXFlatParagraph::setChecked( ::sal_Int32 nType, sal_Bool bVal ) t
if (GetTextNode())
{
if ( text::TextMarkupType::SPELLCHECK == nType )
- GetTextNode()->SetWrongDirty( !bVal );
+ {
+ GetTextNode()->SetWrongDirty(
+ (bVal) ? SwTextNode::WrongState::DONE : SwTextNode::WrongState::TODO);
+ }
else if ( text::TextMarkupType::SMARTTAG == nType )
GetTextNode()->SetSmartTagDirty( !bVal );
else if( text::TextMarkupType::PROOFREADING == nType )
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index 6de0271..e673fb0 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -2562,7 +2562,7 @@ throw (uno::RuntimeException, std::exception)
if ( text::TextMarkupType::SPELLCHECK == nType )
{
- txtNode->SetWrongDirty(true);
+ txtNode->SetWrongDirty(SwTextNode::WrongState::TODO);
txtNode->SetWrong(0, true);
}
else if( text::TextMarkupType::PROOFREADING == nType )
commit ddb9c7c40be9b902425600e018f3a55fa88417f2
Author: Michael Stahl <mstahl at redhat.com>
Date: Fri Sep 11 17:20:27 2015 +0200
Revert "Fix single node CopyRange"
This reverts commit 9099e21b89184bd4e39def497e483cac4a77ec5a.
It causes the problem that frames anchored to the same node where
redlines start or end get duplicated during Hide.
Jan-Marek said that the original mail-merge related problem this change
was fixing is now most likely fixed differently, and the test in
testMultiPageAnchoredDraws() still passes.
(cherry picked from commit e84f0a9b3223f49b0829f2f55dacbf11ae201c1e)
sw: add unit test for the redline frame duplication regression
(cherry picked from commit d5ffcba07acb4dd5bd68373d40f07af825f07fba)
Change-Id: Ie84fed3f64be7696782bc557004eb18fccc5b64b
Reviewed-on: https://gerrit.libreoffice.org/18509
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sw/inc/IDocumentContentOperations.hxx b/sw/inc/IDocumentContentOperations.hxx
index 91ca8ce..75b4f84 100644
--- a/sw/inc/IDocumentContentOperations.hxx
+++ b/sw/inc/IDocumentContentOperations.hxx
@@ -79,6 +79,9 @@ public:
The position can be in the same or in an another document. It can also
be within the range!
+ \warning The range has to include at least two nodes or has to be a
+ SwDoc::IsColumnSelection!
+
Normally this function should work only with content nodes. But there
is a special case used by SwDoc::Paste, which starts the SwPaM at the
content start node. This position doesn't contain any content:
diff --git a/sw/qa/extras/uiwriter/data/redlineFrame.fodt b/sw/qa/extras/uiwriter/data/redlineFrame.fodt
new file mode 100644
index 0000000..31c5f50
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/redlineFrame.fodt
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oas
is:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:
experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:meta><meta:initial-creator>ms </meta:initial-creator><meta:creation-date>2015-08-24T21:49:45.305718699</meta:creation-date><meta:document-statistic meta:table-count="0" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="0" meta:word-count="0" meta:character-count="0" meta:non-whitespace-character-count="0"/><meta:generator>LibreOfficeDev/4.3.7.2$Linux_X86_64 LibreOffice_project/8a35821d8636a03b8bf4e15b48f59794652c68ba</meta:generator></office:meta>
+ <office:font-face-decls>
+ <style:font-face style:name="Lohit Devanagari1" svg:font-family="'Lohit Devanagari'"/>
+ <style:font-face style:name="Liberation Serif" svg:font-family="'Liberation Serif'" style:font-family-generic="roman" style:font-pitch="variable"/>
+ <style:font-face style:name="Liberation Sans" svg:font-family="'Liberation Sans'" style:font-family-generic="swiss" style:font-pitch="variable"/>
+ <style:font-face style:name="Lohit Devanagari" svg:font-family="'Lohit Devanagari'" style:font-family-generic="system" style:font-pitch="variable"/>
+ <style:font-face style:name="Source Han Sans CN Regular" svg:font-family="'Source Han Sans CN Regular'" style:font-family-generic="system" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Sans CN Regular" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ <style:default-style style:family="paragraph">
+ <style:paragraph-properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="page"/>
+ <style:text-properties style:use-window-font-color="true" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="de" fo:country="DE" style:letter-kerning="true" style:font-name-asian="Source Han Sans CN Regular" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Lohit Devanagari" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
+ </style:default-style>
+ <style:default-style style:family="table">
+ <style:table-properties table:border-model="collapsing"/>
+ </style:default-style>
+ <style:default-style style:family="table-row">
+ <style:table-row-properties fo:keep-together="auto"/>
+ </style:default-style>
+ <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+ </office:styles>
+ <office:automatic-styles>
+ <style:page-layout style:name="pm1">
+ <style:page-layout-properties fo:page-width="21.001cm" fo:page-height="29.7cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:footnote-max-height="0cm">
+ <style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="solid" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
+ </style:page-layout-properties>
+ <style:header-style/>
+ <style:footer-style/>
+ </style:page-layout>
+
+ <style:style style:name="P1" style:family="paragraph" style:parent-style-name="Standard">
+ <style:text-properties officeooo:rsid="000b01fe" officeooo:paragraph-rsid="000b01fe"/>
+ </style:style>
+ <style:style style:name="P2" style:family="paragraph" style:parent-style-name="Standard">
+ <style:text-properties officeooo:rsid="000b01fe" officeooo:paragraph-rsid="000b01fe"/>
+ </style:style>
+ <style:style style:name="fr1" style:family="graphic" style:parent-style-name="Frame">
+ <style:graphic-properties style:vertical-pos="top" style:vertical-rel="paragraph-content" style:horizontal-pos="center" style:horizontal-rel="paragraph"/>
+ </style:style>
+ </office:automatic-styles>
+ <office:master-styles>
+ <style:master-page style:name="Standard" style:page-layout-name="pm1"/>
+ </office:master-styles>
+ <office:body>
+ <office:text>
+
+ <text:tracked-changes>
+ <text:changed-region xml:id="ct52929984" text:id="ct52929984">
+ <text:insertion>
+ <office:change-info>
+ <dc:creator>ms </dc:creator>
+ <dc:date>2015-09-10T15:36:00</dc:date>
+ </office:change-info>
+ </text:insertion>
+ </text:changed-region>
+ <text:changed-region xml:id="ct58510944" text:id="ct58510944">
+ <text:deletion>
+ <office:change-info>
+ <dc:creator>ms </dc:creator>
+ <dc:date>2015-09-10T15:36:00</dc:date>
+ </office:change-info>
+ <text:p text:style-name="P1"/>
+ <text:p text:style-name="P1">Removed text</text:p>
+ </text:deletion>
+ </text:changed-region>
+ </text:tracked-changes>
+ <text:p text:style-name="P1"><draw:frame draw:style-name="fr1" draw:name="Frame1" text:anchor-type="char" svg:width="2cm" draw:z-index="0"><draw:text-box fo:min-height="0.499cm"><text:p text:style-name="Frame_20_contents"/></draw:text-box></draw:frame><text:change-start text:change-id="ct52929984"/>Added text<text:change-end text:change-id="ct52929984"/><text:change text:change-id="ct58510944"/></text:p>
+
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 6b8b053..006cb46 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -66,6 +66,7 @@ public:
//Regression test of fdo#70143
//EDITING: undo search&replace corrupt text when searching backward
void testReplaceBackward();
+ void testRedlineFrame();
void testFdo69893();
void testFdo70807();
void testImportRTF();
@@ -106,6 +107,7 @@ public:
CPPUNIT_TEST_SUITE(SwUiWriterTest);
CPPUNIT_TEST(testReplaceForward);
CPPUNIT_TEST(testReplaceBackward);
+ CPPUNIT_TEST(testRedlineFrame);
CPPUNIT_TEST(testFdo69893);
CPPUNIT_TEST(testFdo70807);
CPPUNIT_TEST(testImportRTF);
@@ -194,6 +196,31 @@ void SwUiWriterTest::testReplaceForward()
CPPUNIT_ASSERT_EQUAL(ORIGINAL_REPLACE_CONTENT, pTextNode->GetText());
}
+void SwUiWriterTest::testRedlineFrame()
+{
+ SwDoc * pDoc(createDoc("redlineFrame.fodt"));
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+
+ uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
+ // there is exactly one frame
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDrawPage->getCount());
+
+ sal_uInt16 nMode = pWrtShell->GetRedlineMode();
+ CPPUNIT_ASSERT(nMode & nsRedlineMode_t::REDLINE_SHOW_DELETE);
+
+ // hide delete redlines
+ pWrtShell->SetRedlineMode(nMode & ~nsRedlineMode_t::REDLINE_SHOW_DELETE);
+
+ // there is still exactly one frame
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDrawPage->getCount());
+
+ pWrtShell->SetRedlineMode(nMode); // show again
+
+ // there is still exactly one frame
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDrawPage->getCount());
+}
+
void SwUiWriterTest::testFdo75110()
{
SwDoc* pDoc = createDoc("fdo75110.odt");
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index c6c69f3..1f387f4 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -1584,7 +1584,7 @@ DocumentContentOperationsManager::CopyRange( SwPaM& rPam, SwPosition& rPos, cons
bool bColumnSel = pDoc->IsClipBoard() && pDoc->IsColumnSelection();
// Catch if there's no copy to do
- if( !rPam.HasMark() || ( *pStt > *pEnd && !bColumnSel ) )
+ if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) )
return false;
// Prevent copying in Flys that are anchored in the area
@@ -3132,8 +3132,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
const SwPaM* pCopiedPaM,
const bool bMakeNewFrms,
const bool bDelRedlines,
- const bool bCopyFlyAtFly,
- const bool bMergedFirstNode ) const
+ const bool bCopyFlyAtFly ) const
{
SwDoc* pDest = rInsPos.GetNode().GetDoc();
@@ -3141,17 +3140,13 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
SwNodeIndex aSavePos( rInsPos, -1 );
bool bEndIsEqualEndPos = rInsPos == rRg.aEnd;
- SwNodeRange aRg( rRg );
- if ( bMergedFirstNode )
- aRg.aStart++;
- if ( aRg.aStart <= aRg.aEnd )
- m_rDoc.GetNodes()._CopyNodes( aRg, rInsPos, bMakeNewFrms, true );
- if ( !bMergedFirstNode )
- ++aSavePos;
- if ( bEndIsEqualEndPos )
+ m_rDoc.GetNodes()._CopyNodes( rRg, rInsPos, bMakeNewFrms, true );
+ ++aSavePos;
+ if( bEndIsEqualEndPos )
const_cast<SwNodeIndex&>(rRg.aEnd) = aSavePos;
aRedlRest.Restore();
+
#if OSL_DEBUG_LEVEL > 0
{
//JP 17.06.99: Bug 66973 - check count only if the selection is in
@@ -3165,9 +3160,9 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
!aTmpI.GetNode().IsEndNode() )
{
// If the range starts with a SwStartNode, it isn't copied
- sal_uInt16 offset = (aRg.aStart.GetNode().GetNodeType() != ND_STARTNODE) ? 1 : 0;
+ sal_uInt16 offset = (rRg.aStart.GetNode().GetNodeType() != ND_STARTNODE) ? 1 : 0;
OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
- aRg.aEnd.GetIndex() - aRg.aStart.GetIndex() - 1 + offset,
+ rRg.aEnd.GetIndex() - rRg.aStart.GetIndex() - 1 + offset,
"An insufficient number of nodes were copied!" );
}
}
@@ -3175,7 +3170,7 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
{
::sw::UndoGuard const undoGuard(pDest->GetIDocumentUndoRedo());
- CopyFlyInFlyImpl( rRg, nEndContentIndex, aSavePos, bCopyFlyAtFly, bMergedFirstNode );
+ CopyFlyInFlyImpl( rRg, nEndContentIndex, aSavePos, bCopyFlyAtFly );
}
SwNodeRange aCpyRange( aSavePos, rInsPos );
@@ -3201,8 +3196,7 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
const SwNodeRange& rRg,
const sal_Int32 nEndContentIndex,
const SwNodeIndex& rStartIdx,
- const bool bCopyFlyAtFly,
- const bool bMergedFirstNode ) const
+ const bool bCopyFlyAtFly ) const
{
// First collect all Flys, sort them according to their ordering number,
// and then only copy them. This maintains the ordering numbers (which are only
@@ -3335,8 +3329,6 @@ void DocumentContentOperationsManager::CopyFlyInFlyImpl(
++aIdx;
}
- if ( bMergedFirstNode )
- nAnchorTextNdNumInRange--;
if ( !bAnchorTextNdFound )
{
@@ -4105,7 +4097,7 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
SwPosition* pEnd = rPam.End();
// Catch when there's no copy to do.
- if( !rPam.HasMark() || ( *pStt > *pEnd && !bColumnSel ) ||
+ if( !rPam.HasMark() || ( *pStt >= *pEnd && !bColumnSel ) ||
//JP 29.6.2001: 88963 - dont copy if inspos is in region of start to end
//JP 15.11.2001: don't test inclusive the end, ever exclusive
( pDoc == &m_rDoc && *pStt <= rPos && rPos < *pEnd ))
@@ -4193,8 +4185,6 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
pNumRuleToPropagate = 0;
}
- bool bHandledStartNode = false;
-
// This do/while block is only there so that we can break out of it!
do {
if( pSttTextNd )
@@ -4202,8 +4192,6 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
// Don't copy the beginning completely?
if( !bCopyCollFormat || bColumnSel || pStt->nContent.GetIndex() )
{
- bHandledStartNode = true;
-
SwIndex aDestIdx( rPos.nContent );
bool bCopyOk = false;
if( !pDestTextNd )
@@ -4279,11 +4267,18 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
pEnd->nContent -= nCpyLen;
}
- if( bCopyCollFormat && bOneNode )
+ if( bOneNode )
{
- pSttTextNd->CopyCollFormat( *pDestTextNd );
- POP_NUMRULE_STATE
+ if (bCopyCollFormat)
+ {
+ pSttTextNd->CopyCollFormat( *pDestTextNd );
+ POP_NUMRULE_STATE
+ }
+
+ break;
}
+
+ aRg.aStart++;
}
}
else if( pDestTextNd )
@@ -4340,7 +4335,7 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
}
pDestTextNd = aInsPos.GetNode().GetTextNode();
- if( pEndTextNd && (!bOneNode || !bHandledStartNode) )
+ if (pEndTextNd)
{
SwIndex aDestIdx( rPos.nContent );
if( !pDestTextNd )
@@ -4384,7 +4379,7 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
if( bCopyAll || aRg.aStart != aRg.aEnd )
{
SfxItemSet aBrkSet( pDoc->GetAttrPool(), aBreakSetRange );
- if( !bOneNode && pSttTextNd && bCopyCollFormat && pDestTextNd->HasSwAttrSet() )
+ if (pSttTextNd && bCopyCollFormat && pDestTextNd->HasSwAttrSet())
{
aBrkSet.Put( *pDestTextNd->GetpSwAttrSet() );
if( SfxItemState::SET == aBrkSet.GetItemState( RES_BREAK, false ) )
@@ -4396,15 +4391,13 @@ bool DocumentContentOperationsManager::CopyImpl( SwPaM& rPam, SwPosition& rPos,
if( aInsPos == pEnd->nNode )
{
SwNodeIndex aSaveIdx( aInsPos, -1 );
- CopyWithFlyInFly( aRg, 0, aInsPos, &rPam, bMakeNewFrms,
- false, false, bHandledStartNode );
+ CopyWithFlyInFly( aRg, 0,aInsPos, &rPam, bMakeNewFrms, false );
++aSaveIdx;
pEnd->nNode = aSaveIdx;
pEnd->nContent.Assign( aSaveIdx.GetNode().GetTextNode(), 0 );
}
else
- CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, &rPam,
- bMakeNewFrms, false, false, bHandledStartNode );
+ CopyWithFlyInFly( aRg, pEnd->nContent.GetIndex(), aInsPos, &rPam, bMakeNewFrms, false );
bCopyBookmarks = false;
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 3f60d4e..7a903af 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -896,6 +896,7 @@ SwNodeIndex SwDoc::AppendDoc(const SwDoc& rSource, sal_uInt16 const nStartPageNu
SwPageDesc *const pTargetPageDesc, bool const bDeletePrevious, int pageOffset)
{
// GetEndOfExtras + 1 = StartOfContent == no content node!
+ // this ensures, that we have at least two nodes in the SwPaM.
// @see IDocumentContentOperations::CopyRange
SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 1 );
SwNodeIndex aSourceEndIdx( rSource.GetNodes().GetEndOfContent(), -1 );
diff --git a/sw/source/core/inc/DocumentContentOperationsManager.hxx b/sw/source/core/inc/DocumentContentOperationsManager.hxx
index 24974d1..44560fc 100644
--- a/sw/source/core/inc/DocumentContentOperationsManager.hxx
+++ b/sw/source/core/inc/DocumentContentOperationsManager.hxx
@@ -106,13 +106,11 @@ public:
const SwPaM* pCopiedPaM = NULL,
bool bMakeNewFrms = true,
bool bDelRedlines = true,
- bool bCopyFlyAtFly = false,
- const bool bMergedFirstNode = false ) const;
+ bool bCopyFlyAtFly = false ) const;
void CopyFlyInFlyImpl( const SwNodeRange& rRg,
const sal_Int32 nEndContentIndex,
const SwNodeIndex& rStartIdx,
- const bool bCopyFlyAtFly = false,
- const bool bMergedFirstNode = false ) const;
+ const bool bCopyFlyAtFly = false ) const;
/// Parameters for _Rst and lcl_SetTextFormatColl
//originallyfrom docfmt.cxx
commit 58abf71db71628fdb1cb8e70e8aa55f3f790ce3c
Author: Lubosz Sarnecki <lubosz.sarnecki at collabora.co.uk>
Date: Fri Sep 11 14:48:26 2015 +0200
tdf#94031 - slideshow: bind correct GL context for prepareEnvironment
Change-Id: Ib139e81f770531f7d808764dd3a77c7ac8d6fa3c
Signed-off-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx
index f468f87..db50970 100644
--- a/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx
+++ b/slideshow/source/engine/OGLTrans/generic/OGLTrans_TransitionerImpl.cxx
@@ -1185,6 +1185,7 @@ void OGLTransitionerImpl::GLInitSlides()
TimerContext aTimerContext("texture creation");
#endif
+ mpContext->makeCurrent();
prepareEnvironment();
const OGLFormat* pFormat = NULL;
commit a023cd66e74a96aec52d891508cd757292513401
Author: Regina Henschel <rb.henschel at t-online.de>
Date: Sat Aug 29 18:05:33 2015 +0200
tdf#93634 repair getDisplayDirectory for Windows filepicker
Change wrong PROP_FILENAME to correct PROP_DIRECTORY
Change-Id: Iab2e16c486f487699e1574ed508539d95884bf9b
Reviewed-on: https://gerrit.libreoffice.org/18127
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
(cherry picked from commit 8775593bcc543b3d7021e20736f42fa13035870d)
Reviewed-on: https://gerrit.libreoffice.org/18373
diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.cxx b/fpicker/source/win32/filepicker/VistaFilePicker.cxx
index 4774857..4b2de9d 100644
--- a/fpicker/source/win32/filepicker/VistaFilePicker.cxx
+++ b/fpicker/source/win32/filepicker/VistaFilePicker.cxx
@@ -246,7 +246,7 @@ OUString SAL_CALL VistaFilePicker::getDisplayDirectory()
RequestRef rRequest(new Request());
rRequest->setRequest (VistaFilePickerImpl::E_GET_DIRECTORY);
m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::BLOCKED);
- const OUString sDirectory = rRequest->getArgumentOrDefault(PROP_FILENAME, OUString());
+ const OUString sDirectory = rRequest->getArgumentOrDefault(PROP_DIRECTORY, OUString());
return sDirectory;
}
commit fa26aa0bdb0c93c2a3e5d0bfc879e9185a6e910e
Author: Eike Rathke <erack at redhat.com>
Date: Thu Sep 10 15:52:21 2015 +0200
Resolves: tdf#92995 do not delete caption objects that are held by Undo
Drag&Drop Undo is a special case of ownership..
Change-Id: I2fe7769c4d84efe09d432335d5d8e72d506bf7a1
(cherry picked from commit 44f34c1163882c2e3086282374fee9cd55ee211f)
Reviewed-on: https://gerrit.libreoffice.org/18470
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 9d96793..fd27c10 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -583,7 +583,7 @@ public:
ScPostIt* GetCellNote( SCROW nRow );
const ScPostIt* GetCellNote( SCROW nRow ) const;
const ScPostIt* GetCellNote( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
- void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
+ void DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership );
bool HasCellNotes() const;
void SetCellNote( SCROW nRow, ScPostIt* pNote);
bool IsNotesEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index b95faf5..397808e 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -197,10 +197,11 @@ const InsertDeleteFlags IDF_OUTLINE = InsertDeleteFlags::fromInt(0x0800); //
const InsertDeleteFlags IDF_NOCAPTIONS = InsertDeleteFlags::fromInt(0x0200); /// Internal use only (undo etc.): do not copy/delete caption objects of cell notes.
const InsertDeleteFlags IDF_ADDNOTES = InsertDeleteFlags::fromInt(0x0400); /// Internal use only (copy from clip): do not delete existing cell contents when pasting notes.
const InsertDeleteFlags IDF_SPECIAL_BOOLEAN = InsertDeleteFlags::fromInt(0x1000);
+const InsertDeleteFlags IDF_FORGETCAPTIONS = InsertDeleteFlags::fromInt(0x2000); /// Internal use only (d&d undo): do not delete caption objects of cell notes.
const InsertDeleteFlags IDF_ATTRIB = IDF_HARDATTR | IDF_STYLES;
const InsertDeleteFlags IDF_CONTENTS = IDF_VALUE | IDF_DATETIME | IDF_STRING | IDF_NOTE | IDF_FORMULA | IDF_OUTLINE;
const InsertDeleteFlags IDF_ALL = IDF_CONTENTS | IDF_ATTRIB | IDF_OBJECTS;
-const InsertDeleteFlags IDF_ALL_USED_BITS = IDF_ALL | IDF_EDITATTR | IDF_NOCAPTIONS | IDF_ADDNOTES | IDF_SPECIAL_BOOLEAN;
+const InsertDeleteFlags IDF_ALL_USED_BITS = IDF_ALL | IDF_EDITATTR | IDF_NOCAPTIONS | IDF_ADDNOTES | IDF_SPECIAL_BOOLEAN | IDF_FORGETCAPTIONS;
inline InsertDeleteFlags operator~ (const InsertDeleteFlags& rhs)
{
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index bb6a37d..8929ecd 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1816,8 +1816,27 @@ void ScColumn::SetCellNote(SCROW nRow, ScPostIt* pNote)
maCellNotes.set(nRow, pNote);
}
-void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 )
+namespace {
+class ForgetCellNoteCaptionsHandler
+{
+
+public:
+ ForgetCellNoteCaptionsHandler() {}
+
+ void operator() ( size_t /*nRow*/, ScPostIt* p )
+ {
+ p->ForgetCaption();
+ }
+};
+}
+
+void ScColumn::DeleteCellNotes( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2, bool bForgetCaptionOwnership )
{
+ if (bForgetCaptionOwnership)
+ {
+ ForgetCellNoteCaptionsHandler aFunc;
+ sc::ParseNote(maCellNotes.begin(), maCellNotes, nRow1, nRow2, aFunc);
+ }
rBlockPos.miCellNotePos =
maCellNotes.set_empty(rBlockPos.miCellNotePos, nRow1, nRow2);
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 40ec240..757c3e3 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -684,7 +684,10 @@ void ScColumn::DeleteArea(
}
if (nDelFlag & IDF_NOTE)
- DeleteCellNotes(aBlockPos, nStartRow, nEndRow);
+ {
+ bool bForgetCaptionOwnership = ((nDelFlag & IDF_FORGETCAPTIONS) != IDF_NONE);
+ DeleteCellNotes(aBlockPos, nStartRow, nEndRow, bForgetCaptionOwnership);
+ }
if ( nDelFlag & IDF_EDITATTR )
{
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 46b59c0..ac09eac 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -114,7 +114,7 @@ void ScColumn::DeleteBeforeCopyFromClip(
}
if (nDelFlag & IDF_NOTE)
- DeleteCellNotes(aBlockPos, nRow1, nRow2);
+ DeleteCellNotes(aBlockPos, nRow1, nRow2, false);
if (nDelFlag & IDF_EDITATTR)
RemoveEditAttribs(nRow1, nRow2);
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 2154466..9cecfa0 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -1239,7 +1239,14 @@ void ScUndoDragDrop::DoUndo( ScRange aRange )
// do not undo objects and note captions, they are handled via drawing undo
InsertDeleteFlags nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
- rDoc.DeleteAreaTab( aRange, nUndoFlags );
+ // Additionally discard/forget caption ownership during deletion, as
+ // Drag&Drop is a special case in that the Undo holds captions of the
+ // transfered target range, which would get deleted and
+ // SdrGroupUndo::Undo() would attempt to access invalidated captions and
+ // crash, tdf#92995
+ InsertDeleteFlags nDelFlags = nUndoFlags | IDF_FORGETCAPTIONS;
+
+ rDoc.DeleteAreaTab( aRange, nDelFlags );
pRefUndoDoc->CopyToDocument( aRange, nUndoFlags, false, &rDoc );
if ( rDoc.HasAttrib( aRange, HASATTR_MERGED ) )
rDoc.ExtendMerge( aRange, true );
commit 2d3dbdcd14dbca9e5827cb44e453cc45842dff14
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Thu Sep 10 11:40:33 2015 +0200
windows opengl: mpProgram seen as 0
in JunitTest_sc_unoapi_3.
Change-Id: Ic7e32979f31a3376b67eb3bef59373632461e39f
(cherry picked from commit 0e682d47a792497211d33779312ca2cad9874ffb)
Reviewed-on: https://gerrit.libreoffice.org/18490
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 10b5c35..85c3a3a 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -773,6 +773,12 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi
aVertices[j+1] = GLfloat(rPt.getY());
}
+ if (!mpProgram)
+ {
+ SAL_WARN("vcl.opengl", "OpenGLSalGraphicsImpl::DrawTrapezoid: mpProgram is 0");
+ return;
+ }
+
ApplyProgramMatrices();
mpProgram->SetVertices( &aVertices[0] );
glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
commit 1b381370b026f62397dc2d41ddcecf9d6523e044
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Mon Sep 7 08:42:46 2015 +0200
tdf#83227 oox: reuse RelId in DML/VML export for the same graphic
So that large images are written only once to the ZIP container when
they are exported using both markups. This affects drawinglayer images,
the Writer ones are handled directly in sw and were already
deduplicated.
(cherry picked from commit b484e9814c66d8d51cea974390963a6944bc9d73)
Conflicts:
oox/source/export/drawingml.cxx
Change-Id: Iff7c769329b42939833056b727b070f6a60da5e3
Reviewed-on: https://gerrit.libreoffice.org/18491
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 3b9d847..fff1e2c 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -74,6 +74,10 @@ public:
virtual void WriteOutliner(const OutlinerParaObject& rParaObj) = 0;
/// Write the contents of the textbox that is associated to this shape.
virtual void WriteTextBox(css::uno::Reference<css::drawing::XShape> xShape) = 0;
+ /// Look up the RelId of a graphic based on its checksum.
+ virtual OUString FindRelId(BitmapChecksum nChecksum) = 0;
+ /// Store the RelId of a graphic based on its checksum.
+ virtual void CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId) = 0;
protected:
DMLTextExport() {}
virtual ~DMLTextExport() {}
diff --git a/include/oox/export/vmlexport.hxx b/include/oox/export/vmlexport.hxx
index a87ed16..922b019 100644
--- a/include/oox/export/vmlexport.hxx
+++ b/include/oox/export/vmlexport.hxx
@@ -39,6 +39,10 @@ public:
virtual oox::drawingml::DrawingML& GetDrawingML() = 0;
/// Write the contents of the textbox that is associated to this shape in VML format.
virtual void WriteVMLTextBox(css::uno::Reference<css::drawing::XShape> xShape) = 0;
+ /// Look up the RelId of a graphic based on its checksum.
+ virtual OUString FindRelId(BitmapChecksum nChecksum) = 0;
+ /// Store the RelId of a graphic based on its checksum.
+ virtual void CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId) = 0;
protected:
VMLTextExport() {}
virtual ~VMLTextExport() {}
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index da38474..878276a 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -769,7 +769,7 @@ void DrawingML::WriteOutline( Reference<XPropertySet> rXPropSet )
mpFS->endElementNS( XML_a, XML_ln );
}
-OUString DrawingML::WriteImage( const OUString& rURL, bool bRelPathToMedia )
+bool lcl_URLToGraphic(const OUString& rURL, Graphic& rGraphic)
{
OString aURLBS(OUStringToOString(rURL, RTL_TEXTENCODING_UTF8));
@@ -778,9 +778,18 @@ OUString DrawingML::WriteImage( const OUString& rURL, bool bRelPathToMedia )
if ( index != -1 )
{
- DBG(fprintf (stderr, "begin: %ld %s\n", long( sizeof( aURLBegin ) ), USS( rURL ) + RTL_CONSTASCII_LENGTH( aURLBegin ) ));
- Graphic aGraphic = GraphicObject( aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin)) ).GetTransformedGraphic ();
+ rGraphic = GraphicObject(aURLBS.copy(RTL_CONSTASCII_LENGTH(aURLBegin))).GetTransformedGraphic();
+ return true;
+ }
+
+ return false;
+}
+OUString DrawingML::WriteImage( const OUString& rURL, bool bRelPathToMedia )
+{
+ Graphic aGraphic;
+ if (lcl_URLToGraphic(rURL, aGraphic))
+ {
return WriteImage( aGraphic , bRelPathToMedia );
}
else
@@ -930,7 +939,23 @@ OUString DrawingML::WriteImage( const Graphic& rGraphic , bool bRelPathToMedia )
OUString DrawingML::WriteBlip( Reference< XPropertySet > rXPropSet, const OUString& rURL, bool bRelPathToMedia, const Graphic *pGraphic )
{
- OUString sRelId = pGraphic ? WriteImage( *pGraphic, bRelPathToMedia ) : WriteImage( rURL, bRelPathToMedia );
+ OUString sRelId;
+ BitmapChecksum nChecksum = 0;
+ if (!rURL.isEmpty() && mpTextExport)
+ {
+ Graphic aGraphic;
+ if (lcl_URLToGraphic(rURL, aGraphic))
+ {
+ nChecksum = aGraphic.GetChecksum();
+ sRelId = mpTextExport->FindRelId(nChecksum);
+ }
+ }
+ if (sRelId.isEmpty())
+ {
+ sRelId = pGraphic ? WriteImage( *pGraphic, bRelPathToMedia ) : WriteImage( rURL, bRelPathToMedia );
+ if (!rURL.isEmpty() && mpTextExport)
+ mpTextExport->CacheRelId(nChecksum, sRelId);
+ }
sal_Int16 nBright = 0;
sal_Int32 nContrast = 0;
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index 7161a2f..d90ff82 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -583,7 +583,14 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect
aStream.Seek(0);
Graphic aGraphic;
GraphicConverter::Import(aStream, aGraphic);
- OUString aImageId = m_pTextExport->GetDrawingML().WriteImage( aGraphic );
+
+ BitmapChecksum nChecksum = aGraphic.GetChecksum();
+ OUString aImageId = m_pTextExport->FindRelId(nChecksum);
+ if (aImageId.isEmpty())
+ {
+ aImageId = m_pTextExport->GetDrawingML().WriteImage( aGraphic );
+ m_pTextExport->CacheRelId(nChecksum, aImageId);
+ }
pAttrList->add(FSNS(XML_r, XML_id), OUStringToOString(aImageId, RTL_TEXTENCODING_UTF8));
imageData = true;
}
diff --git a/sw/qa/extras/ooxmlexport/data/tdf83227.docx b/sw/qa/extras/ooxmlexport/data/tdf83227.docx
new file mode 100644
index 0000000..bca19a9
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf83227.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
index 3727353..3a273f3 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport4.cxx
@@ -803,6 +803,18 @@ DECLARE_OOXMLEXPORT_TEST(testSimpleSdts, "simple-sdts.docx")
}
+DECLARE_OOXMLEXPORT_TEST(testTdf83227, "tdf83227.docx")
+{
+ // Bug document contains a rotated image, which is handled as a draw shape (not as a Writer image) on export.
+ if (!mbExported)
+ return;
+
+ uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL());
+ CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("word/media/image1.png")));
+ // This was also true, image was written twice.
+ CPPUNIT_ASSERT_EQUAL(false, bool(xNameAccess->hasByName("word/media/image2.png")));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 022ee0b..00aeb75 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -4074,6 +4074,22 @@ void DocxAttributeOutput::WriteSrcRect(const SdrObject* pSdrObj )
void DocxAttributeOutput::ClearRelIdCache()
{
m_aRelIdCache.clear();
+ m_aSdrRelIdCache.clear();
+}
+
+OUString DocxAttributeOutput::FindRelId(BitmapChecksum nChecksum)
+{
+ OUString aRet;
+
+ if (m_aSdrRelIdCache.find(nChecksum) != m_aSdrRelIdCache.end())
+ aRet = m_aSdrRelIdCache[nChecksum];
+
+ return aRet;
+}
+
+void DocxAttributeOutput::CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId)
+{
+ m_aSdrRelIdCache[nChecksum] = rRelId;
}
void DocxAttributeOutput::FlyFrameGraphic( const SwGrfNode* pGrfNode, const Size& rSize, const SwFlyFrameFormat* pOLEFrameFormat, SwOLENode* pOLENode, const SdrObject* pSdrObj )
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index b7ce59d..4dbc29f 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -906,6 +906,8 @@ private:
/// RelId <-> Graphic* cache, so that in case of alternate content, the same graphic only gets written once.
std::map<const Graphic*, OString> m_aRelIdCache;
+ /// RelId <-> BitmapChecksum cache, similar to m_aRelIdCache, but used for non-Writer graphics, handled in oox.
+ std::map<BitmapChecksum, OUString> m_aSdrRelIdCache;
/// members to control the existence of grabbagged SDT properties in the paragraph
sal_Int32 m_nParagraphSdtPrToken;
@@ -963,6 +965,8 @@ public:
virtual void WriteVMLTextBox(css::uno::Reference<css::drawing::XShape> xShape) SAL_OVERRIDE;
/// DMLTextExport
virtual void WriteTextBox(css::uno::Reference<css::drawing::XShape> xShape) SAL_OVERRIDE;
+ virtual OUString FindRelId(BitmapChecksum nChecksum) SAL_OVERRIDE;
+ virtual void CacheRelId(BitmapChecksum nChecksum, const OUString& rRelId) SAL_OVERRIDE;
virtual oox::drawingml::DrawingML& GetDrawingML() SAL_OVERRIDE;
void BulletDefinition(int nId, const Graphic& rGraphic, Size aSize) SAL_OVERRIDE;
commit b7ffafe77d95c72402bdac0328ca3bfcb7444067
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Thu Sep 10 11:39:44 2015 +0200
windows opengl: mpCurrentProgram seen as 0
in JunitTest_sc_unoapi_3.
Change-Id: Ibe12a31c1158f782bd7df115171b07e1843d025c
(cherry picked from commit 57fc41adc9292f8980bb8bbbb0d7983310fe6fe3)
Reviewed-on: https://gerrit.libreoffice.org/18489
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index d1df28b..ea9664e 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -1751,6 +1751,13 @@ OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const O
return pProgram;
mpCurrentProgram = pProgram;
+
+ if (!mpCurrentProgram)
+ {
+ SAL_WARN("vcl.opengl", "OpenGLContext::UseProgram: mpCurrentProgram is 0");
+ return 0;
+ }
+
mpCurrentProgram->Use();
return mpCurrentProgram;
commit 8488315d565a061749546df27d2507d0927a8993
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Fri Sep 4 09:16:44 2015 +0200
Related: tdf#92982 vcl rendercontext: optimize non-buffered paint of Cursor
Change-Id: Ic8065d4f656d42f1e2e7d8b4c602010fa0ae2d34
Reviewed-on: https://gerrit.libreoffice.org/18343
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
Tested-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/vcl/source/window/cursor.cxx b/vcl/source/window/cursor.cxx
index 1968a26..945789a 100644
--- a/vcl/source/window/cursor.cxx
+++ b/vcl/source/window/cursor.cxx
@@ -44,8 +44,11 @@ struct ImplCursorData
static void ImplCursorInvert( ImplCursorData* pData )
{
vcl::Window* pWindow = pData->mpWindow;
- PaintBufferGuard aGuard(pWindow->ImplGetWindowImpl()->mpFrameData, pWindow);
- vcl::RenderContext* pRenderContext = aGuard.GetRenderContext();
+ std::unique_ptr<PaintBufferGuard> pGuard;
+ const bool bDoubleBuffering = pWindow->SupportsDoubleBuffering();
+ if (bDoubleBuffering)
+ pGuard.reset(new PaintBufferGuard(pWindow->ImplGetWindowImpl()->mpFrameData, pWindow));
+ vcl::RenderContext* pRenderContext = bDoubleBuffering ? pGuard->GetRenderContext() : pWindow;
Rectangle aPaintRect;
bool bMapMode = pRenderContext->IsMapModeEnabled();
pRenderContext->EnableMapMode( false );
@@ -111,16 +114,19 @@ static void ImplCursorInvert( ImplCursorData* pData )
if ( pData->mnOrientation )
aPoly.Rotate( pData->maPixRotOff, pData->mnOrientation );
pRenderContext->Invert( aPoly, nInvertStyle );
- aPaintRect = aPoly.GetBoundRect();
+ if (bDoubleBuffering)
+ aPaintRect = aPoly.GetBoundRect();
}
}
else
{
pRenderContext->Invert( aRect, nInvertStyle );
- aPaintRect = aRect;
+ if (bDoubleBuffering)
+ aPaintRect = aRect;
}
pRenderContext->EnableMapMode( bMapMode );
- aGuard.SetPaintRect(pRenderContext->PixelToLogic(aPaintRect));
+ if (bDoubleBuffering)
+ pGuard->SetPaintRect(pRenderContext->PixelToLogic(aPaintRect));
}
void vcl::Cursor::ImplDraw()
commit e576227d71788409110108281340005638f78bf1
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date: Thu Sep 10 17:25:27 2015 +0200
windows opengl: make sure mpLastContext is indeed the current context
There were two problems here:
1) The OpenGLContext ctor registered the instance on the list of
contexts, but platform-specific call (e.g. wglMakeCurrent()) was only
made later. Add a registerAsCurrent() member function that helps
ensuring that the last item in the context list is indeed the current
context.
2) OpenGLContext::prepareForYield() is called without the solar mutex
being locked, but it still assumes that the last context in the context
list is the thread's current context, which may not be true. The result
is that during JunitTest_sd_unoapi, we end up in a situation like:
debug:4640:5240: OpenGLContext::registerAsCurrent: wglGetCurrentContext() is 00010001, pSVData->maGDIData.mpLastContext is 00FA65F8
debug:4640:7944: OpenGLContext::registerAsCurrent: wglGetCurrentContext() is 000D0003, pSVData->maGDIData.mpLastContext is 00FA6C70
debug:4640:5240: OpenGLContext::prepareForYield: start, wglGetCurrentContext() is 00010001, pSVData->maGDIData.mpLastContext is 00FA6C70
I.e. one thread registers as current, an other registers as current, too (while
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list