Re: Pasting in Writer or how to create a SwDoc deep copy?

2014-06-26 Thread Miklos Vajna
Hi Jan-Marek,

On Wed, Jun 25, 2014 at 01:09:01PM +0200, Jan-Marek Glogowski 
glo...@fbihome.de wrote:
 My best idea is to use
 
 SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), *1* );

Are you sure such an explicit offset is required here? I'm thinking
about special situations like when the document starts with a table, if
you want to paste that into a new document, you probably want to have
the selection start at the first content node of the document, so no
static offset will work here.

I'm thinking about something like:

SwNodeIndex aNodeIndex rSource.GetNodes().GetEndOfAutotext();
SwCntntNode* pStart = rSource.GetNodes().GoNext(aNodeIndex);

Any kind of explicit offset sounds a bit scary to me.

 SwPaM aPara( document content start );
 this-DelFullPara(aPara);

But you're not really trying to delete the paragraph content, just join
the two, right? SwDoc::DeleteAndJoin() might be useful to do that.

Miklos


signature.asc
Description: Digital signature
___
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice


Re: Pasting in Writer or how to create a SwDoc deep copy?

2014-06-26 Thread Jan-Marek Glogowski
Hi Miklos,

Am 26.06.2014 10:54, schrieb Miklos Vajna:
 On Wed, Jun 25, 2014 at 01:09:01PM +0200, Jan-Marek Glogowski 
 glo...@fbihome.de wrote:
 My best idea is to use

 SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), *1* );
 
 Are you sure such an explicit offset is required here? I'm thinking
 about special situations like when the document starts with a table, if
 you want to paste that into a new document, you probably want to have
 the selection start at the first content node of the document, so no
 static offset will work here.
 
 I'm thinking about something like:
 
 SwNodeIndex aNodeIndex rSource.GetNodes().GetEndOfAutotext();
 SwCntntNode* pStart = rSource.GetNodes().GoNext(aNodeIndex);
 
 Any kind of explicit offset sounds a bit scary to me.

Well the current code uses the explicit offset 2 in SwDoc::Paste and
SwFEShell::Paste, which ignores the first content node, which results in
losing the paragraph anchored Flys of the first paragraph of the document.

For a whole document paste, I want the whole document, including the
first node with the pagedesc. This is probably special case for Mail
Merge. I added a boolean to SwFEShell::Paste, so this really pastes the
whole document.

The only user of SwDoc::Paste is SwDoc::CreateCopy. I've merged the
SwDoc::Paste code into SwDoc::CreateCopy. SwDoc::Paste used the fixed
offset of 2 for the source document content offset - same for the target
insert.

 SwPaM aPara( document content start );
 this-DelFullPara(aPara);
 
 But you're not really trying to delete the paragraph content, just join
 the two, right? SwDoc::DeleteAndJoin() might be useful to do that.

No - I really tried to get rid of the whole page.

I pushed my current works for me changeset to
private/jmux/mailmerge-fixes. Would be happy, if I can get a review.

Thanks

Jan-Marek
___
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice


Pasting in Writer or how to create a SwDoc deep copy?

2014-06-25 Thread Jan-Marek Glogowski
Hi Writer devs and everybody interested,

after struggling for a week to come of with working code to create a
deep copy of an SwDoc, this morning I woke up and came to the
conclusion: everything works as expected from my understanding of Paste
in Writer.

So this is my attempt to dump my brain and hopefully get additional
ideas from other devs.

= The problem =

Currently SwDoc::CreateCopy works by creating a new SwDoc and copying
the content using SwDoc::Paste.

The content start point is selected by this call:

SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 2 );

AFAIK this selects the first node *after* the content start node. That
first page is supposed to be something like a start page / start
paragraph node. I don't know yet how to debug these SwNodes structure
effectively, so it's just a guess.

The actual paste operation is done using CopyRange, the content of first
copied paragraph is merged into the first target paragraph. This almost
works as expected, except that it loses all first paragraph anchored
Flys. This problem exists since ages; it also happens with OOo 3.2.1,
the current office suite version we're using in Munich.

You can easily check this by mail merging (MM) an empty document with a
single paragraph anchored fly, like a draw line with two datasets. The
first document contains the line and an additional / two paragraph(s),
with the line anchored at the 2nd paragraph, all other pages just
contain a single paragraph and no line.
This is correct, as MM handles the first page differently - something
I would like to get rid of.

Even funnier things happen, if the MM document is a single page with a
complex header and a page anchored fly:
* The copied document has two pages!
* The first page has the default header.
* The second page contains the original header.
* The page anchored fly moves to the first / empty page.
* The first paragraph anchored fly on the second page is gone (is a
section a fly - well the first section is gone too).
* The first paragraph anchored draw object moves somewhere else

Especially the last bullet point is interesting. The offsets of the
paragraph anchor draw object changes indefinitly. For my test document
this is just broken on the 2nd merged document, but otherwise broken in
all working copies  (also see
https://bugs.freedesktop.org/show_bug.cgi?id=80395 - not my bug, but I
guess the same problem).

Caolán pulled https://gerrit.libreoffice.org/#/c/9860 into master. This
this saves multiple documents in various MM states for the first three
merged documents, when using a dbgutil build.

The first WorkDoc is always after the CreateCopy, the second WorkDoc
right before SwFEShell::Paste.

And BTW:

  SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames )

has the same problem, as it also uses the above code to select the
starting node for the copy. There is a partial fix  for my copy
problem, if the MM document has headers:
  https://gerrit.libreoffice.org/#/c/9862/1

But well - it crashs for me with documents without headers - just saw
that after the gerrit push for review.

= My attempts to fix it =

My best idea is to use

SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), *1* );

in the case of pasting a whole document. This appends a new paragraph at
the position, instead of merging the first paragraph from the source
into the first paragraph of the target.

So for the CreateCopy case, this would leave me with deleting the
first paragraph.

I tried

1.
SwNodeIndex aTargetIdx( pRet-GetNodes().GetEndOfExtras(), 2 );
pRet-GetNodes().Delete( aTargetIdx, 1 );

and a variant of

2.
SwPaM aPara( document content start );
this-DelFullPara(aPara);

3.
and a variant of SwWrtShell::SelAll and SwFEShell::Paste,
which currently just segfaults,

=
but couldn't come up with working code. I would like to prevent to write
just an other paste function for the CreateCopy special case.

AFAIK this is not usable for SwFEShell::Paste, as one expects the
paragraph merge for clipboard content.
OTOH I don't know, where the code is actually used - copy and paste in
the GUI seems not affected. But copy multiple paragraphs with anchored
lines didn't always include that line - with or without the change from
2 = 1.

So from my POV both paste should at least copy all the skipped,
paragraph anchored flys of the first node in the SwFEShell::Paste case
(don't know yet how).

And probably the suggested change to SwDoc::Paste should also be applied
to SwFEShell::Paste.

Thanks for your input,

Jan-Marek
___
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice