X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FCutAndPaste.C;h=d5306afd315e153d959a6ce4765c403075a11cff;hb=98c966c64594611e469313314abd1e59524adb4a;hp=428c9c9980c6c5af95be30e56d4bef27e902aeee;hpb=d32d0cbb9552186e0d69ee2320baf2570402fc72;p=lyx.git diff --git a/src/CutAndPaste.C b/src/CutAndPaste.C index 428c9c9980..d5306afd31 100644 --- a/src/CutAndPaste.C +++ b/src/CutAndPaste.C @@ -1,28 +1,35 @@ /* This file is part of * ====================================================== - * + * * LyX, The Document Processor - * + * * Copyright 1995-2001 The LyX Team. * * ====================================================== */ #include +#ifdef __GNUG__ +#pragma implementation +#endif + #include "CutAndPaste.h" +//#include "debug.h" #include "BufferView.h" #include "buffer.h" #include "paragraph.h" -#include "insets/inseterror.h" -#include "lyx_gui_misc.h" +#include "ParagraphParameters.h" +#include "lyxtext.h" #include "lyxcursor.h" #include "gettext.h" +#include "iterators.h" +#include "lyxtextclasslist.h" -#ifdef __GNUG__ -#pragma implementation -#endif +#include "insets/inseterror.h" using std::pair; +using lyx::pos_type; +using lyx::textclass_type; extern BufferView * current_view; @@ -48,7 +55,7 @@ extern BufferView * current_view; namespace { Paragraph * buf = 0; -LyXTextClassList::size_type textclass = 0; +textclass_type textclass = 0; // for now here this should be in another Cut&Paste Class! // Jürgen, I moved this out of CutAndPaste since it does not operate on any @@ -58,9 +65,9 @@ void DeleteBuffer() { if (!buf) return; - + Paragraph * tmppar; - + while (buf) { tmppar = buf; buf = buf->next(); @@ -73,28 +80,33 @@ void DeleteBuffer() bool CutAndPaste::cutSelection(Paragraph * startpar, Paragraph ** endpar, - int start, int & end, char tc, bool doclear) + int start, int & end, char tc, bool doclear, + bool realcut) { if (!startpar || (start > startpar->size())) return false; - - DeleteBuffer(); - + + if (realcut) + DeleteBuffer(); + textclass = tc; - - if (!(*endpar) || - startpar == (*endpar)) { + + if (!(*endpar) || startpar == (*endpar)) { // only within one paragraph - buf = new Paragraph; - Paragraph::size_type i = start; + if (realcut) { + buf = new Paragraph; + buf->layout(startpar->layout()); + } + pos_type i = start; if (end > startpar->size()) end = startpar->size(); for (; i < end; ++i) { - startpar->copyIntoMinibuffer(*current_view->buffer(), - start); + if (realcut) + startpar->copyIntoMinibuffer(*current_view->buffer(), + start); startpar->erase(start); - - buf->insertFromMinibuffer(buf->size()); + if (realcut) + buf->insertFromMinibuffer(buf->size()); } end = start - 1; } else { @@ -103,24 +115,31 @@ bool CutAndPaste::cutSelection(Paragraph * startpar, Paragraph ** endpar, end); *endpar = (*endpar)->next(); end = 0; - + startpar->breakParagraphConservative(current_view->buffer()->params, start); - + // store the selection - buf = startpar->next(); - - buf->previous(0); + if (realcut) { + buf = startpar->next(); + buf->previous(0); + } else { + startpar->next()->previous(0); + } (*endpar)->previous()->next(0); - + // cut the selection startpar->next(*endpar); - + (*endpar)->previous(startpar); - + // the cut selection should begin with standard layout - buf->clear(); - + if (realcut) { + buf->params().clear(); + buf->bibkey = 0; + buf->layout(textclasslist[current_view->buffer()->params.textclass].defaultLayoutName()); + } + // paste the paragraphs again, if possible if (doclear) startpar->next()->stripLeadingSpaces(textclass); @@ -129,6 +148,12 @@ bool CutAndPaste::cutSelection(Paragraph * startpar, Paragraph ** endpar, startpar->pasteParagraph(current_view->buffer()->params); (*endpar) = startpar; // this because endpar gets deleted here! } + // this paragraph's are of noone's owner! + Paragraph * p = buf; + while (p) { + p->setInsetOwner(0); + p = p->next(); + } } return true; } @@ -139,16 +164,16 @@ bool CutAndPaste::copySelection(Paragraph * startpar, Paragraph * endpar, { if (!startpar || (start > startpar->size())) return false; - + DeleteBuffer(); - + textclass = tc; - - if (!endpar || - startpar == endpar) { + + if (!endpar || startpar == endpar) { // only within one paragraph buf = new Paragraph; - Paragraph::size_type i = start; + buf->layout(startpar->layout()); + pos_type i = start; if (end > startpar->size()) end = startpar->size(); for (; i < end; ++i) { @@ -159,51 +184,58 @@ bool CutAndPaste::copySelection(Paragraph * startpar, Paragraph * endpar, // copy more than one paragraph // clone the paragraphs within the selection Paragraph * tmppar = startpar; - buf = new Paragraph(*tmppar); + buf = new Paragraph(*tmppar, false); Paragraph * tmppar2 = buf; - + while (tmppar != endpar && tmppar->next()) { tmppar = tmppar->next(); - tmppar2->next(new Paragraph(*tmppar)); + tmppar2->next(new Paragraph(*tmppar, false)); tmppar2->next()->previous(tmppar2); tmppar2 = tmppar2->next(); } tmppar2->next(0); - + // the buf paragraph is too big - Paragraph::size_type tmpi2 = start; + pos_type tmpi2 = start; for (; tmpi2; --tmpi2) buf->erase(0); - + // now tmppar 2 is too big, delete all after end tmpi2 = end; while (tmppar2->size() > tmpi2) { tmppar2->erase(tmppar2->size() - 1); } + // this paragraph's are of noone's owner! + tmppar = buf; + while (tmppar) { + tmppar->setInsetOwner(0); + tmppar = tmppar->next(); + } } return true; } bool CutAndPaste::pasteSelection(Paragraph ** par, Paragraph ** endpar, - int & pos, char tc) + int & pos, char tc) { if (!checkPastePossible(*par)) return false; - + if (pos > (*par)->size()) pos = (*par)->size(); - + +#if 0 // Paragraph * tmpbuf; Paragraph * tmppar = *par; int tmppos = pos; - + // There are two cases: cutbuffer only one paragraph or many if (!buf->next()) { // only within a paragraph - Paragraph * tmpbuf = new Paragraph(*buf); - + Paragraph * tmpbuf = new Paragraph(*buf, false); + // Some provisions should be done here for checking // if we are inserting at the beginning of a // paragraph. If there are a space at the beginning @@ -227,35 +259,86 @@ bool CutAndPaste::pasteSelection(Paragraph ** par, Paragraph ** endpar, buf = tmpbuf; *endpar = tmppar->next(); pos = tmppos; - } else { + } else +#endif + { // many paragraphs - + // make a copy of the simple cut_buffer Paragraph * tmpbuf = buf; - Paragraph * simple_cut_clone = new Paragraph(*tmpbuf); + Paragraph * simple_cut_clone = new Paragraph(*tmpbuf, false); Paragraph * tmpbuf2 = simple_cut_clone; - + while (tmpbuf->next()) { tmpbuf = tmpbuf->next(); - tmpbuf2->next(new Paragraph(*tmpbuf)); + tmpbuf2->next(new Paragraph(*tmpbuf, false)); tmpbuf2->next()->previous(tmpbuf2); tmpbuf2 = tmpbuf2->next(); } - + + // now remove all out of the buffer which is NOT allowed in the + // new environment and set also another font if that is required + tmpbuf = buf; + int depth_delta = (*par)->params().depth() - tmpbuf->params().depth(); + // temporary set *par as previous of tmpbuf as we might have to realize + // the font. + tmpbuf->previous(*par); + // make sure there is no class difference - SwitchLayoutsBetweenClasses(textclass, tc, buf); + SwitchLayoutsBetweenClasses(textclass, tc, tmpbuf, + current_view->buffer()->params); + Paragraph::depth_type max_depth = (*par)->getMaxDepthAfter(current_view->buffer()); + + while(tmpbuf) { + // if we have a negative jump so that the depth would go below + // 0 depth then we have to redo the delta to this new max depth + // level so that subsequent paragraphs are aligned correctly to + // this paragraph at level 0. + if ((static_cast(tmpbuf->params().depth()) + depth_delta) < 0) + depth_delta = 0; + // set the right depth so that we are not too deep or shallow. + tmpbuf->params().depth(tmpbuf->params().depth() + depth_delta); + if (tmpbuf->params().depth() > max_depth) + tmpbuf->params().depth(max_depth); + // only set this from the 2nd on as the 2nd depends for maxDepth + // still on *par + if (tmpbuf->previous() != (*par)) + max_depth = tmpbuf->getMaxDepthAfter(current_view->buffer()); + // set the inset owner of this paragraph + tmpbuf->setInsetOwner((*par)->inInset()); + for(pos_type i = 0; i < tmpbuf->size(); ++i) { + if (tmpbuf->getChar(i) == Paragraph::META_INSET) { + if (!(*par)->insetAllowed(tmpbuf->getInset(i)->lyxCode())) + { + tmpbuf->erase(i--); + } + } else { + LyXFont f1 = tmpbuf->getFont(current_view->buffer()->params,i); + LyXFont f2 = f1; + if (!(*par)->checkInsertChar(f1)) { + tmpbuf->erase(i--); + } else if (f1 != f2) { + tmpbuf->setFont(i, f1); + } + } + } + tmpbuf = tmpbuf->next(); + } + // now reset it to 0 + buf->previous(0); + // make the buf exactly the same layout than // the cursor paragraph buf->makeSameLayout(*par); - + // find the end of the buffer Paragraph * lastbuffer = buf; while (lastbuffer->next()) lastbuffer = lastbuffer->next(); - + bool paste_the_end = false; - + // open the paragraph for inserting the buf // if necessary if (((*par)->size() > pos) || !(*par)->next()) { @@ -265,17 +348,17 @@ bool CutAndPaste::pasteSelection(Paragraph ** par, Paragraph ** endpar, } // set the end for redoing later *endpar = (*par)->next()->next(); - + // paste it! lastbuffer->next((*par)->next()); (*par)->next()->previous(lastbuffer); - + (*par)->next(buf); buf->previous(*par); - + if ((*par)->next() == lastbuffer) lastbuffer = *par; - + (*par)->pasteParagraph(current_view->buffer()->params); // store the new cursor position *par = lastbuffer; @@ -296,7 +379,7 @@ bool CutAndPaste::pasteSelection(Paragraph ** par, Paragraph ** endpar, // restore the simple cut buffer buf = simple_cut_clone; } - + return true; } @@ -305,10 +388,10 @@ int CutAndPaste::nrOfParagraphs() { if (!buf) return 0; - + int n = 1; Paragraph * tmppar = buf; - while(tmppar->next()) { + while (tmppar->next()) { ++n; tmppar = tmppar->next(); } @@ -316,40 +399,48 @@ int CutAndPaste::nrOfParagraphs() } -int CutAndPaste::SwitchLayoutsBetweenClasses(LyXTextClassList::size_type c1, - LyXTextClassList::size_type c2, - Paragraph * par) +int CutAndPaste::SwitchLayoutsBetweenClasses(textclass_type c1, + textclass_type c2, + Paragraph * par, + BufferParams const & /*bparams*/) { int ret = 0; if (!par || c1 == c2) return ret; - - while (par) { - string const name = textclasslist.NameOfLayout(c1, - par->layout); - int lay = 0; - pair pp = - textclasslist.NumberOfLayout(c2, name); - if (pp.first) { - lay = pp.second; - } else { // layout not found - // use default layout "Standard" (0) - lay = 0; + + ParIterator end = ParIterator(); + for (ParIterator it = ParIterator(par); it != end; ++it) { + par = *it; + string const name = par->layout(); + LyXTextClass const & tclass = textclasslist[c2]; + + bool hasLayout = tclass.hasLayout(name); + + string lay = tclass.defaultLayoutName(); + if (hasLayout) { + lay = name; + } else { + // not found: use default layout + lay = tclass.defaultLayoutName(); } - par->layout = lay; - - if (name != textclasslist.NameOfLayout(c2, par->layout)) { + par->layout(lay); + + if (name != par->layout()) { ++ret; string const s = _("Layout had to be changed from\n") + name + _(" to ") - + textclasslist.NameOfLayout(c2, par->layout) + + par->layout() + _("\nbecause of class conversion from\n") - + textclasslist.NameOfClass(c1) + _(" to ") - + textclasslist.NameOfClass(c2); + + textclasslist[c1].name() + _(" to ") + + textclasslist[c2].name(); InsetError * new_inset = new InsetError(s); - par->insertInset(0, new_inset); + LyXText * txt = current_view->getLyXText(); + LyXCursor cur = txt->cursor; + txt->setCursorIntern(current_view, par, 0); + txt->insertInset(current_view, new_inset); + txt->fullRebreak(current_view); + txt->setCursorIntern(current_view, cur.par(), cur.pos()); } - par = par->next(); } return ret; } @@ -358,6 +449,6 @@ int CutAndPaste::SwitchLayoutsBetweenClasses(LyXTextClassList::size_type c1, bool CutAndPaste::checkPastePossible(Paragraph *) { if (!buf) return false; - + return true; }