Added a preliminary NOT working insettabular. Lot's of fixes for the text

inset which should work now quite stable (well better as before anyway ;)
There have been especially problems with insets inside insets for which
LyX was not prepared, so if you only tried the ERT-inset all should have
worked great also before.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@681 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Vigna 2000-04-19 14:42:19 +00:00
parent d0950aceda
commit 33868acd2c
30 changed files with 2558 additions and 813 deletions

View File

@ -1,3 +1,64 @@
2000-04-19 Juergen Vigna <jug@sad.it>
* src/insets/insettext.C (init): using a LyXCursor now for cursor
position. Set the inset_owner of the used paragraph so that it knows
that it is inside an inset. Fixed cursor handling with mouse and
cursor keys. Fixed wrong timed inset redraws and lots of other changes
and cleanups to make TextInsets work better.
* src/insets/insettext.h: Using a LyXCursor now. Added a clear() call.
Changed parameters of various functions and added LockInsetInInset().
* src/insets/insettext.C:
* src/insets/insetcollapsable.h:
* src/insets/insetcollapsable.C:
* src/insets/insetfoot.h:
* src/insets/insetfoot.C:
* src/insets/insetert.h:
* src/insets/insetert.C: cleaned up the code so that it works now
correctly with insettext.
* src/insets/inset.C:
* src/insets/lyxinset.h: inserted inset_owner and some more changes so
that insets in insets are supported right.
* src/table.h:
* src/table.C: lots of changes for use with inset tabular (and cleanup)
* src/paragraph.C: some small fixes
* src/debug.h: inserted INSETS debug info
* src/lyxfunc.C (Dispatch): added code for InsetTabular and some inset
fixes (f.ex. calling LFUN_DOWN if exiting inset with LFUN_DOWN).
* src/commandtags.h:
* src/LyXAction.C: insert code for InsetTabular.
* src/BufferView_pimpl.C (workAreaMotionNotify): do return always if
not Button1MotionMask.
(workAreaButtonRelease): send always a InsetButtonRelease event to
the_locking_inset.
(checkInsetHit): some setCursor fixes (always with insets).
* src/BufferView2.C (lockInset): returns a bool now and extended for
locking insets inside insets.
(showLockedInsetCursor): it is important to have the cursor always
before the locked inset.
(fitLockedInsetCursor): forgot adding of InsetInInsetY()-offset.
* src/BufferView.h: made lockInset return a bool.
* src/lyxtext.h: inserted function SetCursor(LyXCursor, ...).
* src/text2.C (SetCursor): This now has a version with a LyXCursor
that is used also internally but can be called as public to have back
a cursor pos which is not set internally.
(SetCursorIntern): Changed to use above function.
* src/CutAndPaste.C (DeleteBuffer): forgot to inizialize textclass
2000-04-19 Lars Gullik Bjønnes <larsbj@lyx.org>
* ANNOUNCE:

View File

@ -12,10 +12,12 @@
src/buffer.C
src/bufferlist.C
src/BufferView2.C
src/bufferview_funcs.C
src/BufferView_pimpl.C
src/bullet_forms.C
src/bullet_forms_cb.C
src/Chktex.C
src/ColorHandler.C
src/combox.C
src/credits.C
src/credits_form.C
@ -41,6 +43,7 @@ src/insets/insetlof.C
src/insets/insetlot.C
src/insets/insetparent.C
src/insets/insetref.C
src/insets/insettabular.C
src/insets/insettext.C
src/insets/insettoc.C
src/insets/inseturl.C
@ -75,7 +78,6 @@ src/mathed/math_forms.C
src/mathed/math_panel.C
src/menus.C
src/minibuffer.C
src/Painter.C
src/PaperLayout.C
src/paragraph.C
src/ParagraphExtra.C
@ -86,6 +88,7 @@ src/support/filetools.C
src/support/getUserName.C
src/support/path.C
src/support/path.h
src/table.C
src/TableLayout.C
src/text2.C
src/text.C

View File

@ -160,7 +160,7 @@ public:
/// Inserts a lyx file at cursor position. Returns false if it fails.
bool insertLyXFile(string const & file);
///
int lockInset(UpdatableInset * inset);
bool lockInset(UpdatableInset * inset);
///
void showLockedInsetCursor(long x, long y, int asc, int desc);
///

View File

@ -723,24 +723,29 @@ void BufferView::replaceWord(string const & replacestring)
// End of spellchecker stuff
/* these functions return 1 if an error occured,
otherwise 0 */
int BufferView::lockInset(UpdatableInset * inset)
bool BufferView::lockInset(UpdatableInset * inset)
{
if (!the_locking_inset && inset){
if (!the_locking_inset && inset) {
the_locking_inset = inset;
return 0;
return true;
} else if (inset) {
return the_locking_inset->LockInsetInInset(this, inset);
}
return 1;
return false;
}
void BufferView::showLockedInsetCursor(long x, long y, int asc, int desc)
{
if (the_locking_inset && available()) {
y += text->cursor.y +
the_locking_inset->InsetInInsetY();
LyXCursor cursor = text->cursor;
if ((cursor.pos - 1 >= 0) &&
(cursor.par->GetChar(cursor.pos-1) ==
LyXParagraph::META_INSET) &&
(cursor.par->GetInset(cursor.pos - 1) ==
the_locking_inset->GetLockingInset()))
text->SetCursor(cursor, cursor.par, cursor.pos-1);
y += cursor.y + the_locking_inset->InsetInInsetY();
pimpl_->screen->ShowManualCursor(x, y, asc, desc,
LyXScreen::BAR_SHAPE);
}
@ -758,7 +763,7 @@ void BufferView::hideLockedInsetCursor()
void BufferView::fitLockedInsetCursor(long x, long y, int asc, int desc)
{
if (the_locking_inset && available()){
y += text->cursor.y;
y += text->cursor.y + the_locking_inset->InsetInInsetY();
if (pimpl_->screen->FitManualCursor(x, y, asc, desc))
updateScrollbar();
}

View File

@ -551,6 +551,10 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state)
{
if (buffer_ == 0 || !screen) return;
// Only use motion with button 1
if (!state & Button1MotionMask)
return;
// Check for inset locking
if (bv_->the_locking_inset) {
LyXCursor cursor = bv_->text->cursor;
@ -561,10 +565,6 @@ void BufferView::Pimpl::workAreaMotionNotify(int x, int y, unsigned int state)
state);
return;
}
// Only use motion with button 1
if (!state & Button1MotionMask)
return;
/* The selection possible is needed, that only motion events are
* used, where the bottom press event was on the drawing area too */
@ -849,6 +849,7 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, unsigned int button)
UpdatableInset *inset = (UpdatableInset *)inset_hit;
inset->InsetButtonRelease(bv_, x, y, button);
} else {
inset_hit->InsetButtonRelease(bv_, x, y, button);
inset_hit->Edit(bv_, x, y, button);
}
return;
@ -938,7 +939,7 @@ void BufferView::Pimpl::workAreaButtonRelease(int x, int y, unsigned int button)
* If hit, the coordinates are changed relative to the inset.
* Otherwise coordinates are not changed, and false is returned.
*/
Inset * BufferView::Pimpl::checkInsetHit(int & x, int & y, unsigned int button)
Inset * BufferView::Pimpl::checkInsetHit(int & x, int & y, unsigned int /* button */)
{
if (!screen)
return 0;
@ -947,12 +948,8 @@ Inset * BufferView::Pimpl::checkInsetHit(int & x, int & y, unsigned int button)
LyXCursor cursor;
bv_->text->SetCursorFromCoordinates(cursor, x, y_tmp);
#if 1
bool move_cursor = true;
#else
bool move_cursor = ((cursor.par != bv_->text->cursor.par) ||
(cursor.pos != bv_->text->cursor.pos)) && (button < 2);
#endif
(cursor.pos != bv_->text->cursor.pos));
if (cursor.pos < cursor.par->Last()
&& cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET
@ -976,8 +973,8 @@ Inset * BufferView::Pimpl::checkInsetHit(int & x, int & y, unsigned int button)
if (x > start_x && x < end_x
&& y_tmp > cursor.y - tmpinset->ascent(bv_->painter(), font)
&& y_tmp < cursor.y + tmpinset->descent(bv_->painter(), font)) {
if (move_cursor)
bv_->text->SetCursorFromCoordinates(x, y_tmp);
if (move_cursor && (tmpinset != bv_->the_locking_inset))
bv_->text->SetCursor(cursor.par,cursor.pos,true);
x = x - start_x;
// The origin of an inset is on the baseline
y = y_tmp - (bv_->text->cursor.y);
@ -1004,8 +1001,8 @@ Inset * BufferView::Pimpl::checkInsetHit(int & x, int & y, unsigned int button)
if (x > start_x && x < end_x
&& y_tmp > cursor.y - tmpinset->ascent(bv_->painter(), font)
&& y_tmp < cursor.y + tmpinset->descent(bv_->painter(), font)) {
if (move_cursor)
bv_->text->SetCursorFromCoordinates(x, y_tmp);
if (move_cursor && (tmpinset != bv_->the_locking_inset))
bv_->text->SetCursor(cursor.par,cursor.pos,true);
x = x - start_x;
// The origin of an inset is on the baseline
y = y_tmp - (bv_->text->cursor.y);

View File

@ -32,7 +32,7 @@ using std::pair;
// easy to implement. (Lgb)
static LyXParagraph * buf = 0;
static LyXTextClassList::size_type textclass;
static LyXTextClassList::size_type textclass = 0;
// for now here this should be in another Cut&Paste Class!
// Jürgen, I moved this out of CutAndPaste since it does not operate on any

View File

@ -340,6 +340,8 @@ void LyXAction::init()
{ LFUN_TAB, "tab-forward", "", Noop },
{ LFUN_TABINSERT, "tab-insert", "", Noop },
{ LFUN_TABLE, "table-insert", N_("Insert Table"), Noop },
{ LFUN_INSET_TABULAR, "tabular-inset-insert",
N_("Insert a new Tabular Inset"), Noop },
{ LFUN_TEX, "tex-mode", N_("Toggle TeX style"), Noop },
{ LFUN_INSET_TEXT, "text-inset-insert",
N_("Insert a new Text Inset"), Noop },

View File

@ -244,8 +244,9 @@ enum kb_action {
LFUN_INSET_ERT, // Jug 20000218
LFUN_INSERT_GRAPHICS, // Lgb 20000226
LFUN_INSET_FOOTNOTE, // Jug 20000307
LFUN_INSET_NUMBER, // Dekel 20000402
LFUN_INSET_NUMBER, // Dekel 20000402
LFUN_PARAGRAPH_SPACING, // Lgb 20000411
LFUN_INSET_TABULAR, // Jug 20000412
LFUN_LASTACTION /* this marks the end of the table */
};

View File

@ -44,6 +44,7 @@ static error_item errorTags[] = {
{ Debug::ROFF, "roff", "Keep *roff temporary files"},
{ Debug::ACTION, "action", "User commands"},
{ Debug::LYXLEX, "lyxlex", "The LyX Lexxer"},
{ Debug::INSETS, "insets", "LyX Insets"},
{ Debug::NONE, "none", "No debugging message"},
{ Debug::ANY, "any", "All debugging messages"}
};

View File

@ -50,14 +50,16 @@ struct Debug {
///
LYXLEX = (1 << 15),
///
DEPEND = (1 << 16)
DEPEND = (1 << 16),
///
INSETS = (1 << 17)
};
///
static const type ANY = type(INFO | INIT | KEY | TOOLBAR |
PARSER | LYXRC | KBMAP | LATEX |
MATHED | FONT | TCLASS | LYXVC |
LYXSERVER | ROFF | ACTION | LYXLEX |
DEPEND);
DEPEND | INSETS);
///
friend inline void operator|=(Debug::type & d1, Debug::type d2);

View File

@ -52,6 +52,8 @@ libinsets_la_SOURCES = \
insetref.h \
insetspecialchar.C \
insetspecialchar.h \
insettabular.C \
insettabular.h \
insettext.C \
insettext.h \
insettoc.C \

View File

@ -122,6 +122,14 @@ void UpdatableInset::ToggleInsetCursor(BufferView *)
{
}
void UpdatableInset::ShowInsetCursor(BufferView *)
{
}
void UpdatableInset::HideInsetCursor(BufferView *)
{
}
void UpdatableInset::Edit(BufferView * bv, int, int, unsigned int)
{
@ -170,10 +178,9 @@ UpdatableInset::LocalDispatch(BufferView *, int, string const &)
return UNDISPATCHED;
}
int UpdatableInset::getMaxWidth(Painter & pain) const
int UpdatableInset::getMaxWidth(Painter & pain, UpdatableInset const *inset) const
{
if (owner_)
return owner_->getMaxWidth(pain);
if (owner())
return static_cast<UpdatableInset*>(owner())->getMaxWidth(pain, inset);
return pain.paperWidth();
}

View File

@ -25,11 +25,12 @@ InsetCollapsable::InsetCollapsable(Buffer * bf)
{
collapsed = true;
label = "Label";
autocolapse = true;
autocollapse = true;
autoBreakRows = true;
framecolor = LColor::footnoteframe;
widthOffset = 10;
button_x = button_top_y = button_bottom_y = top_x = -1;
button_length = button_top_y = button_bottom_y = 0;
setInsetName("Collapsable");
}
@ -42,6 +43,31 @@ Inset * InsetCollapsable::Clone() const
return result;
}
void InsetCollapsable::Write(ostream & os) const
{
os << getInsetName() << "\n\ncollapsed ";
if (display())
os << "false\n";
else
os << "true\n";
WriteParagraphData(os);
}
void InsetCollapsable::Read(LyXLex & lex)
{
if (lex.IsOK()) {
lex.next();
string token = lex.GetString();
if (token == "collapsed") {
lex.next();
collapsed = lex.GetBool();
}
}
InsetText::Read(lex);
}
int InsetCollapsable::ascent_collapsed(Painter & pain, LyXFont const &) const
{
int width = 0, ascent = 0, descent = 0;
@ -92,7 +118,7 @@ int InsetCollapsable::width(Painter & pain, LyXFont const & font) const
if (collapsed)
return width_collapsed(pain, font);
return getMaxWidth(pain) - widthOffset + 2;
return getMaxWidth(pain, this) - widthOffset + 2;
}
@ -109,41 +135,39 @@ void InsetCollapsable::draw_collapsed(Painter & pain, LyXFont const &,
void InsetCollapsable::draw(Painter & pain, LyXFont const & f,
int baseline, float & x) const
{
button_length = width_collapsed(pain, labelfont) + 2;
button_top_y = -ascent_collapsed(pain, f);
button_bottom_y = descent_collapsed(pain, f);
if (collapsed) {
draw_collapsed(pain, f, baseline, x);
return;
}
top_x = int(x);
top_baseline = baseline;
draw_collapsed(pain, f, baseline, x);
button_x = int(x);
button_top_y = -ascent_collapsed(pain, f);
button_bottom_y = descent_collapsed(pain, f);
maxWidth = getMaxWidth(pain) - button_x;
x += 2;
int
w = maxWidth - widthOffset,
h = ascent(pain,f) + descent(pain,f);
top_x = int(x);
draw_collapsed(pain, f, baseline, x);
x += 2;
int w = getMaxTextWidth(pain,this);
int h = ascent(pain,f) + descent(pain,f);
pain.rectangle(int(x), baseline - ascent(pain, f), w, h, framecolor);
x += 4;
top_x = int(x - top_x);
drawTextXOffset = int(x) - top_x;
InsetText::draw(pain, f, baseline, x);
}
void InsetCollapsable::Edit(BufferView *bv, int x, int y, unsigned int button)
{
if (collapsed) {
if (collapsed && autocollapse) {
collapsed = false;
UpdateLocal(bv, true);
InsetText::Edit(bv, 0, 0, button);
} else if (button && (x < button_x)) {
return;
} else {
InsetText::Edit(bv, x-top_x, y, button);
} else if (!collapsed) {
InsetText::Edit(bv, x, y, button);
}
}
@ -157,45 +181,69 @@ Inset::EDITABLE InsetCollapsable::Editable() const
void InsetCollapsable::InsetUnlock(BufferView *bv)
{
if (autocolapse) {
if (autocollapse) {
collapsed = true;
}
InsetText::InsetUnlock(bv);
UpdateLocal(bv, true);
UpdateLocal(bv, false);
}
void InsetCollapsable::UpdateLocal(BufferView * bv, bool flag)
{
maxWidth = getMaxWidth(bv->painter()) -
width_collapsed(bv->painter(), labelfont);
InsetText::UpdateLocal(bv, flag);
}
void InsetCollapsable::InsetButtonPress(BufferView *bv,int x,int y,int button)
{
if ((x >= button_x) && (y >= button_top_y)) {
InsetText::InsetButtonPress(bv, x-top_x, y, button);
if (!collapsed && (x >= button_length)) {
InsetText::InsetButtonPress(bv, x, y, button);
}
}
void InsetCollapsable::InsetButtonRelease(BufferView *bv, int x, int y, int button)
{
if ((x < button_x) && (y >= button_top_y) && (y <= button_bottom_y)) {
collapsed = true;
UpdateLocal(bv, false);
bv->unlockInset(this);
} else if ((x >= button_x) && (y >= button_top_y)) {
InsetText::InsetButtonRelease(bv, x-top_x, y, button);
if ((x >= 0) && (x < button_length) &&
(y >= button_top_y) && (y < button_bottom_y)) {
if (collapsed) {
collapsed = false;
InsetText::InsetButtonRelease(bv, 0, 0, button);
UpdateLocal(bv, true);
} else {
collapsed = true;
UpdateLocal(bv, false);
bv->unlockInset(this);
}
} else if (!collapsed && (x >= button_length) && (y >= button_top_y)) {
InsetText::InsetButtonRelease(bv, x, y, button);
}
}
void InsetCollapsable::InsetMotionNotify(BufferView *bv, int x, int y, int button)
void InsetCollapsable::InsetMotionNotify(BufferView *bv, int x, int y, int state)
{
if ((x >= button_x) && (y >= button_top_y)) {
InsetText::InsetMotionNotify(bv, x-top_x, y, button);
if (x >= button_length) {
InsetText::InsetMotionNotify(bv, x, y, state);
}
}
int InsetCollapsable::getMaxWidth(Painter & pain, UpdatableInset const * inset) const
{
if ((this == inset) && !owner())
return pain.paperWidth();
if (this == inset)
return (static_cast<UpdatableInset*>(owner())->getMaxWidth(pain,inset));
if (owner())
return (static_cast<UpdatableInset*>(owner())->getMaxWidth(pain,inset)-
width_collapsed(pain, labelfont) - 2 - widthOffset);
return pain.paperWidth()-width_collapsed(pain, labelfont)-2-widthOffset;
}
int InsetCollapsable::getMaxTextWidth(Painter & pain,
UpdatableInset const * inset, int) const
{
return getMaxWidth(pain, inset) -
width_collapsed(pain, labelfont) - widthOffset - 2;
}

View File

@ -41,6 +41,10 @@ public:
///
Inset * Clone() const;
///
void Read(LyXLex &);
///
void Write(std::ostream &) const;
///
int ascent(Painter &, LyXFont const &) const;
///
int descent(Painter &, LyXFont const &) const;
@ -67,7 +71,9 @@ public:
///
void setLabelFont(LyXFont & f) { labelfont = f; }
///
void setAutoCollapse(bool f) { autocolapse = f; }
void setAutoCollapse(bool f) { autocollapse = f; }
///
int getMaxWidth(Painter & pain, UpdatableInset const *) const;
protected:
///
@ -80,6 +86,8 @@ protected:
void draw_collapsed(Painter & pain, const LyXFont &, int , float &) const;
///
void UpdateLocal(BufferView *, bool);
///
int getMaxTextWidth(Painter & pain, UpdatableInset const *, int x=0) const;
///
bool collapsed;
@ -92,11 +100,12 @@ private:
///
LyXFont labelfont;
///
bool autocolapse;
bool autocollapse;
///
mutable int
top_baseline, top_x,
button_x, button_top_y, button_bottom_y;
button_length, button_top_y, button_bottom_y;
///
int widthOffset;
};
#endif

View File

@ -36,6 +36,7 @@ InsetERT::InsetERT(Buffer * bf)
labelfont.setColor(LColor::ert);
setLabelFont(labelfont);
setAutoCollapse(false);
setInsetName("ERT");
}
@ -43,17 +44,12 @@ Inset * InsetERT::Clone() const
{
InsetERT * result = new InsetERT(buffer);
result->init(buffer, this);
result->collapsed = collapsed;
return result;
}
void InsetERT::Write(ostream & os) const
{
os << "ERT\n";
WriteParagraphData(os);
}
char const * InsetERT::EditMessage() const
{
return _("Opened ERT Inset");

View File

@ -36,8 +36,6 @@ public:
///
Inset * Clone() const;
///
void Write(std::ostream &) const;
///
char const * EditMessage() const;
///
bool InsertInset(BufferView *, Inset *);

View File

@ -33,6 +33,7 @@ InsetFoot::InsetFoot(Buffer * bf)
font.setColor(LColor::footnote);
setLabelFont(font);
setAutoCollapse(false);
setInsetName("Foot");
}
@ -54,41 +55,15 @@ char const * InsetFoot::EditMessage() const
int InsetFoot::Latex(ostream & os, bool fragile, bool fp) const
{
if (fragile)
os << "\\footnote{"; // was footnotemark but that won't work
else
os << "\\footnote{";
int i = InsetText::Latex(os, fragile, fp);
os << "}";
return i;
}
void InsetFoot::Write(ostream & os) const
{
os << "Foot\n"
<< "\ncollapsed ";
if (display())
os << "false\n";
else
os << "true\n";
WriteParagraphData(os);
}
void InsetFoot::Read(LyXLex & lex)
{
if (lex.IsOK()) {
lex.next();
string token = lex.GetString();
if (token == "collapsed") {
lex.next();
collapsed = lex.GetBool();
}
}
InsetText::Read(lex);
if (fragile)
os << "\\footnote{"; // was footnotemark but that won't work
else
os << "\\footnote{";
int i = InsetText::Latex(os, fragile, fp);
os << "}";
return i;
}

View File

@ -39,10 +39,6 @@ public:
///
int Latex(std::ostream &, bool fragile, bool fp) const;
///
void Write(std::ostream &) const;
///
void Read(LyXLex &);
///
const char * EditMessage() const;
///
bool InsertInset(BufferView *, Inset * inset);

964
src/insets/insettabular.C Normal file
View File

@ -0,0 +1,964 @@
/* This file is part of
* ======================================================
*
* LyX, The Document Processor
*
* Copyright (C) 2000 The LyX Team.
*
*======================================================
*/
#include <config.h>
#include <fstream>
#include <algorithm>
#include <cstdlib>
#ifdef __GNUG__
#pragma implementation
#endif
#include "insettabular.h"
#include "buffer.h"
#include "commandtags.h"
#include "LaTeXFeatures.h"
#include "Painter.h"
#include "font.h"
#include "insets/insettext.h"
const int ADD_TO_HEIGHT = 2;
const int ADD_TO_TABLE_WIDTH = 2;
using std::ostream;
using std::ifstream;
InsetTabular::InsetTabular(Buffer * buf, int rows=1, int columns=1)
{
if (rows <= 0)
rows = 1;
if (columns <= 0)
columns = 1;
tabular = new LyXTable(rows,columns,buf);
the_locking_inset = 0;
buffer = buf;
cursor_visible = false;
old_x = -1;
sel_pos_start = sel_pos_end = 0;
no_selection = false;
init = true;
}
InsetTabular::InsetTabular(InsetTabular const & tab, Buffer * buf)
{
tabular = new LyXTable(*(tab.tabular), buf);
the_locking_inset = 0;
buffer = buf;
cursor_visible = false;
old_x = -1;
sel_pos_start = sel_pos_end = 0;
no_selection = false;
init = true;
}
InsetTabular::~InsetTabular()
{
if (tabular)
delete tabular;
}
InsetTabular * InsetTabular::Clone() const
{
InsetTabular * t = new InsetTabular(*this, buffer);
return t;
}
void InsetTabular::Write(ostream & os) const
{
os << "\\begin_inset Tabular\n";
tabular->Write(os,false);
os << "\\end_inset\n";
}
void InsetTabular::Read(LyXLex & lex)
{
if (tabular)
delete tabular;
// bool old_format = (lex.GetString() == "\\LyXTable");
tabular = new LyXTable(lex, buffer);
init = true;
}
int InsetTabular::ascent(Painter & pain, LyXFont const & font) const
{
if (init) {
calculate_width_of_cells(pain, font);
init = false;
}
return tabular->AscentOfRow(0);
}
int InsetTabular::descent(Painter & pain, LyXFont const & font) const
{
if (init) {
calculate_width_of_cells(pain, font);
init = false;
}
return tabular->HeightOfTable() - tabular->AscentOfRow(0);
}
int InsetTabular::width(Painter & pain, LyXFont const & font) const
{
if (init) {
calculate_width_of_cells(pain, font);
init = false;
}
return tabular->WidthOfTable() + (2 * ADD_TO_TABLE_WIDTH);
}
void InsetTabular::draw(Painter & pain, const LyXFont & font, int,
float &) const
{
calculate_width_of_cells(pain, font);
}
const char * InsetTabular::EditMessage() const
{
return _("Opened Tabular Inset");
}
void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
{
UpdatableInset::Edit(bv, x, y, button);
bv->lockInset(this);
the_locking_inset = 0;
inset_pos = inset_x = inset_y = 0;
no_selection = true;
setPos(x,y);
sel_pos_start = sel_pos_end = actpos;
sel_cell_start = sel_cell_end = actcell;
// bv->getOwner()->getPopups().updateFormTable();
}
void InsetTabular::InsetUnlock(BufferView * bv)
{
if (the_locking_inset)
the_locking_inset->InsetUnlock(bv);
HideInsetCursor(bv);
the_locking_inset = 0;
if (hasCharSelection()) {
sel_pos_start = sel_pos_end = actpos;
UpdateLocal(bv, false);
} else
sel_pos_start = sel_pos_end = actpos;
no_selection = false;
}
bool InsetTabular::LockInsetInInset(UpdatableInset *)
{
return true;
}
bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
bool lr)
{
if (!the_locking_inset)
return false;
if (the_locking_inset == inset) {
the_locking_inset->InsetUnlock(bv);
the_locking_inset = 0;
if (lr)
moveRight(false);
return true;
}
return the_locking_inset->UnlockInsetInInset(bv, inset, lr);
}
void InsetTabular::UpdateLocal(BufferView * bv, bool flag)
{
resetPos();
bv->updateInset(this, flag);
}
bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
{
if (!the_locking_inset)
return false;
if (the_locking_inset != inset)
return the_locking_inset->UpdateInsetInInset(bv, inset);
UpdateLocal(bv);
return true;
}
void InsetTabular::InsetButtonRelease(BufferView *bv, int x, int y, int button)
{
if (the_locking_inset) {
the_locking_inset->InsetButtonRelease(bv, x-inset_x,y-inset_y,button);
return;
}
no_selection = false;
}
void InsetTabular::InsetButtonPress(BufferView *bv, int x, int y, int)
{
if (hasCharSelection()) {
sel_pos_start = sel_pos_end = 0;
UpdateLocal(bv, false);
}
no_selection = false;
setPos(x,y,false);
if (the_locking_inset) {
#if 0
UpdatableInset
* inset=0;
if (par->GetChar(actpos)==LYX_META_INSET)
inset=(UpdatableInset*)par->GetInset(actpos);
if (the_locking_inset == inset) {
the_locking_inset->InsetButtonPress(bv,x-inset_x,y-inset_y,button);
return;
} else if (inset) {
// otherwise unlock the_locking_inset and lock the new inset
inset_x = cx-top_x;
inset_y = cy;
inset_pos = actpos;
the_locking_inset->InsetUnlock(bv);
the_locking_inset = inset;
the_locking_inset->Edit(bv, x - inset_x, y - inset_y, button);
return;
}
#endif
// otherwise only unlock the_locking_inset
the_locking_inset->InsetUnlock(bv);
}
#if 0
int
oldcell = actcell;
#endif
setPos(x,y);
the_locking_inset = 0;
sel_pos_start = sel_pos_end = actpos;
sel_cell_start = sel_cell_end = actcell;
#if 0
if (button == 3)
bview->getOwner()->getPopups().showFormTable();
else if (oldcell != actcell)
bview->getOwner()->getPopups().updateFormTable();
#endif
}
void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
{
if (the_locking_inset) {
the_locking_inset->InsetMotionNotify(bv, x-inset_x,y-inset_y,button);
return;
}
if (!no_selection) {
int
// oldcell = actcell,
old = sel_pos_end;
setPos(x,y);
sel_pos_end = actpos;
sel_cell_end = actcell;
if (old != sel_pos_end)
UpdateLocal(bv, false);
#if 0
if (oldcell != actcell)
bview->getOwner()->getPopups().updateFormTable();
#endif
}
no_selection = false;
}
void InsetTabular::InsetKeyPress(XKeyEvent * xke)
{
if (the_locking_inset) {
the_locking_inset->InsetKeyPress(xke);
return;
}
}
UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView *bv, int action,
string const & arg)
{
no_selection = false;
if (UpdatableInset::LocalDispatch(bv, action, arg)) {
resetPos();
return DISPATCHED;
}
UpdatableInset::RESULT
result=DISPATCHED;
if ((action < 0) && arg.empty())
return FINISHED;
if ((action != LFUN_DOWN) && (action != LFUN_UP) &&
(action != LFUN_DOWNSEL) && (action != LFUN_UPSEL))
old_x = -1;
if (the_locking_inset) {
result=the_locking_inset->LocalDispatch(bv, action, arg);
if (result == DISPATCHED) {
setWidthOfCell(actpos,actcell,actrow);
the_locking_inset->ToggleInsetCursor(bv);
UpdateLocal(bv, false);
the_locking_inset->ToggleInsetCursor(bv);
return result;
} else if (result == FINISHED) {
if ((action == LFUN_RIGHT) || (action == -1)) {
actpos = inset_pos + 1;
resetPos();
}
the_locking_inset=0;
result = DISPATCHED;
return result;
}
}
HideInsetCursor(bv);
switch (action) {
// Normal chars not handled here
case -1:
break;
// --- Cursor Movements ---------------------------------------------
case LFUN_RIGHTSEL:
moveRight(false);
sel_pos_end = actpos;
UpdateLocal(bv, false);
break;
case LFUN_RIGHT:
result= DISPATCH_RESULT(moveRight());
if (hasCharSelection()) {
sel_pos_start = sel_pos_end = actpos;
UpdateLocal(bv, false);
} else
sel_pos_start = sel_pos_end = actpos;
break;
case LFUN_LEFTSEL:
moveLeft(false);
sel_pos_end = actpos;
UpdateLocal(bv, false);
break;
case LFUN_LEFT:
result= DISPATCH_RESULT(moveLeft());
if (hasCharSelection()) {
sel_pos_start = sel_pos_end = actpos;
UpdateLocal(bv, false);
} else
sel_pos_start = sel_pos_end = actpos;
break;
case LFUN_DOWNSEL:
moveDown(false);
sel_pos_end = actpos;
UpdateLocal(bv, false);
break;
case LFUN_DOWN:
result= DISPATCH_RESULT(moveDown());
if (hasCharSelection()) {
sel_pos_start = sel_pos_end = actpos;
UpdateLocal(bv, false);
} else
sel_pos_start = sel_pos_end = actpos;
break;
case LFUN_UPSEL:
moveUp(false);
sel_pos_end = actpos;
UpdateLocal(bv, false);
break;
case LFUN_UP:
result= DISPATCH_RESULT(moveUp());
if (hasCharSelection()) {
sel_pos_start = sel_pos_end = actpos;
UpdateLocal(bv, false);
} else
sel_pos_start = sel_pos_end = actpos;
break;
case LFUN_BACKSPACE:
break;
case LFUN_DELETE:
break;
case LFUN_HOME:
break;
case LFUN_END:
break;
case LFUN_TAB:
if (hasCharSelection()) {
sel_pos_start = sel_pos_end = actpos;
UpdateLocal(bv, false);
}
sel_pos_start = sel_pos_end = actpos;
moveNextCell();
break;
default:
result = UNDISPATCHED;
break;
}
if (result!=FINISHED) {
if (!the_locking_inset) {
#if 0
if (oldcell != actcell)
bview->getOwner()->getPopups().updateFormTable();
#endif
ShowInsetCursor(bv);
}
} else
bv->unlockInset(this);
return result;
}
int InsetTabular::Latex(ostream & os, bool, bool) const
{
return tabular->Latex(os);
}
int InsetTabular::Linuxdoc(ostream &) const
{
return 0;
}
int InsetTabular::DocBook(ostream &) const
{
return 0;
}
void InsetTabular::Validate(LaTeXFeatures & features) const
{
if (tabular->IsLongTable())
features.longtable = true;
}
void InsetTabular::calculate_width_of_cells(Painter & pain, LyXFont const & font) const
{
int
cell=-1,
i,j,
maxAsc, maxDesc;
InsetText
*inset;
for(i=0; i < tabular->rows; ++i) {
maxAsc = maxDesc = 0;
for(j=0; j < tabular->columns; ++j) {
if (tabular->IsPartOfMultiColumn(i,j))
continue;
++cell;
inset = tabular->GetCellInset(cell);
maxAsc = max(maxAsc, inset->ascent(pain, font));
maxDesc = max(maxDesc, inset->descent(pain, font));
tabular->SetWidthOfCell(cell, inset->width(pain, font));
}
tabular->SetAscentOfRow(i,maxAsc+ADD_TO_HEIGHT);
tabular->SetDescentOfRow(i,maxDesc+ADD_TO_HEIGHT);
}
}
void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
int row, int cell)
{
// Juergen, have you thought about drawing the on-off lines in a
// different color (gray of some kind), especially since those
// lines will not be there on the hardcopy anyway. (Lgb)
int
x_old = x;
bool
on_off;
x_old -= tabular->WidthOfColumn(cell);
on_off = !tabular->TopLine(cell);
if ((!on_off || !tabular->TopAlreadyDrawed(cell)) &&
!tabular->IsContRow(cell))
pain.line(x_old, baseline - tabular->AscentOfRow(row),
x, baseline - tabular->AscentOfRow(row),
LColor::tableline,
on_off ? Painter::line_onoffdash:Painter::line_solid);
on_off = !tabular->BottomLine(cell);
if ((!on_off && !tabular->RowHasContRow(cell)) ||
tabular->VeryLastRow(cell))
pain.line(x_old ,baseline + tabular->DescentOfRow(row),
x, baseline + tabular->DescentOfRow(row),
LColor::tableline,
on_off ? Painter::line_onoffdash:Painter::line_solid);
on_off = !tabular->LeftLine(cell);
pain.line(x_old, baseline - tabular->AscentOfRow(row),
x_old, baseline + tabular->DescentOfRow(row),
LColor::tableline,
on_off ? Painter::line_onoffdash:Painter::line_solid);
on_off = !tabular->RightLine(cell);
pain.line(x - tabular->AdditionalWidth(cell),
baseline - tabular->AscentOfRow(row),
x - tabular->AdditionalWidth(cell),
baseline + tabular->DescentOfRow(row),
LColor::tableline,
on_off ? Painter::line_onoffdash:Painter::line_solid);
}
void InsetTabular::GetCursorPos(int & x, int & y)
{
x = cx-top_x;
y = cy;
}
void InsetTabular::ToggleInsetCursor(BufferView * bv)
{
if (the_locking_inset) {
the_locking_inset->ToggleInsetCursor(bv);
return;
}
int
x=0,y=0,
asc,desc;
LyXFont
font; // = the_locking_inset->GetFont(par, actpos);
asc = lyxfont::maxAscent(font);
desc = lyxfont::maxDescent(font);
if (cursor_visible)
bv->hideLockedInsetCursor();
else
bv->showLockedInsetCursor(cx+x, cy+y, asc, desc);
cursor_visible = !cursor_visible;
}
void InsetTabular::ShowInsetCursor(BufferView * bv)
{
if (!cursor_visible) {
int
asc,desc;
LyXFont
font; // = GetFont(par, actpos);
asc = lyxfont::maxAscent(font);
desc = lyxfont::maxDescent(font);
bv->fitLockedInsetCursor(cx, cy, asc, desc);
bv->showLockedInsetCursor(cx, cy, asc, desc);
cursor_visible = true;
}
}
void InsetTabular::HideInsetCursor(BufferView * bv)
{
if (cursor_visible)
ToggleInsetCursor(bv);
}
void InsetTabular::setPos(int, int, bool)
{
}
void InsetTabular::setWidthOfCell(int, int, int)
{
}
bool InsetTabular::moveRight(bool)
{
return false;
}
bool InsetTabular::moveLeft(bool)
{
return false;
}
bool InsetTabular::moveUp(bool)
{
return false;
}
bool InsetTabular::moveDown(bool)
{
return false;
}
bool InsetTabular::moveNextCell()
{
return false;
}
bool InsetTabular::movePrevCell()
{
return false;
}
void InsetTabular::resetPos()
{
}
bool InsetTabular::Delete()
{
return true;
}
void InsetTabular::SetFont(LyXFont const &)
{
}
void InsetTabular::TableFeatures(int, string)
{
#if 0
int
i,
selection_start,
selection_end,
setLines = 0,
setAlign = LYX_ALIGN_LEFT,
lineSet;
bool
what;
switch (feature) {
case LyXTable::ALIGN_LEFT:
setAlign=LYX_ALIGN_LEFT;
break;
case LyXTable::ALIGN_RIGHT:
setAlign=LYX_ALIGN_RIGHT;
break;
case LyXTable::ALIGN_CENTER:
setAlign=LYX_ALIGN_CENTER;
break;
default:
break;
}
if (hasCellSelection()) {
if (sel_cell_start > sel_cell_end) {
selection_start = sel_cell_end;
selection_end = sel_cell_start;
} else {
selection_start = sel_cell_start;
selection_end = sel_cell_end;
}
} else
selection_start = selection_end = actcell;
switch (feature) {
case LyXTable::SET_PWIDTH:
tabular->SetPWidth(actcell,val);
break;
case LyXTable::SET_SPECIAL_COLUMN:
case LyXTable::SET_SPECIAL_MULTI:
tabular->SetAlignSpecial(actcell,val,feature);
break;
case LyXTable::APPEND_ROW:
{
int
pos = actpos,
cell_org = actcell,
cell = actcell;
// if there is a ContRow following this row I have to add
// the row after the ContRow's
if ((pos < par->last()) && tabular->RowHasContRow(cell_org)) {
while((pos < par->last()) && !tabular->IsContRow(cell)) {
while (pos < par->last() && !par->IsNewline(pos))
++pos;
if (pos < par->last())
++pos;
++cell;
}
while((pos < par->last()) && tabular->IsContRow(cell)) {
while (pos < par->last() && !par->IsNewline(pos))
++pos;
if (pos < par->last())
++pos;
++cell;
}
cell_org = --cell;
if (pos < par->last())
--pos;
}
while ((pos < par->last()) &&
((cell == cell_org) || !tabular->IsFirstCell(cell))) {
while ((pos < par->last()) && !par->IsNewline(pos))
++pos;
if (pos < par->last())
++pos;
++cell;
}
// insert the new cells
int number = tabular->NumberOfCellsInRow(cell_org);
for (i=0; i<number; ++i)
par->InsertChar(pos, LYX_META_NEWLINE);
// append the row into the table
tabular->AppendRow(cell_org);
calculate_width_of_cells();
UpdateLocal();
return;
}
case LyXTable::APPEND_CONT_ROW:
{
int
pos = actpos,
cell_org = actcell,
cell = actcell;
// if there is already a controw but not for this cell
// the AppendContRow sets only the right values but does
// not actually add a row
if (tabular->RowHasContRow(cell_org) &&
(tabular->CellHasContRow(cell_org) < 0)) {
tabular->AppendContRow(cell_org);
calculate_width_of_cells();
UpdateLocal();
return;
}
while ((pos < par->last()) &&
((cell == cell_org) || !tabular->IsFirstCell(cell))) {
while (pos < par->last() && !par->IsNewline(pos))
++pos;
if (pos < par->last())
++pos;
++cell;
}
// insert the new cells
int number = tabular->NumberOfCellsInRow(cell_org);
for (i=0; i<number; ++i)
par->InsertChar(pos, LYX_META_NEWLINE);
// append the row into the table
tabular->AppendContRow(cell_org);
calculate_width_of_cells();
UpdateLocal();
return;
}
case LyXTable::APPEND_COLUMN:
{
int
pos = 0,
cell_org = actcell,
cell = 0;
do {
if (pos && (par->IsNewline(pos-1))) {
if (tabular->AppendCellAfterCell(cell_org, cell)) {
par->InsertChar(pos, LYX_META_NEWLINE);
if (pos <= actpos)
++actpos;
++pos;
}
++cell;
}
++pos;
} while (pos <= par->last());
// remember that the very last cell doesn't end with a newline.
// This saves one byte memory per table ;-)
if (tabular->AppendCellAfterCell(cell_org, cell))
par->InsertChar(par->last(), LYX_META_NEWLINE);
// append the column into the table
tabular->AppendColumn(cell_org);
calculate_width_of_cells();
UpdateLocal();
return;
}
case LyXTable::DELETE_ROW:
RemoveTableRow();
calculate_width_of_cells();
UpdateLocal();
return;
case LyXTable::DELETE_COLUMN:
{
int pos = 0;
int cell = 0;
do {
if (!pos || (par->IsNewline(pos-1))){
if (tabular->DeleteCellIfColumnIsDeleted(cell, actcell)) {
// delete one cell
while (pos < par->last() && !par->IsNewline(pos))
par->Erase(pos);
if (pos < par->last())
par->Erase(pos);
else
par->Erase(pos - 1); // the missing newline
// at the end of a table
--pos; // because of ++pos below
}
++cell;
}
++pos;
} while (pos <= par->last());
/* delete the column from the table */
tabular->DeleteColumn(actcell);
calculate_width_of_cells();
UpdateLocal();
return;
}
case LyXTable::TOGGLE_LINE_TOP:
lineSet = !tabular->TopLine(actcell);
for(i=selection_start; i<=selection_end; ++i)
tabular->SetTopLine(i,lineSet);
calculate_width_of_cells();
UpdateLocal();
return;
case LyXTable::TOGGLE_LINE_BOTTOM:
lineSet = !tabular->BottomLine(actcell);
for(i=selection_start; i<=selection_end; ++i)
tabular->SetBottomLine(i,lineSet);
calculate_width_of_cells();
UpdateLocal();
return;
case LyXTable::TOGGLE_LINE_LEFT:
lineSet = !tabular->LeftLine(actcell);
for(i=selection_start; i<=selection_end; ++i)
tabular->SetLeftLine(i,lineSet);
calculate_width_of_cells();
UpdateLocal();
return;
case LyXTable::TOGGLE_LINE_RIGHT:
lineSet = !tabular->RightLine(actcell);
for(i=selection_start; i<=selection_end; ++i)
tabular->SetRightLine(i,lineSet);
calculate_width_of_cells();
UpdateLocal();
return;
case LyXTable::ALIGN_LEFT:
case LyXTable::ALIGN_RIGHT:
case LyXTable::ALIGN_CENTER:
for(i=selection_start; i<=selection_end; ++i)
tabular->SetAlignment(i,setAlign);
UpdateLocal();
return;
case LyXTable::MULTICOLUMN:
{
if (tabular->row_of_cell(selection_start) !=
tabular->row_of_cell(selection_end)) {
WriteAlert(_("Impossible Operation!"),
_("Multicolumns can only be horizontally."),
_("Sorry."));
return;
}
// just multicol for one Single Cell
if (!hasCellSelection()) {
// check wether we are completly in a multicol
if (tabular->IsMultiColumn(actcell)) {
int
newlines,
pos = actpos;
if ((newlines=tabular->UnsetMultiColumn(actcell))) {
while ((pos < par->last()) && !par->IsNewline(pos))
++pos;
for (;newlines;--newlines)
par->InsertChar(pos, LYX_META_NEWLINE);
}
calculate_width_of_cells();
} else {
tabular->SetMultiColumn(actcell, 1);
}
UpdateLocal();
return;
}
// we have a selection so this means we just add all this
// cells to form a multicolumn cell
int
number = 1,
s_start, s_end;
if (sel_pos_start > sel_pos_end) {
s_start = sel_pos_end;
s_end = sel_pos_start;
} else {
s_start = sel_pos_start;
s_end = sel_pos_end;
}
for(i=s_start; i < s_end; ++i) {
if (par->IsNewline(i)) {
par->Erase(i);
// check for double-blanks
if ((i && !par->IsLineSeparator(i-1)) &&
(i < par->last()) && !par->IsLineSeparator(i))
par->InsertChar(i, ' ');
else
--i;
++number;
}
}
tabular->SetMultiColumn(selection_start,number);
actpos = s_start;
sel_cell_end = sel_cell_start;
calculate_width_of_cells();
UpdateLocal();
return;
}
case LyXTable::SET_ALL_LINES:
setLines = 1;
case LyXTable::UNSET_ALL_LINES:
for(i=selection_start; i<=selection_end; ++i)
tabular->SetAllLines(i, setLines);
calculate_width_of_cells();
UpdateLocal();
return;
case LyXTable::SET_LONGTABLE:
tabular->SetLongTable(true);
UpdateLocal(); // because this toggles displayed
return;
case LyXTable::UNSET_LONGTABLE:
tabular->SetLongTable(false);
UpdateLocal(); // because this toggles displayed
return;
case LyXTable::SET_ROTATE_TABLE:
tabular->SetRotateTable(true);
return;
case LyXTable::UNSET_ROTATE_TABLE:
tabular->SetRotateTable(false);
return;
case LyXTable::SET_ROTATE_CELL:
for(i=selection_start; i<=selection_end; ++i)
tabular->SetRotateCell(i,true);
return;
case LyXTable::UNSET_ROTATE_CELL:
for(i=selection_start; i<=selection_end; ++i)
tabular->SetRotateCell(i,false);
return;
case LyXTable::SET_LINEBREAKS:
what = !tabular->Linebreaks(tabular->FirstVirtualCell(actcell));
for(i=selection_start; i<=selection_end; ++i)
tabular->SetLinebreaks(i,what);
return;
case LyXTable::SET_LTFIRSTHEAD:
tabular->SetLTHead(actcell,true);
return;
case LyXTable::SET_LTHEAD:
tabular->SetLTHead(actcell,false);
return;
case LyXTable::SET_LTFOOT:
tabular->SetLTFoot(actcell,false);
return;
case LyXTable::SET_LTLASTFOOT:
tabular->SetLTFoot(actcell,true);
return;
case LyXTable::SET_LTNEWPAGE:
what = !tabular->LTNewPage(actcell);
tabular->SetLTNewPage(actcell,what);
return;
}
#endif
}
void InsetTabular::RemoveTableRow()
{
}

188
src/insets/insettabular.h Normal file
View File

@ -0,0 +1,188 @@
// -*- C++ -*-
/* This file is part of
* ======================================================
*
* LyX, The Document Processor
*
* Copyright (C) 1995-2000 The LyX Team.
*
*======================================================
*/
// This is the rewrite of the tabular (table) support.
// It will probably be a lot of work.
// One first goal could be to make the inset read the old table format
// and just output it again... no viewing at all.
// When making the internal structure of tabular support I really think
// that STL containers should be used. This will separate the container from
// the rest of the code, which is a good thing.
// Ideally the tabular support should do as the mathed and use
// LaTeX in the .lyx file too.
// Things to think of when desingning the new tabular support:
// - color support (colortbl, color)
// - decimal alignment (dcloumn)
// - custom lines (hhline)
// - rotation
// - multicolumn
// - multirow
// - column styles
// This is what I have written about tabular support in the LyX3-Tasks file:
//
// o rewrite of table code. Should probably be written as some
// kind of an inset. At least get the code out of the kernel.
// - colortbl -multirow
// - hhline -multicolumn
// - dcolumn
// o enhance longtable support
// Lgb
#ifndef INSETTABULAR_H
#define INSETTABULAR_H
#ifdef __GNUG__
#pragma interface
#endif
#include "lyxinset.h"
#include "table.h"
#include "LString.h"
class LyXLex;
class Painter;
class BufferView;
class Buffer;
class TexRow;
class InsetTabular : public UpdatableInset {
public:
///
InsetTabular(Buffer *, int rows=1, int columns=1);
///
InsetTabular(InsetTabular const &, Buffer *);
///
~InsetTabular();
///
InsetTabular * InsetTabular::Clone() const;
///
void Read(LyXLex &);
///
void Write(std::ostream &) const;
///
int ascent(Painter &, LyXFont const &) const;
///
int descent(Painter &, LyXFont const &) const;
///
int width(Painter &, LyXFont const & f) const;
///
void draw(Painter & pain, const LyXFont &, int , float &) const;
///
const char * EditMessage() const;
///
void Edit(BufferView *, int x, int y, unsigned int);
///
void InsetUnlock(BufferView *);
///
bool LockInsetInInset(UpdatableInset *);
///
bool UnlockInsetInInset(BufferView *, UpdatableInset *, bool lr=false);
///
void UpdateLocal(BufferView *, bool flag = true);
///
bool UpdateInsetInInset(BufferView *, Inset *);
///
bool display() const { return tabular->IsLongTable(); }
///
void InsetButtonRelease(BufferView *, int, int, int);
///
void InsetButtonPress(BufferView *, int, int, int);
///
void InsetMotionNotify(BufferView *, int, int, int);
///
void InsetKeyPress(XKeyEvent *);
///
UpdatableInset::RESULT LocalDispatch(BufferView *, int, string const &);
///
int Latex(std::ostream &, bool, bool) const;
///
int Linuxdoc(std::ostream &) const;
///
int DocBook(std::ostream &) const;
///
void Validate(LaTeXFeatures & features) const;
///
Inset::Code LyxCode() const { return Inset::TABULAR_CODE; }
///
void GetCursorPos(int & x, int & y);
///
void ToggleInsetCursor(BufferView *);
///
void TableFeatures(int feature, string val="");
///
int GetActCell() { return actcell; }
///
void SetFont(LyXFont const &);
///
/// Public structures and variables
///
LyXTable * tabular;
private:
void calculate_width_of_cells(Painter &, LyXFont const &) const;
///
void DrawCellLines(Painter &, int x, int baseline, int row, int cell);
///
void ShowInsetCursor(BufferView *);
///
void HideInsetCursor(BufferView *);
///
void setPos(int x, int y, bool activate_inset=true);
///
void setWidthOfCell(int pos, int cell, int row);
///
bool moveRight(bool activate_inset=true);
bool moveLeft(bool activate_inset=true);
bool moveUp(bool activate_inset=true);
bool moveDown(bool activate_inset=true);
bool moveNextCell();
bool movePrevCell();
bool Delete();
///
void resetPos();
///
void RemoveTableRow();
///
bool hasCharSelection() const {return (sel_pos_start != sel_pos_end);}
bool hasCellSelection() const {return hasCharSelection() &&
(sel_cell_start != sel_cell_end);}
///
/// Private structures and variables
///
UpdatableInset
* the_locking_inset;
Buffer
* buffer;
int
inset_pos,
inset_x, inset_y,
sel_pos_start,
sel_pos_end,
sel_cell_start,
sel_cell_end,
old_x,
cx, cy,
actpos,
actcell,
actcol,
actrow;
bool
no_selection;
mutable bool
init;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -19,9 +19,9 @@
#endif
#include "lyxinset.h"
#include "lyxparagraph.h"
#include "LString.h"
//#include "buffer.h"
#include "lyxparagraph.h"
#include "lyxcursor.h"
class Painter;
class BufferView;
@ -46,6 +46,8 @@ public:
///
Inset * Clone() const;
///
void clear() const { par->clearContents(); }
///
void Read(LyXLex &);
///
void Write(std::ostream &) const;
@ -64,7 +66,9 @@ public:
///
void InsetUnlock(BufferView *);
///
bool UnlockInsetInInset(BufferView *, Inset *, bool lr = false);
bool LockInsetInInset(BufferView *, UpdatableInset *);
///
bool UnlockInsetInInset(BufferView *, UpdatableInset *, bool lr = false);
///
bool UpdateInsetInInset(BufferView *, Inset *);
///
@ -110,7 +114,7 @@ protected:
///
void WriteParagraphData(std::ostream &) const;
///
void resetPos(BufferView *, bool setfont=false);
void resetPos(Painter &) const;
///
void drawSelection(Painter &, int pos, int baseline, float x);
///
@ -122,6 +126,9 @@ protected:
LyXFont GetFont(LyXParagraph * par, int pos) const;
///
virtual LyXFont GetDrawFont(LyXParagraph * par, int pos) const;
///
virtual int getMaxTextWidth(Painter &, UpdatableInset const *,
int x=0) const;
Buffer * buffer;
///
@ -129,15 +136,14 @@ protected:
///
LyXFont real_current_font;
///
mutable int maxWidth;
///
mutable int maxAscent;
///
mutable int maxDescent;
///
mutable int insetWidth;
///
int widthOffset;
mutable int drawTextXOffset;
mutable int drawTextYOffset;
///
bool autoBreakRows;
@ -159,12 +165,12 @@ private:
///
void HideInsetCursor(BufferView *);
///
void setPos(BufferView *, int x, int y, bool activate_inset = true);
void setPos(Painter &, int x, int y) const;
///
bool moveRight(BufferView *, bool activate_inset = true);
bool moveLeft(BufferView *, bool activate_inset = true);
bool moveUp(BufferView *, bool activate_inset = true);
bool moveDown(BufferView *, bool activate_inset = true);
UpdatableInset::RESULT moveRight(BufferView *, bool activate_inset = true);
UpdatableInset::RESULT moveLeft(BufferView *, bool activate_inset = true);
UpdatableInset::RESULT moveUp(BufferView *);
UpdatableInset::RESULT moveDown(BufferView *);
bool Delete();
bool cutSelection();
bool copySelection();
@ -175,14 +181,17 @@ private:
void SetCharFont(int pos, LyXFont const & font);
///
string getText(int);
///
bool checkAndActivateInset(BufferView * bv, int x = 0, int y = 0,
int button = 0);
/* Private structures and variables */
///
int inset_pos;
///
int inset_x;
mutable int inset_x;
///
int inset_y;
mutable int inset_y;
///
int interline_space;
///
@ -190,15 +199,11 @@ private:
///
int selection_end;
///
int old_x;
mutable LyXCursor cursor;
///
int cx;
mutable LyXCursor old_cursor;
///
int cy;
///
int actpos;
///
int actrow;
mutable int actrow;
///
bool no_selection;
///
@ -227,7 +232,6 @@ private:
buffer = it.buffer; // suspect
current_font = it.current_font;
real_current_font = it.real_current_font;
maxWidth = it.maxWidth;
maxAscent = it.maxAscent;
maxDescent = it.maxDescent;
insetWidth = it.insetWidth;
@ -237,10 +241,7 @@ private:
interline_space = it.interline_space;
selection_start = it.selection_start;
selection_end = it.selection_end;
old_x = it.old_x;
cx = it.cx;
cy = it.cy;
actpos = it.actpos;
cursor = it.cursor;
actrow = it.actrow;
no_selection = it.no_selection;
the_locking_inset = it.the_locking_inset; // suspect

View File

@ -4,7 +4,6 @@
*
* LyX, The Document Processor
*
* Copyright 1995 Matthias Ettrich
* Copyright 1995-2000 the LyX Team.
*
* ====================================================== */
@ -92,7 +91,9 @@ public:
///
SPECIALCHAR_CODE,
///
NUMBER_CODE
NUMBER_CODE,
///
TABULAR_CODE
};
enum EDITABLE {
@ -101,6 +102,8 @@ public:
HIGHLY_EDITABLE
};
///
Inset() { owner_ = 0; }
///
virtual ~Inset() {}
///
@ -121,6 +124,12 @@ public:
///
virtual EDITABLE Editable() const;
///
virtual void InsetButtonPress(BufferView *, int, int, int) {}
///
virtual void InsetButtonRelease(BufferView *, int, int, int) {}
///
virtual void InsetMotionNotify(BufferView *, int , int , int) {}
///
bool IsTextInset() const;
///
virtual bool AutoDelete() const;
@ -172,6 +181,20 @@ public:
virtual void init(BufferView *) {}
///
virtual bool InsertInsetAllowed(Inset *) const { return false; }
///
virtual void setInsetName(const char * s) { name = s; }
///
virtual string getInsetName() const { return name; }
///
virtual void setOwner(Inset * inset) { owner_ = inset; }
///
virtual Inset * owner() const { return owner_; }
///
private:
///
Inset * owner_;
///
string name;
};
@ -209,6 +232,8 @@ public:
are not enough.
DISPATCHED = the inset catched the action
DISPATCHED_NOUPDATE = the inset catched the action and no update
is needed here to redraw the inset
FINISHED = the inset must be unlocked as a result
of the action
UNDISPATCHED = the action was not catched, it should be
@ -217,6 +242,7 @@ public:
enum RESULT {
UNDISPATCHED = 0,
DISPATCHED,
DISPATCHED_NOUPDATE,
FINISHED
};
@ -226,10 +252,7 @@ public:
}
///
UpdatableInset() {
scx = mx_scx = 0;
owner_ = 0;
}
UpdatableInset() { scx = mx_scx = 0; }
///
//virtual ~UpdatableInset() {}
///
@ -238,6 +261,10 @@ public:
/// may call ToggleLockedInsetCursor
virtual void ToggleInsetCursor(BufferView *);
///
virtual void ShowInsetCursor(BufferView *);
///
virtual void HideInsetCursor(BufferView *);
///
virtual void GetCursorPos(int &, int &) const {}
///
virtual void InsetButtonPress(BufferView *, int x, int y, int button);
@ -270,7 +297,10 @@ public:
virtual bool UpdateInsetInInset(BufferView *, Inset *)
{ return false; }
///
virtual bool UnlockInsetInInset(BufferView *, Inset *,
virtual bool LockInsetInInset(BufferView *, UpdatableInset *)
{ return false; }
///
virtual bool UnlockInsetInInset(BufferView *, UpdatableInset *,
bool /*lr*/ = false)
{ return false; }
/// An updatable inset could handle lyx editing commands
@ -278,11 +308,7 @@ public:
///
virtual bool isCursorVisible() const { return cursor_visible; }
///
virtual int getMaxWidth(Painter & pain) const;
///
virtual void setOwner(UpdatableInset * inset) { owner_ = inset; }
///
virtual UpdatableInset * owner() { return owner_; }
virtual int getMaxWidth(Painter & pain, UpdatableInset const *) const;
protected:
///
@ -296,8 +322,5 @@ private:
///
int mx_scx;
mutable int scx;
///
UpdatableInset * owner_;
};
#endif

View File

@ -54,6 +54,7 @@ using std::istringstream;
#include "insets/insetert.h"
#include "insets/insetgraphics.h"
#include "insets/insetfoot.h"
#include "insets/insettabular.h"
#include "mathed/formulamacro.h"
#include "toolbar.h"
#include "spellchecker.h" // RVDK_PATCH_5
@ -533,6 +534,7 @@ string LyXFunc::Dispatch(int ac,
// the math inset [asierra060396]
if (owner->view()->available() &&
owner->view()->the_locking_inset) {
UpdatableInset::RESULT result;
if (action > 1
|| (action == LFUN_UNKNOWN_ACTION
&& keyseq.length >= -1)) {
@ -574,10 +576,11 @@ string LyXFunc::Dispatch(int ac,
if (inset)
inset->Edit(owner->view(),slx,sly,0);
return string();
} else if (owner->view()->the_locking_inset->
} else if (((result=owner->view()->the_locking_inset->
LocalDispatch(owner->view(), action,
argument) ==
UpdatableInset::DISPATCHED)
argument)) ==
UpdatableInset::DISPATCHED) ||
(result == UpdatableInset::DISPATCHED_NOUPDATE))
return string();
else {
setMessage(N_("Text mode"));
@ -605,6 +608,12 @@ string LyXFunc::Dispatch(int ac,
Set(CurrentState(owner->view()));
}
return string();
case LFUN_DOWN:
owner->view()->text->CursorDown();
moveCursorUpdate(false);
owner->getMiniBuffer()->
Set(CurrentState(owner->view()));
return string();
default:
break;
}
@ -2048,6 +2057,14 @@ string LyXFunc::Dispatch(int ac,
}
break;
case LFUN_INSET_TABULAR:
{
InsetTabular * new_inset = new InsetTabular(owner->buffer(),2,2);
owner->view()->insertInset(new_inset);
new_inset->Edit(owner->view(), 0, 0, 0);
}
break;
// --- lyxserver commands ----------------------------
case LFUN_CHARATCURSOR:

View File

@ -239,6 +239,8 @@ public:
void SetCursor(LyXParagraph * par,
LyXParagraph::size_type pos,
bool setfont = true) const;
void SetCursor(LyXCursor &, LyXParagraph * par,
LyXParagraph::size_type pos) const;
///
void SetCursorIntern(LyXParagraph * par,
LyXParagraph::size_type pos,

View File

@ -1,5 +1,5 @@
/*
* File: formula.h
* File: formula.C
* Purpose: Implementation of formula inset
* Author: Alejandro Aguilar Sierra <asierra@servidor.unam.mx>
* Created: January 1996
@ -461,7 +461,8 @@ char const * InsetFormula::EditMessage() const
void InsetFormula::Edit(BufferView * bv, int x, int y, unsigned int)
{
mathcursor = new MathedCursor(par);
bv->lockInset(this);
if (!bv->lockInset(this))
lyxerr[Debug::MATHED] << "Cannot lock inset!!!" << endl;
par->Metrics();
bv->updateInset(this, false);
x += par->xo;

View File

@ -644,6 +644,8 @@ void LyXParagraph::InsertInset(LyXParagraph::size_type pos,
"there is an inset in position: " << pos << endl;
else
insetlist.insert(it, InsetTable(pos,inset));
if (inset_owner)
inset->setOwner(inset_owner);
}
}
@ -3483,7 +3485,9 @@ LyXParagraph * LyXParagraph::TeXDeeper(ostream & os, TexRow & texrow,
lyxerr[Debug::LATEX] << "TeXDeeper... " << this << endl;
LyXParagraph * par = this;
while (par && par->depth == depth) {
while (par &&
(par->depth == depth) &&
(par->footnoteflag == footnoteflag)) {
if (par->IsDummy())
lyxerr << "ERROR (LyXParagraph::TeXDeeper)" << endl;
if (textclasslist.Style(current_view->buffer()->params.textclass,
@ -3736,7 +3740,8 @@ LyXParagraph * LyXParagraph::TeXEnvironment(ostream & os, TexRow & texrow,
} while (par
&& par->layout == layout
&& par->depth == depth
&& par->pextra_type == pextra_type);
&& par->pextra_type == pextra_type
&& par->footnoteflag == footnoteflag);
if (style.isEnvironment()) {
os << "\\end{" << style.latexname() << '}';

View File

@ -24,6 +24,8 @@
#include "layout.h"
#include "support/lstrings.h"
#include "support/lyxmanip.h"
#include "lyx_gui_misc.h"
#include "insets/insettext.h"
using std::ostream;
using std::istream;
@ -32,33 +34,162 @@ using std::endl;
static int const WIDTH_OF_LINE = 5;
/// Define a few methods for the inner structs
LyXTable::cellstruct::cellstruct(Buffer * buf)
{
cellno = 0; //should be initilaized correctly later.
width_of_cell = 0;
multicolumn = LyXTable::CELL_NORMAL;
alignment = LYX_ALIGN_CENTER;
top_line = true;
bottom_line = false;
has_cont_row = false;
rotate = false;
linebreaks = false;
buf ? inset = new InsetText(buf): inset = 0;
}
LyXTable::cellstruct::~cellstruct()
{
if (inset)
delete inset;
}
LyXTable::cellstruct &
LyXTable::cellstruct::operator=(cellstruct const & cs)
{
cellno = cs.cellno;
width_of_cell = cs.width_of_cell;
multicolumn = cs.multicolumn;
alignment = cs.alignment;
top_line = cs.top_line;
bottom_line = cs.bottom_line;
has_cont_row = cs.has_cont_row;
rotate = cs.rotate;
linebreaks = cs.linebreaks;
return *this;
}
LyXTable::rowstruct::rowstruct()
{
top_line = true;
bottom_line = false;
is_cont_row = false;
ascent_of_row = 0;
descent_of_row = 0;
newpage = false;
}
// Nothing to do, but gcc 2.7.2.3 wants one... (JMarc)
LyXTable::rowstruct::~rowstruct()
{
}
LyXTable::rowstruct &
LyXTable::rowstruct::operator=(rowstruct const & rs)
{
top_line = rs.top_line;
bottom_line = rs.bottom_line;
is_cont_row = rs.is_cont_row;
ascent_of_row = rs.ascent_of_row;
descent_of_row = rs.descent_of_row;
newpage = rs.newpage;
return *this;
}
LyXTable::columnstruct::columnstruct()
{
left_line = true;
right_line = false;
alignment = LYX_ALIGN_CENTER;
width_of_column = 0;
}
LyXTable::columnstruct::~columnstruct()
{
}
LyXTable::columnstruct &
LyXTable::columnstruct::operator=(columnstruct const & cs)
{
left_line = cs.left_line;
right_line = cs.right_line;
alignment = cs.alignment;
width_of_column = cs.width_of_column;
p_width = cs.p_width;
align_special = cs.align_special;
return *this;
}
/* konstruktor */
LyXTable::LyXTable(int rows_arg, int columns_arg)
LyXTable::LyXTable(int rows_arg, int columns_arg, Buffer *buf)
{
Init(rows_arg, columns_arg);
buffer = buf;
Init(rows_arg, columns_arg);
}
LyXTable::LyXTable(LyXLex & lex)
LyXTable::LyXTable(LyXTable const & lt, Buffer * buf)
{
istream & is = lex.getStream();
Read(is);
buffer = buf;
Init(lt.rows, lt.columns);
operator=(lt);
}
LyXTable::LyXTable(LyXLex & lex, Buffer *buf)
{
istream & is = lex.getStream();
buffer = buf;
Read(is);
}
LyXTable::~LyXTable() {
delete[] rowofcell;
delete[] columnofcell;
delete[] column_info;
delete[] row_info;
for (int i = 0; i < rows; ++i) {
delete[] cell_info[i]; // verify that this shoudn't be freed with delete
}
delete[] cell_info;
LyXTable::~LyXTable()
{
delete[] rowofcell;
delete[] columnofcell;
delete[] column_info;
delete[] row_info;
for (int i = 0; i < rows; ++i) {
delete[] cell_info[i];
}
delete[] cell_info;
}
LyXTable & LyXTable::operator=(LyXTable const & lt)
{
// If this and lt is not of the same size we have a serious bug
// So then it is ok to throw an exception, or for now
// call abort()
Assert(rows == lt.rows && columns == lt.columns);
int row = 0, column = 0;
for (row = 0; row < rows; ++row) {
for (column = 0; column < columns; ++column) {
cell_info[row][column] = lt.cell_info[row][column];
}
}
for (row = 0; row < rows; ++row) {
row_info[row] = lt.row_info[row];
}
for (column = 0; column < columns; ++column) {
column_info[column] = lt.column_info[column];
}
SetLongTable(lt.is_long_table);
rotate = lt.rotate;
Reinit();
return *this;
}
LyXTable * LyXTable::Clone()
{
LyXTable * result = new LyXTable(rows, columns);
@ -101,33 +232,15 @@ void LyXTable::Init(int rows_arg, int columns_arg)
int cellno = 0;
for (i = 0; i < rows; ++i) {
cell_info[i] = new cellstruct[columns];
row_info[i].top_line = true;
row_info[i].bottom_line = false;
row_info[i].is_cont_row = false;
row_info[i].newpage = false;
cell_info[i] = new cellstruct[columns](buffer);
for (j = 0; j < columns; ++j) {
cell_info[i][j].cellno = cellno++;
cell_info[i][j].width_of_cell = 0;
cell_info[i][j].multicolumn = LyXTable::CELL_NORMAL;
cell_info[i][j].alignment = LYX_ALIGN_CENTER;
cell_info[i][j].top_line = row_info[i].top_line;
cell_info[i][j].bottom_line = row_info[i].bottom_line;
cell_info[i][j].has_cont_row = false;
cell_info[i][j].rotate = false;
cell_info[i][j].linebreaks = false;
}
}
row_info[i-1].bottom_line = true;
row_info[0].bottom_line = true;
for (i = 0; i < columns; ++i) {
column_info[i].left_line = true;
column_info[i].right_line = false;
column_info[i].alignment = LYX_ALIGN_CENTER;
// set width_of_column to zero before it is used in
// calculate_width_of_column() (thornley)
column_info[i].width_of_column = 0;
calculate_width_of_column(i);
}
column_info[i-1].right_line = true;
@ -780,7 +893,7 @@ void LyXTable::calculate_width_of_table()
}
int LyXTable::row_of_cell(int cell)
int LyXTable::row_of_cell(int cell) const
{
if (cell >= numberofcells)
return rows-1;
@ -790,7 +903,7 @@ int LyXTable::row_of_cell(int cell)
}
int LyXTable::column_of_cell(int cell)
int LyXTable::column_of_cell(int cell) const
{
if (cell >= numberofcells)
return columns-1;
@ -811,29 +924,30 @@ int LyXTable::right_column_of_cell(int cell)
}
void LyXTable::Write(ostream & os)
void LyXTable::Write(ostream & os, bool old_format)
{
int i, j;
os << "multicol5\n"
<< rows << " " << columns << " " << is_long_table << " "
<< rotate << " " << endhead << " " << endfirsthead << " "
<< endfoot << " " << endlastfoot << "\n";
for (i = 0; i < rows; ++i) {
if (old_format) {
int i, j;
os << "multicol5\n"
<< rows << " " << columns << " " << is_long_table << " "
<< rotate << " " << endhead << " " << endfirsthead << " "
<< endfoot << " " << endlastfoot << "\n";
for (i = 0; i < rows; ++i) {
os << row_info[i].top_line << " "
<< row_info[i].bottom_line << " "
<< row_info[i].is_cont_row << " "
<< row_info[i].newpage << "\n";
}
for (i = 0; i < columns; ++i) {
}
for (i = 0; i < columns; ++i) {
os << column_info[i].alignment << " "
<< column_info[i].left_line << " "
<< column_info[i].right_line << " \""
<< VSpace(column_info[i].p_width).asLyXCommand() << "\" \""
<< column_info[i].align_special << "\"\n";
}
}
for (i = 0; i < rows; ++i) {
for (j = 0; j < columns; ++j) {
for (i = 0; i < rows; ++i) {
for (j = 0; j < columns; ++j) {
os << cell_info[i][j].multicolumn << " "
<< cell_info[i][j].alignment << " "
<< cell_info[i][j].top_line << " "
@ -843,7 +957,10 @@ void LyXTable::Write(ostream & os)
<< cell_info[i][j].linebreaks << " \""
<< cell_info[i][j].align_special << "\" \""
<< cell_info[i][j].p_width << "\"\n";
}
}
}
} else {
lyxerr << "New format type not yet implemented!!!\n" << endl;
}
}
@ -871,13 +988,13 @@ void LyXTable::Read(istream & is)
version = atoi(s.c_str() + 8);
else
version = 1;
#ifdef WITH_WARNINGS
#warning Insert a error message window here that this format is not supported anymore
#endif
if (version < 5) {
lyxerr << "Tabular format < 5 is not supported anymore\n"
"Get an older version of LyX (< 1.1.x) for conversion!"
<< endl;
WriteAlert(_("Warning:"),
_("Tabular format < 5 is not supported anymore\n"),
_("Get an older version of LyX (< 1.1.x) for conversion!"));
if (version > 2) {
is >> rows_arg >> columns_arg >> is_long_table_arg
>> rotate_arg >> a >> b >> c >> d;
@ -1915,3 +2032,60 @@ bool LyXTable::LTNewPage(int cell)
{
return row_info[row_of_cell(cell)].newpage;
}
void LyXTable::SetAscentOfRow(int row, int height)
{
if (row >= rows)
return;
row_info[row].ascent_of_row = height;
}
void LyXTable::SetDescentOfRow(int row, int height)
{
if (row >= rows)
return;
row_info[row].descent_of_row = height;
}
int LyXTable::AscentOfRow(int row)
{
if (row >= rows)
return 0;
return row_info[row].ascent_of_row;
}
int LyXTable::DescentOfRow(int row)
{
if (row >= rows)
return 0;
return row_info[row].descent_of_row;
}
int LyXTable::HeightOfTable()
{
int
height,
row;
for(row=0,height=0;(row<rows); ++row)
height += AscentOfRow(row) + DescentOfRow(row) +
AdditionalHeight(GetCellNumber(0,row));
return height;
}
bool LyXTable::IsPartOfMultiColumn(int row, int column)
{
if ((row >= rows) || (column >= columns))
return false;
return (cell_info[row][column].multicolumn==CELL_PART_OF_MULTICOLUMN);
}
int LyXTable::Latex(ostream &)
{
return 0;
}
InsetText * LyXTable::GetCellInset(int cell) const
{
return cell_info[row_of_cell(cell)][column_of_cell(cell)].inset;
}

View File

@ -20,327 +20,377 @@
#include "lyxlex.h"
#include "LString.h"
class InsetText;
class Buffer;
/* The features the text class offers for tables */
///
class LyXTable {
public:
// Are the values of these enums important? (Lgb)
enum {
APPEND_ROW = 0,
APPEND_COLUMN = 1,
DELETE_ROW = 2,
DELETE_COLUMN = 3,
TOGGLE_LINE_TOP = 4,
TOGGLE_LINE_BOTTOM = 5,
TOGGLE_LINE_LEFT = 6,
TOGGLE_LINE_RIGHT = 7,
ALIGN_LEFT = 8, // what are these alignment enums used for?
ALIGN_RIGHT = 9,
ALIGN_CENTER = 10,
DELETE_TABLE = 11,
MULTICOLUMN = 12,
SET_ALL_LINES = 13,
UNSET_ALL_LINES = 14,
SET_LONGTABLE = 15,
UNSET_LONGTABLE = 16,
SET_PWIDTH = 17,
APPEND_CONT_ROW = 18,
SET_ROTATE_TABLE = 19,
UNSET_ROTATE_TABLE = 20,
SET_ROTATE_CELL = 21,
UNSET_ROTATE_CELL = 22,
SET_LINEBREAKS = 23,
SET_LTHEAD = 24,
SET_LTFIRSTHEAD = 25,
SET_LTFOOT = 26,
SET_LTLASTFOOT = 27,
SET_LTNEWPAGE = 28,
SET_SPECIAL_COLUMN = 29,
SET_SPECIAL_MULTI = 30
};
// Are the values of these enums important? (Lgb)
enum {
APPEND_ROW = 0,
APPEND_COLUMN = 1,
DELETE_ROW = 2,
DELETE_COLUMN = 3,
TOGGLE_LINE_TOP = 4,
TOGGLE_LINE_BOTTOM = 5,
TOGGLE_LINE_LEFT = 6,
TOGGLE_LINE_RIGHT = 7,
ALIGN_LEFT = 8, // what are these alignment enums used for?
ALIGN_RIGHT = 9,
ALIGN_CENTER = 10,
DELETE_TABLE = 11,
MULTICOLUMN = 12,
SET_ALL_LINES = 13,
UNSET_ALL_LINES = 14,
SET_LONGTABLE = 15,
UNSET_LONGTABLE = 16,
SET_PWIDTH = 17,
APPEND_CONT_ROW = 18,
SET_ROTATE_TABLE = 19,
UNSET_ROTATE_TABLE = 20,
SET_ROTATE_CELL = 21,
UNSET_ROTATE_CELL = 22,
SET_LINEBREAKS = 23,
SET_LTHEAD = 24,
SET_LTFIRSTHEAD = 25,
SET_LTFOOT = 26,
SET_LTLASTFOOT = 27,
SET_LTNEWPAGE = 28,
SET_SPECIAL_COLUMN = 29,
SET_SPECIAL_MULTI = 30
};
enum {
CELL_NORMAL = 0,
CELL_BEGIN_OF_MULTICOLUMN = 1,
CELL_PART_OF_MULTICOLUMN = 2
};
/* konstruktor */
///
LyXTable(int columns_arg, int rows_arg);
///
explicit
LyXTable(LyXLex & lex);
///
~LyXTable();
///
LyXTable * Clone();
/// Returns true if there is a topline, returns false if not
bool TopLine(int cell);
/// Returns true if there is a topline, returns false if not
bool BottomLine(int cell);
/// Returns true if there is a topline, returns false if not
bool LeftLine(int cell);
/// Returns true if there is a topline, returns false if not
bool RightLine(int cell);
enum {
CELL_NORMAL = 0,
CELL_BEGIN_OF_MULTICOLUMN = 1,
CELL_PART_OF_MULTICOLUMN = 2
};
/* konstruktor */
///
LyXTable(int columns_arg, int rows_arg, Buffer *buf = 0);
///
///
LyXTable(LyXTable const &, Buffer *buf = 0);
///
explicit
LyXTable(LyXLex & lex, Buffer *buf = 0);
///
~LyXTable();
///
LyXTable & operator=(LyXTable const &);
///
LyXTable * Clone();
/// Returns true if there is a topline, returns false if not
bool TopLine(int cell);
/// Returns true if there is a topline, returns false if not
bool BottomLine(int cell);
/// Returns true if there is a topline, returns false if not
bool LeftLine(int cell);
/// Returns true if there is a topline, returns false if not
bool RightLine(int cell);
///
bool TopAlreadyDrawed(int cell);
///
bool VeryLastRow(int cell);
///
int AdditionalHeight(int cell);
///
int AdditionalWidth(int cell);
/* returns the maximum over all rows */
///
int WidthOfColumn(int cell);
///
int WidthOfTable();
///
int AscentOfRow(int row);
///
int DescentOfRow(int row);
///
int HeightOfTable();
///
void SetAscentOfRow(int row, int height);
///
void SetDescentOfRow(int row, int height);
/// Returns true if a complete update is necessary, otherwise false
bool SetWidthOfCell(int cell, int new_width);
/// Returns true if a complete update is necessary, otherwise false
bool SetAllLines(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetTopLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetBottomLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetLeftLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetRightLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetAlignment(int cell, char align);
///
bool SetPWidth(int cell, string width);
///
bool SetAlignSpecial(int cell, string special, int what);
///
char GetAlignment(int cell); // add approp. signedness
///
string GetPWidth(int cell);
///
string GetAlignSpecial(int cell, int what);
///
int GetWidthOfCell(int cell);
///
int GetBeginningOfTextInCell(int cell);
///
void AppendRow(int cell);
///
void DeleteRow(int cell);
///
void AppendColumn(int cell);
///
void DeleteColumn(int cell);
///
bool IsFirstCell(int cell);
///
bool IsLastCell(int cell);
///
int GetNumberOfCells();
///
int AppendCellAfterCell(int append_cell, int question_cell);
///
int DeleteCellIfColumnIsDeleted(int cell, int delete_column_cell);
///
int NumberOfCellsInRow(int cell);
///
void Reinit();
///
bool TopAlreadyDrawed(int cell);
///
bool VeryLastRow(int cell);
void Init(int columns_arg, int rows_arg);
///
int AdditionalHeight(int cell);
///
int AdditionalWidth(int cell);
/* returns the maximum over all rows */
///
int WidthOfColumn(int cell);
///
int WidthOfTable();
/// Returns true if a complete update is necessary, otherwise false
bool SetWidthOfCell(int cell, int new_width);
/// Returns true if a complete update is necessary, otherwise false
bool SetAllLines(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetTopLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetBottomLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetLeftLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetRightLine(int cell, bool line);
/// Returns true if a complete update is necessary, otherwise false
bool SetAlignment(int cell, char align);
///
bool SetPWidth(int cell, string width);
///
bool SetAlignSpecial(int cell, string special, int what);
///
char GetAlignment(int cell); // add approp. signedness
///
string GetPWidth(int cell);
///
string GetAlignSpecial(int cell, int what);
///
void Write(std::ostream &, bool old_format=true);
///
void Read(std::istream &);
///
int Latex(std::ostream &);
///
int GetWidthOfCell(int cell);
///
int GetBeginningOfTextInCell(int cell);
///
void AppendRow(int cell);
///
void DeleteRow(int cell);
///
void AppendColumn(int cell);
///
void DeleteColumn(int cell);
///
bool IsFirstCell(int cell);
///
bool IsLastCell(int cell);
///
int GetNumberOfCells();
///
int AppendCellAfterCell(int append_cell, int question_cell);
///
int DeleteCellIfColumnIsDeleted(int cell, int delete_column_cell);
///
int NumberOfCellsInRow(int cell);
///
void Reinit();
///
void Init(int columns_arg, int rows_arg);
///
void Write(std::ostream &);
///
void Read(std::istream &);
// cell <0 will tex the preamble
// returns the number of printed newlines
///
int TexEndOfCell(std::ostream &, int cell);
///
int DocBookEndOfCell(std::ostream &, int cell, int & depth);
// cell <0 will tex the preamble
// returns the number of printed newlines
///
int TexEndOfCell(std::ostream &, int cell);
///
int DocBookEndOfCell(std::ostream &, int cell, int & depth);
#if 0
///
int RoffEndOfCell(std::ostream &, int cell);
///
int RoffEndOfCell(std::ostream &, int cell);
#endif
///
char const * getDocBookAlign(int cell, bool isColumn = false);
///
char const * getDocBookAlign(int cell, bool isColumn = false);
///
bool IsMultiColumn(int cell);
///
void SetMultiColumn(int cell, int number);
///
int UnsetMultiColumn(int cell); // returns number of new cells
///
int row_of_cell(int cell);
///
int column_of_cell(int cell);
///
int rows;
///
int columns;
///
void SetLongTable(int what);
///
bool IsLongTable();
///
void SetRotateTable(int what);
///
bool RotateTable();
///
void SetRotateCell(int cell, int what);
///
bool RotateCell(int cell);
///
bool NeedRotating();
///
void AppendContRow(int cell);
///
bool IsContRow(int cell);
/// returns the number of the cell which continues
/// or -1 if no ContRow
int CellHasContRow(int cell);
///
bool RowHasContRow(int cell);
///
int FirstVirtualCell(int cell);
///
int NextVirtualCell(int cell);
///
bool ShouldBeVeryLastCell(int cell);
///
bool ShouldBeVeryLastRow(int cell);
///
int GetCellAbove(int cell);
///
int GetCellNumber(int column, int row);
///
void SetLinebreaks(int cell, bool what);
///
bool Linebreaks(int cell);
///
/// Long Table Options
///
void SetLTHead(int cell, bool first);
///
bool RowOfLTHead(int cell);
///
bool RowOfLTFirstHead(int cell);
///
void SetLTFoot(int cell, bool last);
///
bool RowOfLTFoot(int cell);
///
bool RowOfLTLastFoot(int cell);
///
void SetLTNewPage(int cell, bool what);
///
bool LTNewPage(int cell);
private:
///
struct cellstruct {
///
int cellno;
///
int width_of_cell;
///
int multicolumn; // add approp. signedness
///
int alignment; // add approp. signedness
///
bool top_line;
///
bool bottom_line;
///
bool has_cont_row;
///
bool linebreaks;
///
int rotate;
///
string align_special;
///
string p_width; // this is only set for multicolumn!!!
};
///
struct rowstruct {
bool top_line;
bool bottom_line;
bool is_cont_row;
/// This are for longtables only
bool newpage;
};
///
struct columnstruct {
int alignment; // add approp. signedness
bool left_line;
bool right_line;
int width_of_column;
string p_width;
string align_special;
};
///
int numberofcells;
///
int * rowofcell;
///
int * columnofcell;
///
void set_row_column_number_info();
///
bool IsMultiColumn(int cell);
///
void SetMultiColumn(int cell, int number);
///
int UnsetMultiColumn(int cell); // returns number of new cells
///
bool IsPartOfMultiColumn(int row, int column);
///
int row_of_cell(int cell) const;
///
int column_of_cell(int cell) const;
///
int rows;
///
int columns;
///
void SetLongTable(int what);
///
bool IsLongTable();
///
void SetRotateTable(int what);
///
bool RotateTable();
///
void SetRotateCell(int cell, int what);
///
bool RotateCell(int cell);
///
bool NeedRotating();
///
void AppendContRow(int cell);
///
bool IsContRow(int cell);
/// returns the number of the cell which continues
/// or -1 if no ContRow
int CellHasContRow(int cell);
///
bool RowHasContRow(int cell);
///
int FirstVirtualCell(int cell);
///
int NextVirtualCell(int cell);
///
bool ShouldBeVeryLastCell(int cell);
///
bool ShouldBeVeryLastRow(int cell);
///
int GetCellAbove(int cell);
///
int GetCellNumber(int column, int row);
///
void SetLinebreaks(int cell, bool what);
///
bool Linebreaks(int cell);
///
/// Long Table Options
///
void SetLTHead(int cell, bool first);
///
bool RowOfLTHead(int cell);
///
bool RowOfLTFirstHead(int cell);
///
void SetLTFoot(int cell, bool last);
///
bool RowOfLTFoot(int cell);
///
bool RowOfLTLastFoot(int cell);
///
void SetLTNewPage(int cell, bool what);
///
bool LTNewPage(int cell);
///
InsetText * GetCellInset(int cell) const;
///
private: //////////////////////////////////////////////////////////////////
///
struct cellstruct {
///
rowstruct * row_info;
///
columnstruct * column_info;
///
cellstruct ** cell_info;
cellstruct(Buffer * buf = 0);
///
int width_of_table;
///
/// for long tables
///
int endhead; // row of endhead
int endfirsthead; // row of endfirsthead
int endfoot; // row of endfoot
int endlastfoot; // row of endlastfoot
/// Returns true if a complete update is necessary, otherwise false
bool SetWidthOfMulticolCell(int cell, int new_width);
void recalculateMulticolCells(int cell, int new_width);
/// Returns true if change
bool calculate_width_of_column(int column);
bool calculate_width_of_column_NMC(int column); // no multi cells
~cellstruct();
///
void calculate_width_of_table();
///
int right_column_of_cell(int cell);
cellstruct & operator=(cellstruct const &);
///
cellstruct * cellinfo_of_cell(int cell);
int cellno;
///
void delete_column(int column);
int width_of_cell;
///
int cells_in_multicolumn(int cell);
int multicolumn; // add approp. signedness
///
int is_long_table;
int alignment; // add approp. signedness
///
bool top_line;
///
bool bottom_line;
///
bool has_cont_row;
///
bool linebreaks;
///
int rotate;
///
string align_special;
///
string p_width; // this is only set for multicolumn!!!
///
InsetText *inset;
};
///
struct rowstruct {
///
rowstruct();
///
~rowstruct();
///
rowstruct & operator=(rowstruct const &);
///
bool top_line;
bool bottom_line;
bool is_cont_row;
int ascent_of_row;
int descent_of_row;
/// This are for longtables only
bool newpage;
};
///
struct columnstruct {
///
columnstruct();
///
~columnstruct();
///
columnstruct & operator=(columnstruct const &);
///
int alignment; // add approp. signedness
bool left_line;
bool right_line;
int width_of_column;
string p_width;
string align_special;
};
///
int numberofcells;
///
int * rowofcell;
///
int * columnofcell;
///
rowstruct * row_info;
///
columnstruct * column_info;
///
cellstruct ** cell_info;
///
int width_of_table;
///
/// for long tables
///
int endhead; // row of endhead
int endfirsthead; // row of endfirsthead
int endfoot; // row of endfoot
int endlastfoot; // row of endlastfoot
///
Buffer *buffer;
///
void set_row_column_number_info();
/// Returns true if a complete update is necessary, otherwise false
bool SetWidthOfMulticolCell(int cell, int new_width);
void recalculateMulticolCells(int cell, int new_width);
/// Returns true if change
bool calculate_width_of_column(int column);
bool calculate_width_of_column_NMC(int column); // no multi cells
///
void calculate_width_of_table();
///
int right_column_of_cell(int cell);
///
cellstruct * cellinfo_of_cell(int cell);
///
void delete_column(int column);
///
int cells_in_multicolumn(int cell);
///
int is_long_table;
///
int rotate;
};
#endif

View File

@ -3156,10 +3156,136 @@ void LyXText::SetCursor(LyXParagraph * par,
DeleteEmptyParagraphMechanism(old_cursor);
}
void LyXText::SetCursor(LyXCursor & cur, LyXParagraph * par,
LyXParagraph::size_type pos) const
{
// correct the cursor position if impossible
if (pos > par->Last()){
LyXParagraph * tmppar = par->ParFromPos(pos);
pos = par->PositionInParFromPos(pos);
par = tmppar;
}
if (par->IsDummy() && par->previous &&
par->previous->footnoteflag == LyXParagraph::CLOSED_FOOTNOTE) {
while (par->previous &&
((par->previous->IsDummy() &&
(par->previous->previous->footnoteflag ==
LyXParagraph::CLOSED_FOOTNOTE)) ||
(par->previous->footnoteflag ==
LyXParagraph::CLOSED_FOOTNOTE))) {
par = par->previous ;
if (par->IsDummy() &&
(par->previous->footnoteflag ==
LyXParagraph::CLOSED_FOOTNOTE))
pos += par->size() + 1;
}
if (par->previous) {
par = par->previous;
}
pos += par->size() + 1;
}
cur.par = par;
cur.pos = pos;
/* get the cursor y position in text */
long y = 0;
Row * row = GetRow(par, pos, y);
/* y is now the beginning of the cursor row */
y += row->baseline;
/* y is now the cursor baseline */
cur.y = y;
/* now get the cursors x position */
float x;
float fill_separator, fill_hfill, fill_label_hfill;
PrepareToPrint(row, x, fill_separator, fill_hfill, fill_label_hfill);
LyXParagraph::size_type cursor_vpos;
LyXParagraph::size_type last = RowLastPrintable(row);
if (pos > last + 1) // This shouldn't happen.
pos = last+1;
if (last < row->pos)
cursor_vpos = 0;
else if ((pos > last) ||
((pos - 1 >= row->pos) &&
(row->par->IsSeparator(pos) ||
(row->par->table && row->par->IsNewline(pos)))))
/// Place cursor after char at (logical) position pos-1
cursor_vpos = !(bidi_level(pos-1) % 2)
? log2vis(pos-1) + 1 : log2vis(pos-1);
else
/// Place cursor before char at (logical) position pos
cursor_vpos = !(bidi_level(pos) % 2)
? log2vis(pos) : log2vis(pos) + 1;
/* table stuff -- begin*/
if (row->par->table) {
int cell = NumberOfCell(row->par, row->pos);
float x_old = x;
x += row->par->table->GetBeginningOfTextInCell(cell);
for (LyXParagraph::size_type vpos = row->pos;
vpos < cursor_vpos; ++vpos) {
pos = vis2log(vpos);
if (row->par->IsNewline(pos)) {
x = x_old + row->par->table->WidthOfColumn(cell);
x_old = x;
++cell;
x += row->par->table->GetBeginningOfTextInCell(cell);
} else {
x += SingleWidth(row->par, pos);
}
}
} else {
/* table stuff -- end*/
LyXParagraph::size_type main_body =
BeginningOfMainBody(row->par);
if ((main_body > 0) &&
((main_body-1 > last) ||
!row->par->IsLineSeparator(main_body-1)))
main_body = 0;
for (LyXParagraph::size_type vpos = row->pos;
vpos < cursor_vpos; ++vpos) {
pos = vis2log(vpos);
if (main_body > 0 && pos == main_body-1) {
x += fill_label_hfill +
lyxfont::width(textclasslist.Style(
buffer->params.textclass,
row->par->GetLayout())
.labelsep,
GetFont(row->par, -2));
if (row->par->IsLineSeparator(main_body-1))
x -= SingleWidth(row->par,main_body-1);
}
if (HfillExpansion(row, pos)) {
x += SingleWidth(row->par, pos);
if (pos >= main_body)
x += fill_hfill;
else
x += fill_label_hfill;
} else if (row->par->IsSeparator(pos)) {
x += SingleWidth(row->par, pos);
if (pos >= main_body)
x += fill_separator;
} else
x += SingleWidth(row->par, pos);
}
}
cur.x = int(x);
cur.x_fix = cur.x;
cur.row = row;
}
void LyXText::SetCursorIntern(LyXParagraph * par,
LyXParagraph::size_type pos, bool setfont) const
{
SetCursor(cursor, par, pos);
#warning Remove this when verified working (Jug 20000413)
#if 0
// correct the cursor position if impossible
if (pos > par->Last()){
LyXParagraph * tmppar = par->ParFromPos(pos);
@ -3185,18 +3311,6 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
cursor.par = par;
cursor.pos = pos;
if (setfont)
if (cursor.pos &&
(cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos)
|| (cursor.par->table && cursor.par->IsNewline(cursor.pos))
)) {
current_font = cursor.par->GetFontSettings(cursor.pos - 1);
real_current_font = GetFont(cursor.par, cursor.pos - 1);
} else {
current_font = cursor.par->GetFontSettings(cursor.pos);
real_current_font = GetFont(cursor.par, cursor.pos);
}
/* get the cursor y position in text */
long y = 0;
Row * row = GetRow(par, pos, y);
@ -3287,6 +3401,19 @@ void LyXText::SetCursorIntern(LyXParagraph * par,
cursor.x_fix = cursor.x;
cursor.row = row;
#endif
if (setfont) {
if (cursor.pos &&
(cursor.pos == cursor.par->Last() || cursor.par->IsSeparator(cursor.pos)
|| (cursor.par->table && cursor.par->IsNewline(cursor.pos))
)) {
current_font = cursor.par->GetFontSettings(cursor.pos - 1);
real_current_font = GetFont(cursor.par, cursor.pos - 1);
} else {
current_font = cursor.par->GetFontSettings(cursor.pos);
real_current_font = GetFont(cursor.par, cursor.pos);
}
}
}