]> git.lyx.org Git - lyx.git/commitdiff
Added clean CutAndPaste handling with it's own class. Various updates for
authorJürgen Vigna <jug@sad.it>
Mon, 10 Apr 2000 14:29:05 +0000 (14:29 +0000)
committerJürgen Vigna <jug@sad.it>
Mon, 10 Apr 2000 14:29:05 +0000 (14:29 +0000)
text-insets (look at the ChangeLog Entries)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@643 a592a061-630c-0410-9148-cb99ea01b6c8

20 files changed:
ChangeLog
po/POTFILES.in
src/BufferView2.C
src/CutAndPaste.C [new file with mode: 0644]
src/CutAndPaste.h [new file with mode: 0644]
src/Makefile.am
src/insets/insetcollapsable.C
src/insets/insetert.C
src/insets/insetfoot.C
src/insets/insetfoot.h
src/insets/insettext.C
src/insets/insettext.h
src/insets/lyxinset.h
src/lyx_cb.C
src/lyxfunc.C
src/lyxparagraph.h
src/lyxtext.h
src/paragraph.C
src/support/lyxstring.h
src/text2.C

index b22425a6deb66fe19d5cfe5e5891b9df4df77eb2..1b2a1993d3918d39b9fabc29bd1872e3c21d52f2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,59 @@
+2000-04-10  Juergen Vigna  <jug@sad.it>
+
+       * src/insets/insetfoot.C (GetDrawFont): implemented this as the
+       footnote font should be decreased in size twice when displaying.
+
+       * src/insets/insettext.C (GetDrawFont): inserted this function as
+       the drawing-font may differ from the real paragraph font.
+
+       * src/lyxfunc.C (processKeyEvent): fixed Esc-handling when unlocking
+       insets (inset in inset!).
+
+       * src/insets/insetfoot.C (InsertInsetAllowed): implemented the below
+       function here because we don't want footnotes inside footnotes.
+
+       * src/insets/insettext.C (InsetText): forgot to set autoBreakRows for
+       Cloned insets.
+       (init): now set the inset_owner in paragraph.C
+       (LocalDispatch): added some resetPos() in the right position
+       (cutSelection): 
+       (copySelection): 
+       (pasteSelection): changed to use the new CutAndPaste-Class.
+
+       * src/insets/lyxinset.h: inserted new function InsertInsetAllowed
+       which tells if it is allowed to insert another inset inside this one.
+
+       * src/lyx_cb.C (DocumentApplyCB): Using CutAndPaste-Class for
+       SwitchLayoutsBetweenClasses.
+
+       * src/text2.C (InsertInset): checking of the new paragraph-function
+       InsertInsetAllowed.
+       (DeleteSimpleCutBuffer): removed (for now only with #ifdef) as this
+       is not needed anymore here!
+       (CutSelection): 
+       (CopySelection): 
+       (PasteSelection): redone (also with #ifdef) so that now this uses
+       the CutAndPaste-Class.
+       (SwitchLayoutsBetweenClasses): removed here and implemented in the
+       CutAndPaste-Class.
+       
+       * src/CutAndPaste.[Ch]: added this for clean handling of CutAndPaste
+       from/to text/insets.
+
+       * src/paragraph.C (LyXParagraph): inserted new inset_owner pointer
+       so that the paragraph knows if it is inside an (text)-inset.
+       (InsertFromMinibuffer): changed return-value to bool as now it
+       may happen that an inset is not inserted in the paragraph.
+       (InsertInsetAllowed): this checks if it is allowed to insert an
+       inset in this paragraph.
+       (PasteParagraph): 
+       (BreakParagraphConservative): 
+       (BreakParagraph) : small change for the above change of the return
+       value of InsertFromMinibuffer.
+
+       * src/lyxparagraph.h: added inset_owner and the functions to handle
+       this (SetInsetOwner(), InInset() and InsertInsetAllowed()).
+
 2000-04-10  Lars Gullik Bjønnes  <larsbj@lyx.org>
 
        * src/BufferView.[Ch], src/BufferView_pimpl.[Ch]: move more
index ca08ee083209f0ab873d20959f1f92ea140cb03c..60b54c6d45bfad3381a4719080cee733afc34186 100644 (file)
 src/buffer.C
 src/bufferlist.C
 src/BufferView2.C
-src/BufferView.C
+src/BufferView_pimpl.C
 src/bullet_forms.C
 src/bullet_forms_cb.C
 src/Chktex.C
 src/combox.C
 src/credits.C
 src/credits_form.C
+src/CutAndPaste.C
 src/filedlg.C
 src/FontLoader.C
 src/form1.C
index 762050a3dd1407859b6a2f742953f822c6004978..b4b46aa6536c40e4f07cb7884ac300e32cebf13e 100644 (file)
@@ -771,6 +771,10 @@ int BufferView::unlockInset(UpdatableInset * inset)
                the_locking_inset = 0;
                text->FinishUndo();
                return 0;
+       } else if (inset && the_locking_inset &&
+                  the_locking_inset->UnlockInsetInInset(this, inset)) {
+               text->FinishUndo();
+               return 0;
        }
        return bufferlist.unlockInset(inset);
 }
diff --git a/src/CutAndPaste.C b/src/CutAndPaste.C
new file mode 100644 (file)
index 0000000..006f3fc
--- /dev/null
@@ -0,0 +1,423 @@
+/* This file is part of
+ * ======================================================
+ * 
+ *           LyX, The Document Processor
+ *      
+ *           Copyright 1995-2000 The LyX Team.
+ *
+ * ====================================================== */
+
+#include <config.h>
+
+#include "CutAndPaste.h"
+#include "lyxparagraph.h"
+#include "insets/inseterror.h"
+#include "lyx_gui_misc.h"
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+static LyXParagraph * buf = 0;
+
+CutAndPaste::CutAndPaste()
+{
+}
+
+
+CutAndPaste::~CutAndPaste()
+{
+}
+
+// for now here this should be in another Cut&Paste Class!
+//
+void CutAndPaste::DeleteBuffer()
+{
+    if (!buf)
+       return;
+
+    LyXParagraph * tmppar;
+    
+    while (buf) {
+       tmppar =  buf;
+       buf = buf->next;
+       delete tmppar;
+    }
+    buf = 0;
+}
+
+bool CutAndPaste::cutSelection(LyXParagraph *startpar, LyXParagraph **endpar,
+                              int start, int & end, char tc, bool doclear)
+{
+    if (!startpar || (start > startpar->Last()))
+       return false;
+
+    DeleteBuffer();
+
+    textclass = tc;
+
+    if (!(*endpar) || (startpar->ParFromPos(start) ==
+                      (*endpar)->ParFromPos(end))) {
+       // only within one paragraph
+       buf = new LyXParagraph;
+       LyXParagraph::size_type i = start;
+       if (end > startpar->Last())
+           end = startpar->Last();
+       for (; i < end; ++i) {
+           startpar->CopyIntoMinibuffer(start);
+           /* table stuff -- begin */
+           if (startpar->table && startpar->IsNewline(start)) {
+               ++start;
+           } else {
+               /* table stuff -- end */
+               startpar->Erase(start);
+           }
+           buf->InsertFromMinibuffer(buf->Last());
+       }
+    } else {
+       // more than one paragraph
+       (*endpar)->BreakParagraphConservative(end);
+       *endpar = (*endpar)->Next();
+       end = 0;
+   
+       startpar->BreakParagraphConservative(start);
+
+       // store the selection
+       buf = startpar->ParFromPos(start)->next;
+       buf->previous = 0;
+       (*endpar)->previous->next = 0;
+
+       // cut the selection
+       startpar->ParFromPos(start)->next = (*endpar);
+       
+       (*endpar)->previous = startpar->ParFromPos(start);
+
+       // care about footnotes
+       if (buf->footnoteflag) {
+           LyXParagraph * tmppar = buf;
+           while (tmppar){
+               tmppar->footnoteflag = LyXParagraph::NO_FOOTNOTE;
+               tmppar = tmppar->next;
+           }
+       }
+
+       // the cut selection should begin with standard layout
+       buf->Clear(); 
+   
+       // paste the paragraphs again, if possible
+       if (doclear)
+           startpar->Next()->ClearParagraph();
+       if (startpar->FirstPhysicalPar()->HasSameLayout(startpar->Next()) || 
+           !startpar->Next()->Last())
+           startpar->ParFromPos(start)->PasteParagraph();
+    }
+    return true;
+}
+
+bool CutAndPaste::copySelection(LyXParagraph *startpar, LyXParagraph *endpar,
+                               int start, int end, char tc)
+{
+    if (!startpar || (start > startpar->Last()))
+       return false;
+
+    DeleteBuffer();
+
+    textclass = tc;
+
+    if (!(endpar) || (startpar->ParFromPos(start) ==
+                      (endpar)->ParFromPos(end))) {
+       // only within one paragraph
+       buf = new LyXParagraph;
+       LyXParagraph::size_type i = start;
+       if (end > startpar->Last())
+           end = startpar->Last();
+       for (; i < end; ++i) {
+           startpar->CopyIntoMinibuffer(i);
+           buf->InsertFromMinibuffer(buf->Last());
+       }
+    } else {
+       // copy more than one paragraph
+       // clone the paragraphs within the selection
+       LyXParagraph *tmppar = startpar->ParFromPos(start);
+       buf = tmppar->Clone();
+       LyXParagraph *tmppar2 = buf;
+     
+       while (tmppar != endpar->ParFromPos(end)
+              && tmppar->next) {
+           tmppar = tmppar->next;
+           tmppar2->next = tmppar->Clone();
+           tmppar2->next->previous = tmppar2;
+           tmppar2 = tmppar2->next;
+       }
+       tmppar2->next = 0;
+
+       // care about footnotes
+       if (buf->footnoteflag) {
+           tmppar = buf;
+           while (tmppar){
+               tmppar->footnoteflag = LyXParagraph::NO_FOOTNOTE;
+               tmppar = tmppar->next;
+           }
+       }
+       
+       // the buf paragraph is too big
+       LyXParagraph::size_type tmpi2 = startpar->PositionInParFromPos(start);
+       for (; tmpi2; --tmpi2)
+           buf->Erase(0);
+       
+       // now tmppar 2 is too big, delete all after end
+       
+       tmpi2 = endpar->PositionInParFromPos(end);
+       while (tmppar2->size() > tmpi2) {
+           tmppar2->Erase(tmppar2->size() - 1);
+       }
+    }
+    return true;
+}
+
+bool CutAndPaste::pasteSelection(LyXParagraph **par, LyXParagraph **endpar,
+                                int &pos, char tc)
+{
+    if (!checkPastePossible(*par, pos))
+       return false;
+
+    if (pos > (*par)->Last())
+       pos = (*par)->Last();
+
+    LyXParagraph * tmpbuf;
+    LyXParagraph * tmppar = *par;
+    int tmppos = pos;
+
+    // There are two cases: cutbuffer only one paragraph or many
+    if (!buf->next) {
+       // only within a paragraph
+       tmpbuf = buf->Clone();
+       /* table stuff -- begin */
+       bool table_too_small = false;
+       if ((*par)->table) {
+           while (buf->size() && !table_too_small) {
+               if (buf->IsNewline(0)){
+                   while((tmppos < tmppar->Last()) &&
+                         !tmppar->IsNewline(tmppos))
+                       tmppos++;
+                   buf->Erase(0);
+                   if (tmppos < tmppar->Last())
+                       tmppos++;
+                   else
+                       table_too_small = true;
+               } else {
+                   // This is an attempt to fix the
+                   // "never insert a space at the
+                   // beginning of a paragraph" problem.
+                   if (!tmppos && buf->IsLineSeparator(0)) {
+                       buf->Erase(0);
+                   } else {
+                       buf->CutIntoMinibuffer(0);
+                       buf->Erase(0);
+                       if (tmppar->InsertFromMinibuffer(tmppos))
+                           ++tmppos;
+                   }
+               }
+           }
+       } else {
+           /* table stuff -- end */
+           // 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
+           // of the text to insert and we are inserting at
+           // the beginning of the paragraph the space should
+           // be removed.
+           while (buf->size()) {
+               // This is an attempt to fix the
+               // "never insert a space at the
+               // beginning of a paragraph" problem.
+               if (!tmppos && buf->IsLineSeparator(0)) {
+                   buf->Erase(0);
+               } else {
+                   buf->CutIntoMinibuffer(0);
+                   buf->Erase(0);
+                   if (tmppar->InsertFromMinibuffer(tmppos))
+                       ++tmppos;
+               }
+           }
+       }
+       delete buf;
+       buf = tmpbuf;
+       *endpar = tmppar->Next();
+       pos = tmppos;
+    } else {
+       // many paragraphs
+
+       // make a copy of the simple cut_buffer
+       tmpbuf = buf;
+       LyXParagraph * simple_cut_clone = tmpbuf->Clone();
+       LyXParagraph * tmpbuf2 = simple_cut_clone;
+       if ((*par)->footnoteflag){
+           tmpbuf->footnoteflag = (*par)->footnoteflag;
+           tmpbuf->footnotekind = (*par)->footnotekind;
+       }
+       while (tmpbuf->next) {
+           tmpbuf = tmpbuf->next;
+           tmpbuf2->next = tmpbuf->Clone();
+           tmpbuf2->next->previous = tmpbuf2;
+           tmpbuf2 = tmpbuf2->next;
+           if ((*par)->footnoteflag){
+               tmpbuf->footnoteflag = (*par)->footnoteflag;
+               tmpbuf->footnotekind = (*par)->footnotekind;
+           }
+       }
+       
+       // make sure there is no class difference
+       SwitchLayoutsBetweenClasses(textclass, tc, buf);
+       
+       // make the buf exactly the same layout than
+       // the cursor paragraph
+       buf->MakeSameLayout(*par);
+       
+       // find the end of the buffer
+       LyXParagraph * lastbuffer = buf;
+       while (lastbuffer->Next())
+           lastbuffer = lastbuffer->Next();
+       
+       bool paste_the_end = false;
+       
+       // open the paragraph for inserting the buf
+       // if necessary
+       if (((*par)->Last() > pos) || !(*par)->Next()) {
+           (*par)->BreakParagraphConservative(pos);
+           paste_the_end = true;
+       }
+       
+       // set the end for redoing later
+       *endpar = (*par)->ParFromPos(pos)->next->Next();
+       
+       // paste it!
+       lastbuffer->ParFromPos(lastbuffer->Last())->next =
+           (*par)->ParFromPos(pos)->next;
+       (*par)->ParFromPos(pos)->next->previous =
+           lastbuffer->ParFromPos(lastbuffer->Last());
+       
+       (*par)->ParFromPos(pos)->next = buf;
+       buf->previous = (*par)->ParFromPos(pos);
+       
+       if ((*par)->ParFromPos(pos)->Next() == lastbuffer)
+           lastbuffer = *par;
+       
+       (*par)->ParFromPos(pos)->PasteParagraph();
+       
+       // store the new cursor position
+       tmppar = lastbuffer;
+       tmppos = lastbuffer->Last();
+       
+       // maybe some pasting
+       if (lastbuffer->Next() && paste_the_end) {
+           if (lastbuffer->Next()->HasSameLayout(lastbuffer)) {
+               lastbuffer->ParFromPos(lastbuffer->Last())->PasteParagraph();
+           } else if (!lastbuffer->Next()->Last()) {
+               lastbuffer->Next()->MakeSameLayout(lastbuffer);
+               lastbuffer->ParFromPos(lastbuffer->Last())->PasteParagraph();
+           } else if (!lastbuffer->Last()) {
+               lastbuffer->MakeSameLayout(lastbuffer->next);
+               lastbuffer->ParFromPos(lastbuffer->Last())->PasteParagraph();
+           } else
+               lastbuffer->Next()->ClearParagraph();
+       }
+       // restore the simple cut buffer
+       buf = simple_cut_clone;
+       pos = tmppos;
+    }
+
+    return true;
+}
+
+int CutAndPaste::nrOfParagraphs() const
+{
+    if (!buf)
+       return 0;
+
+    int n = 1;
+    LyXParagraph *tmppar = buf;
+    while(tmppar->next) {
+       ++n;
+       tmppar = tmppar->next;
+    }
+    return n;
+}
+
+int CutAndPaste::SwitchLayoutsBetweenClasses(LyXTextClassList::size_type c1,
+                                            LyXTextClassList::size_type c2,
+                                            LyXParagraph * par)
+{
+    int ret = 0;
+    if (!par || c1 == c2)
+       return ret;
+    par = par->FirstPhysicalPar();
+    while (par) {
+       string name = textclasslist.NameOfLayout(c1, par->layout);
+       int lay = 0;
+       pair<bool, LyXTextClass::LayoutList::size_type> pp =
+           textclasslist.NumberOfLayout(c2, name);
+       if (pp.first) {
+           lay = pp.second;
+       } else { // layout not found
+           // use default layout "Standard" (0)
+           lay = 0;
+       }
+       par->layout = lay;
+       
+       if (name != textclasslist.NameOfLayout(c2, par->layout)) {
+           ++ret;
+           string s = "Layout had to be changed from\n"
+               + name + " to "
+               + textclasslist.NameOfLayout(c2, par->layout)
+               + "\nbecause of class conversion from\n"
+               + textclasslist.NameOfClass(c1) + " to "
+               + textclasslist.NameOfClass(c2);
+           InsetError * new_inset = new InsetError(s);
+           par->InsertChar(0, LyXParagraph::META_INSET);
+           par->InsertInset(0, new_inset);
+       }
+       
+       par = par->next;
+    }
+    return ret;
+}
+
+char CutAndPaste::getBufferTextClass()
+{
+    return textclass;
+}
+
+bool CutAndPaste::checkPastePossible(LyXParagraph *par, int)
+{
+    if (!buf)
+       return false;
+
+    LyXParagraph *tmppar;
+
+    // be carefull with footnotes in footnotes
+    if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
+       // check whether the cut_buffer includes a footnote
+       tmppar = buf;
+       while (tmppar && tmppar->footnoteflag == LyXParagraph::NO_FOOTNOTE)
+           tmppar = tmppar->next;
+      
+       if (tmppar) {
+           WriteAlert(_("Impossible operation"),
+                      _("Can't paste float into float!"),
+                      _("Sorry."));
+           return false;
+       }
+    }
+    /* table stuff -- begin */
+    if (par->table) {
+       if (buf->next) {
+           WriteAlert(_("Impossible operation"),
+                      _("Table cell cannot include more than one paragraph!"),
+                      _("Sorry."));
+           return false;
+       }
+    }
+    /* table stuff -- end */
+    return true;
+}
diff --git a/src/CutAndPaste.h b/src/CutAndPaste.h
new file mode 100644 (file)
index 0000000..d2ff6e5
--- /dev/null
@@ -0,0 +1,53 @@
+// -*- C++ -*-
+/* This file is part of
+ * ====================================================== 
+ * 
+ *           LyX, The Document Processor
+ *      
+ *           Copyright 1995-2000 the LyX Team.
+ *
+ * ====================================================== */
+
+#ifndef CUTANDPASTE_H
+#define CUTANDPASTE_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "layout.h"
+
+class LyXParagraph;
+
+///
+class CutAndPaste {
+public:
+    ///
+    CutAndPaste();
+    ~CutAndPaste();
+    bool cutSelection(LyXParagraph *startpar, LyXParagraph **endpar,
+                     int start, int & end, char tc, bool doclear=false);
+    bool copySelection(LyXParagraph *startpar, LyXParagraph *endpar,
+                      int start, int end, char tc);
+    bool pasteSelection(LyXParagraph **par, LyXParagraph **endpar,
+                       int & pos, char tc);
+    int nrOfParagraphs() const;
+    /** needed to switch between different classes this works
+       for a list of paragraphs beginning with the specified par 
+       return value is the number of wrong conversions
+    */ 
+    int SwitchLayoutsBetweenClasses(LyXTextClassList::size_type class1,
+                                   LyXTextClassList::size_type class2,
+                                   LyXParagraph * par);
+    char getBufferTextClass();
+    bool checkPastePossible(LyXParagraph *, int pos);
+
+private:
+    ///
+    void DeleteBuffer();
+    ///
+    char textclass;
+
+};
+
+#endif
index 87a8e995a2f9ced9f2f95941432531c1ccd20963..b098b89a2b53c0a202860418f3df110c7eee42ab 100644 (file)
@@ -20,6 +20,8 @@ lyx_SOURCES = \
        Bullet.h \
        Chktex.C \
        Chktex.h \
+       CutAndPaste.C \
+       CutAndPaste.h \
        DepTable.C \
        DepTable.h \
        FontInfo.C \
index a8d0254882d488384021dc55876cf6a908c105c1..3cde4b52d59635996642be57e52b7508ddaf066f 100644 (file)
@@ -36,7 +36,7 @@ InsetCollapsable::InsetCollapsable(Buffer * bf)
 Inset * InsetCollapsable::Clone() const
 {
     InsetCollapsable * result = new InsetCollapsable(buffer);
-    result->init(buffer, par);
+    result->init(buffer, this);
 
     result->collapsed = collapsed;
     return result;
index 604287548460b8ce0e81e916e8fdfe776acce282..bbbd43edc2f514a542183a0b877d6c35078c4a80 100644 (file)
@@ -42,6 +42,7 @@ InsetERT::InsetERT(Buffer * bf)
 Inset * InsetERT::Clone() const
 {
     InsetERT * result = new InsetERT(buffer);
+    result->init(buffer, this);
     return result;
 }
 
index e4504e48b95628b64ecc2803a40494e2a4f63f2f..fd775a3badea42dbb76f335d1485814c824464cd 100644 (file)
@@ -39,7 +39,7 @@ InsetFoot::InsetFoot(Buffer * bf)
 Inset * InsetFoot::Clone() const
 {
     InsetFoot * result = new InsetFoot(buffer);
-    result->init(buffer, par);
+    result->init(buffer, this);
 
     result->collapsed = collapsed;
     return result;
@@ -55,7 +55,7 @@ char const * InsetFoot::EditMessage() const
 int InsetFoot::Latex(ostream & os, signed char fragile, bool fp) const
 {
        if (fragile) 
-               os << "\\footnotetext{";
+               os << "\\footnote{"; // was footnotemark but that won't work
        else 
                os << "\\footnote{";
        
@@ -93,10 +93,26 @@ void InsetFoot::Read(LyXLex & lex)
 
 
 bool InsetFoot::InsertInset(BufferView * bv, Inset * inset)
+{
+    if (!InsertInsetAllowed(inset))
+       return false;
+
+    return InsetText::InsertInset(bv, inset);
+}
+
+bool InsetFoot::InsertInsetAllowed(Inset * inset) const
 {
     if ((inset->LyxCode() == Inset::FOOT_CODE) ||
        (inset->LyxCode() == Inset::MARGIN_CODE)) {
        return false;
     }
-    return InsetText::InsertInset(bv, inset);
+    return true;
+}
+
+LyXFont InsetFoot::GetDrawFont(LyXParagraph * par, int pos) const
+{
+    LyXFont fn = InsetCollapsable::GetDrawFont(par, pos);
+    fn.decSize();
+    fn.decSize();
+    return fn;
 }
index 3ac1ee73bf7e0522c4b7bfa928fc8f574a35a4d7..43faa6dd4aa8db64116dc2ad35b4017fc1200b48 100644 (file)
@@ -46,6 +46,11 @@ public:
     const char * EditMessage() const;
     ///
     bool InsertInset(BufferView *, Inset * inset);
+    ///
+    bool InsertInsetAllowed(Inset * inset) const;
+    ///
+    LyXFont GetDrawFont(LyXParagraph * par, int pos) const;
+    ///
 };
 
 #endif
index b3f756ea9ec8ce215a6c537b6af4369b81133d0c..08da8ce5abe0cb01713e6150efe8637abbbcc37c 100644 (file)
@@ -51,6 +51,7 @@
 #include "support/LAssert.h"
 #include "lyxtext.h"
 #include "lyxcursor.h"
+#include "CutAndPaste.h"
 #include "font.h"
 
 using std::ostream;
@@ -72,16 +73,12 @@ InsetText::InsetText(InsetText const & ins, Buffer * buf)
 {
     par = 0;
     widthOffset = 0;
-    init(buf, ins.par);
+    init(buf, &ins);
+    autoBreakRows = ins.autoBreakRows;
 }
 
-void InsetText::init(Buffer * buf, LyXParagraph *p)
+void InsetText::init(Buffer * buf, InsetText const * ins)
 {
-    if (p) {
-       if (par)
-           delete par;
-       par = p->Clone();
-    }
     the_locking_inset = 0;
     buffer = buf;
     cursor_visible = false;
@@ -93,6 +90,13 @@ void InsetText::init(Buffer * buf, LyXParagraph *p)
     maxAscent = maxDescent = insetWidth = 0;
     autoBreakRows = false;
     xpos = 0.0;
+    if (ins) {
+       if (par)
+           delete par;
+       par = ins->par->Clone();
+       autoBreakRows = ins->autoBreakRows;
+    }
+    par->SetInsetOwner(this);
 }
 
 
@@ -197,11 +201,11 @@ void InsetText::draw(Painter & pain, LyXFont const & f,
                     int baseline, float & x) const
 {
     xpos = x;
-    computeTextRows(pain, x);
     UpdatableInset::draw(pain, f, baseline, x);
     
     top_x = int(x);
     top_baseline = baseline;
+    computeTextRows(pain, x);
     computeBaselines(baseline);
     for(RowList::size_type r = 0; r < rows.size() - 1; ++r) {
         drawRowSelection(pain, rows[r].pos, rows[r + 1].pos, r, 
@@ -239,7 +243,7 @@ void InsetText::drawRowSelection(Painter & pain, int startpos, int endpos,
        if ((p >= s_start) && (p <= s_end))
            esel_x = int(x);
        char ch = par->GetChar(p);
-       font = GetFont(par,p);
+       font = GetDrawFont(par,p);
        if (IsFloatChar(ch)) {
            // skip for now
        } else if (ch == LyXParagraph::META_INSET) {
@@ -269,7 +273,7 @@ void InsetText::drawRowText(Painter & pain, int startpos, int endpos,
 
     for(int p = startpos; p < endpos; ++p) {
        char ch = par->GetChar(p);
-       LyXFont font = GetFont(par,p);
+       LyXFont font = GetDrawFont(par,p);
        if (IsFloatChar(ch)) {
            // skip for now
        } else if (par->IsNewline(p)) {
@@ -321,6 +325,7 @@ char const * InsetText::EditMessage() const
 
 void InsetText::Edit(BufferView * bv, int x, int y, unsigned int button)
 {
+    par->SetInsetOwner(this);
     UpdatableInset::Edit(bv, x, y, button);
 
     bv->lockInset(this);
@@ -507,6 +512,7 @@ InsetText::LocalDispatch(BufferView * bv,
        moveRight(bv, false);
        selection_end = actpos;
        UpdateLocal(bv, false);
+       resetPos(bv, true);
        break;
     case LFUN_RIGHT:
        bv->text->FinishUndo();
@@ -517,12 +523,14 @@ InsetText::LocalDispatch(BufferView * bv,
        } else {
            selection_start = selection_end = actpos;
        }
+       resetPos(bv, true);
        break;
     case LFUN_LEFTSEL:
        bv->text->FinishUndo();
        moveLeft(bv, false);
        selection_end = actpos;
        UpdateLocal(bv, false);
+       resetPos(bv, true);
        break;
     case LFUN_LEFT:
        bv->text->FinishUndo();
@@ -533,12 +541,14 @@ InsetText::LocalDispatch(BufferView * bv,
        } else {
                selection_start = selection_end = actpos;
        }
+       resetPos(bv, true);
        break;
     case LFUN_DOWNSEL:
        bv->text->FinishUndo();
        moveDown(bv, false);
        selection_end = actpos;
        UpdateLocal(bv, false);
+       resetPos(bv, true);
        break;
     case LFUN_DOWN:
        bv->text->FinishUndo();
@@ -549,12 +559,14 @@ InsetText::LocalDispatch(BufferView * bv,
        } else {
            selection_start = selection_end = actpos;
        }
+       resetPos(bv, true);
        break;
     case LFUN_UPSEL:
        bv->text->FinishUndo();
        moveUp(bv, false);
        selection_end = actpos;
        UpdateLocal(bv, false);
+       resetPos(bv, true);
        break;
     case LFUN_UP:
        bv->text->FinishUndo();
@@ -565,6 +577,7 @@ InsetText::LocalDispatch(BufferView * bv,
        } else {
            selection_start = selection_end = actpos;
        }
+       resetPos(bv, true);
        break;
     case LFUN_BACKSPACE:
        if (!actpos) { // || par->IsNewline(actpos-1)) {
@@ -576,13 +589,17 @@ InsetText::LocalDispatch(BufferView * bv,
        }
        moveLeft(bv);
     case LFUN_DELETE:
-       bool ret;
+    {
        bv->text->SetUndo(Undo::DELETE, 
            bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
            bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
-       if (hasSelection())
-           ret = cutSelection();
-       else
+       bool ret = true;
+       if (hasSelection()) {
+           LyXParagraph::size_type i = selection_start;
+           for (; i < selection_end; ++i) {
+               par->Erase(selection_start);
+           }
+       } else
            ret = Delete();
        if (ret) { // we need update
            selection_start = selection_end = actpos;
@@ -591,22 +608,28 @@ InsetText::LocalDispatch(BufferView * bv,
            selection_start = selection_end = actpos;
            UpdateLocal(bv, false);
        }
-       break;
+    }
+    resetPos(bv, true);
+    break;
     case LFUN_CUT:
-       bv->text->SetUndo(Undo::DELETE, 
-           bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
-           bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
-       if (cutSelection()) { // we need update
+       bv->text->SetUndo(Undo::DELETE, 
+         bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
+         bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
+
+       if (cutSelection()) {
+           // we need update
            actpos = selection_end = selection_start;
            UpdateLocal(bv, true);
        } else if (hasSelection()) {
            selection_start = selection_end = actpos;
            UpdateLocal(bv, false);
        }
+       resetPos(bv, true);
        break;
     case LFUN_COPY:
        bv->text->FinishUndo();
-       if (copySelection()) { // we need update
+       if (copySelection()) {
+           // we need update
            selection_start = selection_end = actpos;
            UpdateLocal(bv, true);
        } else if (hasSelection()) {
@@ -615,14 +638,17 @@ InsetText::LocalDispatch(BufferView * bv,
        }
        break;
     case LFUN_PASTE:
+    {
        bv->text->SetUndo(Undo::INSERT, 
-           bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
-           bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
+         bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
+         bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
        if (pasteSelection()) {
            selection_start = selection_end = actpos;
            UpdateLocal(bv, true);
        }
-       break;
+    }
+    resetPos(bv, true);
+    break;
     case LFUN_HOME:
        bv->text->FinishUndo();
        for(; actpos > rows[actrow].pos; --actpos)
@@ -634,6 +660,7 @@ InsetText::LocalDispatch(BufferView * bv,
        } else {
            selection_start = selection_end = actpos;
        }
+       resetPos(bv, true);
        break;
     case LFUN_END:
     {
@@ -650,6 +677,7 @@ InsetText::LocalDispatch(BufferView * bv,
            selection_start = selection_end = actpos;
        }
     }
+    resetPos(bv, true);
     break;
     case LFUN_MATH_MODE:   // Open or create a math inset
        bv->text->SetUndo(Undo::INSERT, 
@@ -663,6 +691,7 @@ InsetText::LocalDispatch(BufferView * bv,
            selection_start = selection_end = actpos;
        }
        return DISPATCHED;
+    case LFUN_BREAKPARAGRAPH:
     case LFUN_BREAKLINE:
        bv->text->SetUndo(Undo::INSERT, 
            bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
@@ -704,7 +733,7 @@ void InsetText::Validate(LaTeXFeatures & features) const
 // Returns the width of a character at a certain spot
 int InsetText::SingleWidth(Painter & pain, LyXParagraph * par, int pos) const
 {
-    LyXFont font = GetFont(par, pos);
+    LyXFont font = GetDrawFont(par, pos);
     char c = par->GetChar(pos);
 
     if (IsPrintable(c)) {
@@ -727,7 +756,7 @@ int InsetText::SingleWidth(Painter & pain, LyXParagraph * par, int pos) const
 void InsetText::SingleHeight(Painter & pain, LyXParagraph * par,int pos,
                             int & asc, int & desc) const
 {
-    LyXFont font = GetFont(par, pos);
+    LyXFont font = GetDrawFont(par, pos);
     char c = par->GetChar(pos);
 
     asc = desc = 0;
@@ -817,6 +846,11 @@ LyXFont InsetText::GetFont(LyXParagraph * par, int pos) const
     return tmpfont;
 }
 
+// the font for drawing may be different from the real font
+LyXFont InsetText::GetDrawFont(LyXParagraph * par, int pos) const
+{
+    return GetFont(par, pos);
+}
 
 int InsetText::BeginningOfMainBody(LyXParagraph * par) const
 {
@@ -852,7 +886,7 @@ void InsetText::ToggleInsetCursor(BufferView * bv)
         return;
     }
 
-    LyXFont font = GetFont(par, actpos);
+    LyXFont font = GetDrawFont(par, actpos);
 
     int asc = lyxfont::maxAscent(font);
     int desc = lyxfont::maxDescent(font);
@@ -868,7 +902,7 @@ void InsetText::ToggleInsetCursor(BufferView * bv)
 void InsetText::ShowInsetCursor(BufferView * bv)
 {
     if (!cursor_visible) {
-       LyXFont font = GetFont(par, actpos);
+       LyXFont font = GetDrawFont(par, actpos);
        
        int asc = lyxfont::maxAscent(font);
        int desc = lyxfont::maxDescent(font);
@@ -962,7 +996,7 @@ bool InsetText::moveLeft(BufferView * bv, bool activate_inset)
        inset_y = cy;
        inset_pos = actpos;
        the_locking_inset->Edit(bv, the_locking_inset->
-                               width(bv->painter(), GetFont(par,actpos)),
+                               width(bv->painter(), GetDrawFont(par,actpos)),
                                0, 0);
     } else {
        resetPos(bv);
@@ -991,8 +1025,11 @@ bool InsetText::moveDown(BufferView * bv, bool activate_inset)
 }
 
 
-void InsetText::resetPos(BufferView * bv)
+void InsetText::resetPos(BufferView * bv, bool setfont)
 {
+    if (setfont) {
+           real_current_font = current_font = GetDrawFont(par, actpos);
+    }
     if (!rows.size())
        return;
 
@@ -1315,75 +1352,43 @@ void InsetText::UpdateLocal(BufferView *bv, bool flag)
     ShowInsetCursor(bv);
 }
 
-// this is for the simple cut and paste mechanism
-// this then should be a global stuff so that cut'n'paste can work in and
-// and outside text-insets
-static LyXParagraph * simple_cut_buffer = 0;
-// static char simple_cut_buffer_textclass = 0;
-
-// for now here this should be in another Cut&Paste Class!
-//
-static void DeleteSimpleCutBuffer()
-{
-       if (!simple_cut_buffer)
-               return;
-       LyXParagraph * tmppar;
-
-       while (simple_cut_buffer) {
-               tmppar =  simple_cut_buffer;
-               simple_cut_buffer = simple_cut_buffer->next;
-               delete tmppar;
-       }
-       simple_cut_buffer = 0;
-}
-
 bool InsetText::cutSelection()
 {
     if (!hasSelection())
        return false;
-    DeleteSimpleCutBuffer();
-
-    // only within one paragraph
-    simple_cut_buffer = new LyXParagraph;
-    LyXParagraph::size_type i = selection_start;
-    for (; i < selection_end; ++i) {
-       par->CopyIntoMinibuffer(selection_start);
-       par->Erase(selection_start);
-       simple_cut_buffer->InsertFromMinibuffer(simple_cut_buffer->Last());
-    }
-    return true;
+
+    CutAndPaste cap;
+
+    LyXParagraph *endpar = par;
+
+    return cap.cutSelection(par, &endpar, selection_start, selection_end,
+                           buffer->params.textclass);
 }
 
 bool InsetText::copySelection()
 {
     if (!hasSelection())
        return false;
-    DeleteSimpleCutBuffer();
-
-    // only within one paragraph
-    simple_cut_buffer = new LyXParagraph;
-    LyXParagraph::size_type i = selection_start;
-    for (; i < selection_end; ++i) {
-       par->CopyIntoMinibuffer(i);
-       simple_cut_buffer->InsertFromMinibuffer(simple_cut_buffer->Last());
-    }
-    return true;
+
+    CutAndPaste cap;
+
+    return cap.copySelection(par, par, selection_start, selection_end,
+                            buffer->params.textclass);
 }
 
 bool InsetText::pasteSelection()
 {
-    if (!simple_cut_buffer)
-       return false;
-
-    LyXParagraph * tmppar = simple_cut_buffer->Clone();
+    CutAndPaste cap;
 
-    while (simple_cut_buffer->size()) {
-       simple_cut_buffer->CutIntoMinibuffer(0);
-       simple_cut_buffer->Erase(0);
-       par->InsertFromMinibuffer(actpos);
-       ++actpos;
+    if (cap.nrOfParagraphs() > 1) {
+       WriteAlert(_("Impossible operation"),
+                  _("Cannot include more than one paragraph!"),
+                  _("Sorry."));
+       return false;
     }
-    delete simple_cut_buffer;
-    simple_cut_buffer = tmppar;
-    return true;
+    LyXParagraph *endpar;
+    LyXParagraph *actpar = par;
+
+    return cap.pasteSelection(&actpar, &endpar, actpos,
+                             buffer->params.textclass);
 }
index 08d4814d61233e3647b145eca60a14329eb6a405..a95523f834df8e6e08cc911853334b6da5a24f5b 100644 (file)
@@ -100,7 +100,7 @@ public:
     ///
     void SetFont(BufferView *, LyXFont const &, bool toggleall = false);
     ///
-    void init(Buffer *, LyXParagraph * p = 0);
+    void init(Buffer *, InsetText const * ins = 0);
 
     LyXParagraph * par;
 
@@ -110,7 +110,7 @@ protected:
     ///
     void WriteParagraphData(std::ostream &) const;
     ///
-    void resetPos(BufferView *);
+    void resetPos(BufferView *, bool setfont=false);
     ///
     void drawSelection(Painter &, int pos, int baseline, float x);
     ///
@@ -120,6 +120,8 @@ protected:
     int SingleWidth(Painter &, LyXParagraph * par, int pos) const;
     ///
     LyXFont GetFont(LyXParagraph * par, int pos) const;
+    ///
+    virtual LyXFont GetDrawFont(LyXParagraph * par, int pos) const;
 
     Buffer * buffer;
     ///
index 3a334ab900535d785fcde34661536e8bc9040285..debef0e87c7800047fbae08f7e675415608bed34 100644 (file)
@@ -170,7 +170,8 @@ public:
        }
        ///
        virtual void init(BufferView *) {}
-
+       ///
+       virtual bool InsertInsetAllowed(Inset *) const { return false; }
 };
 
 
@@ -260,6 +261,8 @@ public:
        ///
        virtual bool InsertInset(BufferView *, Inset *) { return false; }
        ///
+       virtual bool InsertInsetAllowed(Inset *) const { return true; }
+       ///
        virtual UpdatableInset * GetLockingInset() { return this; }
        ///
        virtual int InsetInInsetY() { return 0; }
index 975c51f4973557a381f13b2fad601a90ea2b62ad..2a54f1128f6e0d7b307d8c7963285df6b4063d01 100644 (file)
@@ -54,6 +54,7 @@
 #include "gettext.h"
 #include "layout.h"
 #include "language.h"
+#include "CutAndPaste.h"
 
 using std::ifstream;
 using std::copy;
@@ -2710,13 +2711,13 @@ extern "C" void DocumentApplyCB(FL_OBJECT *, long)
                if (textclasslist.Load(new_class)) {
                        // successfully loaded
                        redo = true;
-                       current_view->owner()->getMiniBuffer()->Set(_("Converting document to new document class..."));
-                       int ret = current_view->text->
-                               SwitchLayoutsBetweenClasses(current_view->buffer()->
-                                                           params.textclass,
-                                                           new_class,
-                                                           current_view->buffer()->
-                                                           paragraph);
+                       current_view->owner()->getMiniBuffer()->
+                               Set(_("Converting document to new document class..."));
+                       CutAndPaste cap;
+                       int ret = cap.SwitchLayoutsBetweenClasses(
+                               current_view->buffer()->params.textclass,
+                               new_class,
+                               current_view->buffer()->paragraph);
 
                        if (ret) {
                                string s;
index efc97ad917febc28aa49c4f2f106d2f807f67070..97068104158ea910379658ce2e59d16531b0ae30 100644 (file)
@@ -200,13 +200,17 @@ int LyXFunc::processKeyEvent(XEvent * ev)
        }
        
        // this function should be used always [asierra060396]
-       if (owner->view()->available() &&
-           owner->view()->the_locking_inset &&
-           keysym_return == XK_Escape) {
-               owner->view()->unlockInset(owner->view()->the_locking_inset);
-               owner->view()->text->CursorRight();
-               moveCursorUpdate(false);
-               owner->getMiniBuffer()->Set(CurrentState());
+       UpdatableInset * tli = owner->view()->the_locking_inset;
+       if (owner->view()->available() && tli && (keysym_return==XK_Escape)) {
+               if (tli == tli->GetLockingInset()) {
+                       owner->view()->unlockInset(tli);
+                       owner->view()->text->CursorRight();
+                       moveCursorUpdate(false);
+                       owner->getMiniBuffer()->Set(CurrentState());
+               } else {
+                       tli->UnlockInsetInInset(owner->view(),
+                                               tli->GetLockingInset());
+               }
                return 0;
        }
 
index 17a8d1149159aab01144a0f47ccb9514d0e3c744..52c08a0f143db1208f31f68db08966b5112164ae 100644 (file)
@@ -184,9 +184,15 @@ public:
            proof environment */
        int GetEndLabel() const;
 
+       Inset * InInset() { return inset_owner; }
+       void SetInsetOwner(Inset *i) { inset_owner = i; }
+
 private:
        ///
        TextContainer text;
+       ///
+       Inset * inset_owner;
+
 public:
        ///
        size_type size() const { return text.size(); }
@@ -401,6 +407,8 @@ public:
        ///
        void InsertInset(size_type pos, Inset * inset);
        ///
+       bool InsertInsetAllowed(Inset * inset);
+       ///
        Inset * GetInset(size_type pos);
        ///
        Inset const * GetInset(size_type pos) const;
@@ -415,7 +423,7 @@ public:
        ///
        void CutIntoMinibuffer(size_type pos);
        ///
-       void InsertFromMinibuffer(size_type pos);
+       bool InsertFromMinibuffer(size_type pos);
 
        ///
        bool IsHfill(size_type pos) const;
index 200fd75049657ee8c625275e063dc5ce952ae707..66838241043b88691941728d5feb801ce04a34a8 100644 (file)
@@ -391,14 +391,6 @@ public:
        /// just another feature :)
        bool GotoNextNote() const;
 
-       /** needed to switch between different classes this works
-         for a list of paragraphs beginning with the specified par 
-         return value is the number of wrong conversions
-         */ 
-       int SwitchLayoutsBetweenClasses(LyXTextClassList::size_type class1,
-                                       LyXTextClassList::size_type class2,
-                                       LyXParagraph * par);
-
        /* for the greater insets */
   
        /// returns 0 if inset wasn't found
index 0841a945e575a8a607c6366122139930531d8b0a..28faee543a6ce62355f44daa6afc0e9c27f0da22 100644 (file)
@@ -77,6 +77,7 @@ LyXParagraph::LyXParagraph()
        /* table stuff -- begin*/ 
        table = 0;
        /* table stuff -- end*/ 
+       inset_owner = 0;
        id_ = paragraph_id++;
         bibkey = 0; // ale970302
        Clear();
@@ -106,6 +107,7 @@ LyXParagraph::LyXParagraph(LyXParagraph * par)
        /* table stuff -- begin*/ 
        table = 0;
        /* table stuff -- end*/ 
+       inset_owner = 0;
        id_ = paragraph_id++;
 
         bibkey = 0; // ale970302        
@@ -442,12 +444,16 @@ void LyXParagraph::CutIntoMinibuffer(LyXParagraph::size_type pos)
 }
 
 
-void LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
+bool LyXParagraph::InsertFromMinibuffer(LyXParagraph::size_type pos)
 {
+       if ((minibuffer_char == LyXParagraph::META_INSET) &&
+           !InsertInsetAllowed(minibuffer_inset))
+               return false;
        InsertChar(pos, minibuffer_char);
        SetFont(pos, minibuffer_font);
        if (minibuffer_char == LyXParagraph::META_INSET)
                InsertInset(pos, minibuffer_inset);
+       return true;
 }
 
 // end of minibuffer
@@ -636,6 +642,15 @@ void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
 }
 
 
+bool LyXParagraph::InsertInsetAllowed(Inset *inset)
+{
+       if (inset_owner) {
+               printf("CODE:%d\n",inset->LyxCode());
+               return inset_owner->InsertInsetAllowed(inset);
+       }
+       return true;
+}
+
 Inset * LyXParagraph::GetInset(LyXParagraph::size_type pos)
 {
        if (pos >= size()) {
@@ -1335,7 +1350,7 @@ LyXParagraph const * LyXParagraph::Previous() const
 void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
                                  int flag)
 {
-       size_type i, pos_end, pos_first;
+       size_type i, j, pos_end, pos_first;
        // create a new paragraph
        LyXParagraph * par = ParFromPos(pos);
        LyXParagraph * firstpar = FirstPhysicalPar();
@@ -1380,9 +1395,10 @@ void LyXParagraph::BreakParagraph(LyXParagraph::size_type pos,
                //if (pos_end > pos)
                //      tmp->text.reserve(pos_end - pos);
 
-               for (i = pos; i <= pos_end; ++i) {
+               for (i = j = pos; i <= pos_end; ++i) {
                        par->CutIntoMinibuffer(i - pos_first);
-                       tmp->InsertFromMinibuffer(i - pos);
+                       if (tmp->InsertFromMinibuffer(j - pos))
+                               ++j;
                }
                tmp->text.resize(tmp->text.size());
                for (i = pos_end; i >= pos; --i)
@@ -1472,6 +1488,8 @@ LyXParagraph * LyXParagraph::Clone() const
        else
                result->table = 0;
        /* table stuff -- end*/ 
+
+       result->inset_owner = inset_owner;
    
         // ale970302
         result->bibkey = (bibkey) ? new InsetBibKey(bibkey): 0;
@@ -1551,9 +1569,11 @@ void LyXParagraph::BreakParagraphConservative(LyXParagraph::size_type pos)
                //if (pos_end > pos)
                //      tmp->text.reserve(pos_end - pos);
 
-               for (size_type i = pos; i <= pos_end; ++i) {
+               size_type i, j;
+               for (i = j = pos; i <= pos_end; ++i) {
                        par->CutIntoMinibuffer(i - pos_first);
-                       tmp->InsertFromMinibuffer(i - pos);
+                       if (tmp->InsertFromMinibuffer(j - pos))
+                               ++j;
                }
                tmp->text.resize(tmp->text.size());
                for (size_type i = pos_end; i >= pos; --i)
@@ -1581,9 +1601,11 @@ void LyXParagraph::PasteParagraph()
        size_type pos_insert = Last();
 
        // ok, now copy the paragraph
-       for (size_type i = 0; i <= pos_end; ++i) {
+       size_type i, j;
+       for (i = j = 0; i <= pos_end; ++i) {
                the_next->CutIntoMinibuffer(i);
-               InsertFromMinibuffer(pos_insert + i);
+               if (InsertFromMinibuffer(pos_insert + j))
+                       ++j;
        }
    
        // delete the next paragraph
index e96e9f8206c38bf2603854ccfef9787714b0a2cb..8ed99ec07916edf96c8ed51387427ad4c727e91b 100644 (file)
@@ -163,7 +163,7 @@ public:
        lyxstring(value_type const *, size_type n);
        
        /// #lyxstring x("abc")#
-       explicit
+//     explicit
        lyxstring(value_type const *);
        
        /// lyxstring(5, 'n') -> "nnnnn"
index 625d145f09e052df9f0a23004c715b224ba99cb6..13774a60d520fef45fe4a911a83f42be319e8123 100644 (file)
 #include "BufferView.h"
 #include "LyXView.h"
 #include "lyxrow.h"
+#include "CutAndPaste.h"
 #include "Painter.h"
 #include "font.h"
 #include "debug.h"
 
 #define FIX_DOUBLE_SPACE 1
+//#define USE_OLD_CUT_AND_PASTE 1
 
 using std::copy;
 using std::endl;
@@ -1843,6 +1845,8 @@ void LyXText::UpdateCounters(Row * row) const
 /* insets an inset. */ 
 void LyXText::InsertInset(Inset *inset)
 {
+       if (!cursor.par->InsertInsetAllowed(inset))
+               return;
        SetUndo(Undo::INSERT, 
                cursor.par->ParFromPos(cursor.pos)->previous, 
                cursor.par->ParFromPos(cursor.pos)->next);
@@ -1854,6 +1858,7 @@ void LyXText::InsertInset(Inset *inset)
 }
 
 
+#ifdef USE_OLD_CUT_AND_PASTE
 // this is for the simple cut and paste mechanism
 static LyXParagraph * simple_cut_buffer = 0;
 static char simple_cut_buffer_textclass = 0;
@@ -1871,7 +1876,7 @@ void DeleteSimpleCutBuffer()
        }
        simple_cut_buffer = 0;
 }
-
+#endif
 
 void LyXText::copyEnvironmentType()
 {
@@ -1884,7 +1889,7 @@ void LyXText::pasteEnvironmentType()
        SetLayout(copylayouttype);
 }
 
-
+#ifdef USE_OLD_CUT_AND_PASTE
 void LyXText::CutSelection(bool doclear)
 {
        // This doesn't make sense, if there is no selection
@@ -2140,7 +2145,98 @@ void LyXText::CutSelection(bool doclear)
        UpdateCounters(cursor.row);
 }
 
+#else ///////////////////////////////////////////////////////////////////
+
+void LyXText::CutSelection(bool doclear)
+{
+    // This doesn't make sense, if there is no selection
+    if (!selection)
+       return;
+   
+    // OK, we have a selection. This is always between sel_start_cursor
+    // and sel_end cursor
+    LyXParagraph * tmppar;
+    
+    // Check whether there are half footnotes in the selection
+    if (sel_start_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE
+       || sel_end_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
+       tmppar = sel_start_cursor.par;
+       while (tmppar != sel_end_cursor.par){
+           if (tmppar->footnoteflag != sel_end_cursor.par->footnoteflag) {
+               WriteAlert(_("Impossible operation"),
+                          _("Don't know what to do with half floats."),
+                          _("sorry."));
+               return;
+                       }
+           tmppar = tmppar->Next();
+       }
+    }
+    
+    /* table stuff -- begin */
+    if (sel_start_cursor.par->table || sel_end_cursor.par->table) {
+       if ( sel_start_cursor.par != sel_end_cursor.par) {
+           WriteAlert(_("Impossible operation"),
+                      _("Don't know what to do with half tables."),
+                      _("sorry."));
+           return;
+       }
+       sel_start_cursor.par->table->Reinit();
+    }
+    /* table stuff -- end */
     
+    // make sure that the depth behind the selection are restored, too
+    LyXParagraph * endpar = sel_end_cursor.par->LastPhysicalPar()->Next();
+    LyXParagraph * undoendpar = endpar;
+    
+    if (endpar && endpar->GetDepth()) {
+       while (endpar && endpar->GetDepth()) {
+           endpar = endpar->LastPhysicalPar()->Next();
+           undoendpar = endpar;
+       }
+    } else if (endpar) {
+       endpar = endpar->Next(); // because of parindents etc.
+    }
+    
+    SetUndo(Undo::DELETE, sel_start_cursor
+           .par->ParFromPos(sel_start_cursor.pos)->previous, undoendpar);
+    
+    CutAndPaste cap;
+
+    // there are two cases: cut only within one paragraph or
+    // more than one paragraph
+    if (sel_start_cursor.par->ParFromPos(sel_start_cursor.pos) 
+       == sel_end_cursor.par->ParFromPos(sel_end_cursor.pos)) {
+       // only within one paragraph
+       endpar = sel_start_cursor.par;
+       cap.cutSelection(sel_start_cursor.par, &endpar,
+                        sel_start_cursor.pos, sel_end_cursor.pos,
+                        parameters->textclass, doclear);
+    } else {
+       endpar = sel_end_cursor.par;
+
+       cap.cutSelection(sel_start_cursor.par, &endpar,
+                        sel_start_cursor.pos, sel_end_cursor.pos,
+                        parameters->textclass, doclear);
+       cursor.par = sel_end_cursor.par = endpar;
+       cursor.pos = sel_end_cursor.pos;
+    }
+    endpar = sel_end_cursor.par->Next();
+
+    // sometimes necessary
+    if (doclear)
+       sel_start_cursor.par->ClearParagraph();
+
+    RedoParagraphs(sel_start_cursor, endpar);
+   
+    ClearSelection();
+    cursor = sel_start_cursor;
+    SetCursor(cursor.par, cursor.pos);
+    sel_cursor = cursor;
+    UpdateCounters(cursor.row);
+}
+#endif
+    
+#ifdef USE_OLD_CUT_AND_PASTE
 void LyXText::CopySelection()
 {
        // this doesnt make sense, if there is no selection
@@ -2245,8 +2341,65 @@ void LyXText::CopySelection()
                }
        }
 }
-          
 
+#else //////////////////////////////////////////////////////////////////////
+
+void LyXText::CopySelection()
+{
+       // this doesnt make sense, if there is no selection
+       if (!selection)
+               return;
+
+       // ok we have a selection. This is always between sel_start_cursor
+       // and sel_end cursor
+       LyXParagraph * tmppar;
+   
+       /* check wether there are half footnotes in the selection */
+       if (sel_start_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE
+           || sel_end_cursor.par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
+               tmppar = sel_start_cursor.par;
+               while (tmppar != sel_end_cursor.par) {
+                       if (tmppar->footnoteflag !=
+                           sel_end_cursor.par->footnoteflag) {
+                               WriteAlert(_("Impossible operation"),
+                                          _("Don't know what to do"
+                                            " with half floats."),
+                                          _("sorry."));
+                               return;
+                       }
+                       tmppar = tmppar->Next();
+               }
+       }
+
+       /* table stuff -- begin */
+       if (sel_start_cursor.par->table || sel_end_cursor.par->table){
+               if ( sel_start_cursor.par != sel_end_cursor.par){
+                       WriteAlert(_("Impossible operation"),
+                                  _("Don't know what to do with half tables."),
+                                  _("sorry."));
+                       return;
+               }
+       }
+       /* table stuff -- end */
+   
+#ifdef FIX_DOUBLE_SPACE
+       // copy behind a space if there is one
+       while (sel_start_cursor.par->Last() > sel_start_cursor.pos
+              && sel_start_cursor.par->IsLineSeparator(sel_start_cursor.pos)
+              && (sel_start_cursor.par != sel_end_cursor.par
+                  || sel_start_cursor.pos < sel_end_cursor.pos))
+               sel_start_cursor.pos++; 
+#endif
+
+       CutAndPaste cap;
+
+       cap.copySelection(sel_start_cursor.par, sel_end_cursor.par,
+                         sel_start_cursor.pos, sel_end_cursor.pos,
+                         parameters->textclass);
+}
+#endif          
+
+#ifdef USE_OLD_CUT_AND_PASTE
 void LyXText::PasteSelection()
 {
        // this does not make sense, if there is nothing to paste
@@ -2373,6 +2526,7 @@ void LyXText::PasteSelection()
                endpar = tmpcursor.par->Next();
        } else {
                // many paragraphs
+               CutAndPaste cap;
 
                // make a copy of the simple cut_buffer
                tmppar = simple_cut_buffer;
@@ -2394,9 +2548,9 @@ void LyXText::PasteSelection()
                }
      
                // make sure there is no class difference
-               SwitchLayoutsBetweenClasses(simple_cut_buffer_textclass,
-                                           parameters->textclass,
-                                           simple_cut_buffer);
+               cap.SwitchLayoutsBetweenClasses(simple_cut_buffer_textclass,
+                                               parameters->textclass,
+                                               simple_cut_buffer);
      
                // make the simple_cut_buffer exactly the same layout than
                // the cursor paragraph
@@ -2512,7 +2666,38 @@ void LyXText::PasteSelection()
        SetSelection();
        UpdateCounters(cursor.row);
 }
+
+#else ////////////////////////////////////////////////////////////////////
+
+void LyXText::PasteSelection()
+{
+    CutAndPaste cap;
+
+    // this does not make sense, if there is nothing to paste
+    if (!cap.checkPastePossible(cursor.par, cursor.pos))
+       return;
+
+    SetUndo(Undo::INSERT, 
+           cursor.par->ParFromPos(cursor.pos)->previous, 
+           cursor.par->ParFromPos(cursor.pos)->next); 
+
+    LyXParagraph *endpar;
+    LyXParagraph *actpar = cursor.par;
+    int endpos = cursor.pos;
+
+    cap.pasteSelection(&actpar, &endpar, endpos, parameters->textclass);
+
+    RedoParagraphs(cursor, endpar);
+    
+    SetCursor(cursor.par, cursor.pos);
+    ClearSelection();
    
+    sel_cursor = cursor;
+    SetCursor(actpar, endpos);
+    SetSelection();
+    UpdateCounters(cursor.row);
+}
+#endif   
 
 // returns a pointer to the very first LyXParagraph
 LyXParagraph * LyXText::FirstParagraph() const
@@ -2673,9 +2858,13 @@ void LyXText::InsertStringA(string const & str)
 #if 1
                                InsetSpecialChar * new_inset =
                                        new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
-                               par->InsertChar(pos, LyXParagraph::META_INSET);
-                               par->SetFont(pos, current_font);
-                               par->InsertInset(pos, new_inset);
+                               if (par->InsertInsetAllowed(new_inset)) {
+                                       par->InsertChar(pos, LyXParagraph::META_INSET);
+                                       par->SetFont(pos, current_font);
+                                       par->InsertInset(pos, new_inset);
+                               } else {
+                                       delete new_inset;
+                               }
 #else
                                par->InsertChar(pos, LyXParagraph::META_PROTECTED_SEPARATOR);
                                par->SetFont(pos, current_font);
@@ -2686,9 +2875,13 @@ void LyXText::InsertStringA(string const & str)
 #if 1
                                InsetSpecialChar * new_inset =
                                        new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
-                               par->InsertChar(pos, LyXParagraph::META_INSET);
-                               par->SetFont(pos, current_font);
-                               par->InsertInset(pos, new_inset);
+                               if (par->InsertInsetAllowed(new_inset)) {
+                                       par->InsertChar(pos, LyXParagraph::META_INSET);
+                                       par->SetFont(pos, current_font);
+                                       par->InsertInset(pos, new_inset);
+                               } else {
+                                       delete new_inset;
+                               }
 #else
                                        par->InsertChar(a, LyXParagraph::META_PROTECTED_SEPARATOR);
                                        par->SetFont(a, current_font);
@@ -2730,9 +2923,13 @@ void LyXText::InsertStringA(string const & str)
 #if 1
                                        InsetSpecialChar * new_inset =
                                                new InsetSpecialChar(InsetSpecialChar::PROTECTED_SEPARATOR);
-                                       par->InsertChar(pos, LyXParagraph::META_INSET);
-                                       par->SetFont(pos, current_font);
-                                       par->InsertInset(pos, new_inset);
+                                       if (par->InsertInsetAllowed(new_inset)) {
+                                               par->InsertChar(pos, LyXParagraph::META_INSET);
+                                               par->SetFont(pos, current_font);
+                                               par->InsertInset(pos, new_inset);
+                                       } else {
+                                               delete new_inset;
+                                       }
 #else
                                         par->InsertChar(pos, LyXParagraph::META_PROTECTED_SEPARATOR);
                                        par->SetFont(pos, current_font);
@@ -2838,45 +3035,6 @@ bool LyXText::GotoNextNote() const
 }
 
 
-int LyXText::SwitchLayoutsBetweenClasses(LyXTextClassList::size_type class1,
-                                        LyXTextClassList::size_type class2,
-                                        LyXParagraph * par)
-{
-       int ret = 0;
-       if (!par || class1 == class2)
-               return ret;
-       par = par->FirstPhysicalPar();
-       while (par) {
-               string name = textclasslist.NameOfLayout(class1, par->layout);
-               int lay = 0;
-               pair<bool, LyXTextClass::LayoutList::size_type> pp =
-                       textclasslist.NumberOfLayout(class2, name);
-               if (pp.first) {
-                       lay = pp.second;
-               } else { // layout not found
-                       // use default layout "Standard" (0)
-                       lay = 0;
-               }
-               par->layout = lay;
-      
-               if (name != textclasslist.NameOfLayout(class2, par->layout)) {
-                       ++ret;
-                       string s = "Layout had to be changed from\n"
-                               + name + " to " + textclasslist.NameOfLayout(class2, par->layout)
-                               + "\nbecause of class conversion from\n"
-                               + textclasslist.NameOfClass(class1) + " to "
-                               + textclasslist.NameOfClass(class2);
-                       InsetError * new_inset = new InsetError(s);
-                       par->InsertChar(0, LyXParagraph::META_INSET);
-                       par->InsertInset(0, new_inset);
-               }
-      
-               par = par->next;
-       }
-       return ret;
-}
-
-
 void LyXText::CheckParagraph(LyXParagraph * par,
                             LyXParagraph::size_type pos)
 {