mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 21:21:32 +00:00
Added clean CutAndPaste handling with it's own class. Various updates for
text-insets (look at the ChangeLog Entries) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@643 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
1136642d8a
commit
e97f3d1b31
56
ChangeLog
56
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
|
||||
|
@ -12,13 +12,14 @@
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
|
423
src/CutAndPaste.C
Normal file
423
src/CutAndPaste.C
Normal file
@ -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;
|
||||
}
|
53
src/CutAndPaste.h
Normal file
53
src/CutAndPaste.h
Normal file
@ -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
|
@ -20,6 +20,8 @@ lyx_SOURCES = \
|
||||
Bullet.h \
|
||||
Chktex.C \
|
||||
Chktex.h \
|
||||
CutAndPaste.C \
|
||||
CutAndPaste.h \
|
||||
DepTable.C \
|
||||
DepTable.h \
|
||||
FontInfo.C \
|
||||
|
@ -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;
|
||||
|
@ -42,6 +42,7 @@ InsetERT::InsetERT(Buffer * bf)
|
||||
Inset * InsetERT::Clone() const
|
||||
{
|
||||
InsetERT * result = new InsetERT(buffer);
|
||||
result->init(buffer, this);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
CutAndPaste cap;
|
||||
|
||||
if (cap.nrOfParagraphs() > 1) {
|
||||
WriteAlert(_("Impossible operation"),
|
||||
_("Cannot include more than one paragraph!"),
|
||||
_("Sorry."));
|
||||
return false;
|
||||
|
||||
LyXParagraph * tmppar = simple_cut_buffer->Clone();
|
||||
|
||||
while (simple_cut_buffer->size()) {
|
||||
simple_cut_buffer->CutIntoMinibuffer(0);
|
||||
simple_cut_buffer->Erase(0);
|
||||
par->InsertFromMinibuffer(actpos);
|
||||
++actpos;
|
||||
}
|
||||
delete simple_cut_buffer;
|
||||
simple_cut_buffer = tmppar;
|
||||
return true;
|
||||
LyXParagraph *endpar;
|
||||
LyXParagraph *actpar = par;
|
||||
|
||||
return cap.pasteSelection(&actpar, &endpar, actpos,
|
||||
buffer->params.textclass);
|
||||
}
|
||||
|
@ -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;
|
||||
///
|
||||
|
@ -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; }
|
||||
|
15
src/lyx_cb.C
15
src/lyx_cb.C
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
266
src/text2.C
266
src/text2.C
@ -35,11 +35,13 @@
|
||||
#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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user