From 756af0279404b9dba9918dbbbe1c1f8d51d9fe85 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrgen=20Vigna?= Date: Mon, 15 May 2000 14:49:36 +0000 Subject: [PATCH] Lots of fixes for text/tabular insets. Now tabular insets work quite good and you have now automatic row-breaking for cells with width! Also added the fix from Denkel. See ChangeLog. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@732 a592a061-630c-0410-9148-cb99ea01b6c8 --- ChangeLog | 47 ++++ src/BufferView.h | 3 +- src/BufferView2.C | 17 +- src/TableLayout.C | 9 +- src/TabularLayout.C | 39 ++-- src/insets/inset.C | 6 +- src/insets/insetcollapsable.C | 24 ++- src/insets/insetcollapsable.h | 2 +- src/insets/insetlof.h | 2 + src/insets/insetlot.h | 2 + src/insets/insettabular.C | 235 ++++++++++++++------ src/insets/insettabular.h | 21 +- src/insets/insettext.C | 283 ++++++++++++------------ src/insets/insettext.h | 26 ++- src/insets/lyxinset.h | 19 +- src/lyxfunc.C | 90 +++++--- src/mathed/formula.C | 6 + src/mathed/formula.h | 1 + src/mathed/formulamacro.C | 6 + src/mathed/math_write.C | 3 +- src/tabular.C | 390 +++++++++++++++++++++++++++------- src/tabular.h | 40 ++-- src/text.C | 1 - src/vspace.C | 13 +- src/vspace.h | 2 + 25 files changed, 908 insertions(+), 379 deletions(-) diff --git a/ChangeLog b/ChangeLog index a844e75457..ed54c8e7cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +2000-05-15 Juergen Vigna + + * src/insets/insetcollapsable.C (draw): enhancements in drawing and + width calculating. + + * src/insets/insettext.C (computeTextRows): redone completely this + function in a much cleaner way, because of problems when having a + fixed maxWidth. + (draw): added a frame border when the inset is locked. + (SetDrawLockedFrame): this sets if we draw the border or not. + (SetFrameColor): this sets the frame color (default=insetframe). + + * src/insets/lyxinset.h: added x() and y() functions which return + the top_x and top_baseline values. Added a GetFirstLockingInsetOfType + function which is needed to see if we have a locking inset of some + type in this inset (needed for now in insettabular). + + * src/vspace.C (inPixels): the same function also without a BufferView + parameter as so it is easier to use it in some ocasions. + + * src/lyxfunc.C: changed all places where insertInset was used so + that now if it couldn't be inserted it is deleted! + + * src/TabularLayout.C: + * src/TableLayout.C: added support for new tabular-inset! + + * src/BufferView2.C (insertInset): this now returns a bool if the + inset was really inserted!!! + + * src/tabular.C (GetLastCellInRow): + (GetFirstCellInRow): new helper functions. + (Latex): implemented for new tabular class. + (TeXCellPostamble): + (TeXCellPreamble): + (TeXBottomHLine): + (TeXTopHLine): new Latex() helper functions. + +2000-05-12 Juergen Vigna + + * src/mathed/formulamacro.C (Read): + * src/mathed/formula.C (Read): read also the \end_inset here! + +2000-05-10 Dekel Tsur + + * src/mathed/math_write.C (MathParInset::Write): Fixed a bug: + crush when saving formulae with unbalanced parenthesis. + 20000-05-11 Dekel Tsur * src/layout.C: Add new keyword "endlabelstring" to layout file diff --git a/src/BufferView.h b/src/BufferView.h index 25f536e785..766f48f737 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -22,6 +22,7 @@ class LyXView; class LyXText; class TeXErrors; +class Buffer; /// class BufferView { @@ -151,7 +152,7 @@ public: /** Insert an inset into the buffer Insert inset into buffer, placing it in a layout of lout, if no_table make sure that it doesn't end up in a table. */ - void insertInset(Inset * inset, string const & lout = string(), + bool insertInset(Inset * inset, string const & lout = string(), bool no_table = false); /// open and lock an updatable inset void open_new_inset(UpdatableInset * new_inset); diff --git a/src/BufferView2.C b/src/BufferView2.C index f757c78bcd..41d8d8eb21 100644 --- a/src/BufferView2.C +++ b/src/BufferView2.C @@ -184,16 +184,26 @@ void BufferView::setCursorFromRow(int row) text->SetCursor(texrowpar, tmppos); } -void BufferView::insertInset(Inset * inset, string const & lout, +bool BufferView::insertInset(Inset * inset, string const & lout, bool no_table) { + // if we are in a locking inset we should try to insert the + // inset there otherwise this is a illegal function now + if (the_locking_inset) { + if (the_locking_inset->InsertInsetAllowed(inset) && + the_locking_inset->InsertInset(this, inset)) + return true; + return false; + } + // check for table/list in tables if (no_table && text->cursor.par->table){ WriteAlert(_("Impossible Operation!"), _("Cannot insert table/list in table."), _("Sorry.")); - return; + return false; } + // not quite sure if we want this... text->SetCursorParUndo(); text->FreezeUndo(); @@ -252,7 +262,8 @@ void BufferView::insertInset(Inset * inset, string const & lout, #endif update(-1); - text->UnFreezeUndo(); + text->UnFreezeUndo(); + return true; } diff --git a/src/TableLayout.C b/src/TableLayout.C index 8acf303bdc..56ae4832af 100644 --- a/src/TableLayout.C +++ b/src/TableLayout.C @@ -40,9 +40,7 @@ static int extra_col_cursor_x; // need no y's, one-line input fields static int extra_multicol_cursor_x; // Joacim -#define IS_TABULAR (current_view->the_locking_inset && \ - (current_view->the_locking_inset->LyxCode() == \ - Inset::TABULAR_CODE)) +#define IS_TABULAR (current_view->the_locking_inset != 0) bool UpdateLayoutTable(int flag) { @@ -219,8 +217,6 @@ bool UpdateLayoutTable(int flag) table->RotateTable()); fl_set_focus_object(fd_form_table_options->form_table_options, fd_form_table_options->button_table_delete); - } else if (update && IS_TABULAR) { - UpdateLayoutTabular(flag); } else if (fd_form_table_options->form_table_options->visible) { fl_set_focus_object(fd_form_table_options->form_table_options, fd_form_table_options->button_table_delete); @@ -249,7 +245,6 @@ void OpenLayoutTableExtra() } } - void MenuLayoutTable(int flag) { if (UpdateLayoutTable(flag)) { @@ -475,7 +470,7 @@ void TableSpeCloseCB(FL_OBJECT *, long) void SetPWidthCB(FL_OBJECT * ob, long l) { if (IS_TABULAR) { - SetPWidthCB(ob, l); + SetPWidthTabularCB(ob, l); return; } diff --git a/src/TabularLayout.C b/src/TabularLayout.C index 3dc106ccf8..7bd052fa59 100644 --- a/src/TabularLayout.C +++ b/src/TabularLayout.C @@ -24,6 +24,7 @@ extern FD_form_table_extra * fd_form_table_extra; extern BufferView * current_view; extern void OpenLayoutTableExtra(); +extern bool UpdateLayoutTabular(bool); static int Confirmed = false; static int ActCell; @@ -38,20 +39,38 @@ static int extra_col_cursor_x; // need no y's, one-line input fields static int extra_multicol_cursor_x; // Joacim +static InsetTabular * inset = 0; -bool UpdateLayoutTabular(int flag) +void MenuLayoutTabular(bool flag, InsetTabular * ins) { + inset = ins; + if (!inset) + return; + if (UpdateLayoutTabular(flag)) { + if (fd_form_table_options->form_table_options->visible) { + fl_raise_form(fd_form_table_options->form_table_options); + } + else { + fl_show_form(fd_form_table_options->form_table_options, + FL_PLACE_MOUSE, FL_FULLBORDER, + _("Table Layout")); + } + } +} + +bool UpdateLayoutTabular(bool flag) +{ + if (!inset) + return false; + bool update = true; if (!current_view->available()) update = false; - if (update && current_view->the_locking_inset && - (current_view->the_locking_inset->LyxCode() == Inset::TABULAR_CODE)) { + if (update) { char buf[12]; string pwidth, special; - InsetTabular * inset = static_cast - (current_view->the_locking_inset); LyXTabular * table = inset->tabular; int cell = inset->GetActCell(); @@ -226,16 +245,13 @@ bool UpdateLayoutTabular(int flag) void TabularOptionsCB(FL_OBJECT * ob, long) { - if (!current_view->available() || !current_view->the_locking_inset || - (current_view->the_locking_inset->LyxCode() != Inset::TABULAR_CODE)) { + if (!inset) { MenuLayoutTable(0); return; } int s, num = 0; string special, str; - InsetTabular * inset = static_cast - (current_view->the_locking_inset); LyXTabular * table = inset->tabular; int cell = inset->GetActCell(); @@ -407,12 +423,9 @@ void TabularOptionsCB(FL_OBJECT * ob, long) void SetPWidthTabularCB(FL_OBJECT * ob, long) { - if (!current_view->available() || !current_view->the_locking_inset || - (current_view->the_locking_inset->LyxCode() != Inset::TABULAR_CODE)) { + if (!inset) { return; } - InsetTabular * inset = static_cast - (current_view->the_locking_inset); fl_set_object_label(fd_form_table_options->text_warning, ""); Confirmed = false; diff --git a/src/insets/inset.C b/src/insets/inset.C index c07a0f384c..0cb824c21f 100644 --- a/src/insets/inset.C +++ b/src/insets/inset.C @@ -145,7 +145,7 @@ void UpdatableInset::draw(Painter &, LyXFont const &, int /* baseline */, float & x) const { if (scx) x += float(scx); -// ATTENTION: this is not good doing here +// ATTENTION: don't do the following here!!! // top_x = int(x); // top_baseline = baseline; } @@ -179,9 +179,9 @@ UpdatableInset::LocalDispatch(BufferView *, int, string const &) return UNDISPATCHED; } -int UpdatableInset::getMaxWidth(Painter & pain, UpdatableInset const *inset) const +int UpdatableInset::getMaxWidth(Painter & pain, UpdatableInset const *) const { if (owner()) - return static_cast(owner())->getMaxWidth(pain, inset); + return static_cast(owner())->getMaxWidth(pain, this); return pain.paperWidth(); } diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index 9cbad721e9..8af5d6d76b 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -30,7 +30,7 @@ InsetCollapsable::InsetCollapsable(Buffer * bf) autocollapse = true; autoBreakRows = true; framecolor = LColor::footnoteframe; - widthOffset = 10; + widthOffset = 6; // 2+2 (behind+back), 1+1 (frame) button_length = button_top_y = button_bottom_y = 0; setInsetName("Collapsable"); } @@ -120,15 +120,17 @@ int InsetCollapsable::width(Painter & pain, LyXFont const & font) const if (collapsed) return width_collapsed(pain, font); - return getMaxWidth(pain, this) - widthOffset + 2; + return InsetText::width(pain, font) + width_collapsed(pain,font) + + widthOffset; } -void InsetCollapsable::draw_collapsed(Painter & pain, LyXFont const &, +void InsetCollapsable::draw_collapsed(Painter & pain, LyXFont const & font, int baseline, float & x) const { int width = 0; - pain.buttonText(int(x) + TEXT_TO_INSET_OFFSET, baseline, + pain.buttonText(int(x) + TEXT_TO_INSET_OFFSET, + baseline-ascent(pain, font)+ascent_collapsed(pain, font), label.c_str(), labelfont, true, width); x += width + (2 * TEXT_TO_INSET_OFFSET); } @@ -148,14 +150,14 @@ void InsetCollapsable::draw(Painter & pain, LyXFont const & f, int top_x = int(x); draw_collapsed(pain, f, baseline, x); - x += 2; + x -= TEXT_TO_INSET_OFFSET; - int w = getMaxTextWidth(pain, this); + int w = InsetText::width(pain, f) + TEXT_TO_INSET_OFFSET; int h = ascent(pain,f) + descent(pain, f); pain.rectangle(int(x), baseline - ascent(pain, f), w, h, framecolor); - x += 4; + x += TEXT_TO_INSET_OFFSET; drawTextXOffset = int(x) - top_x; InsetText::draw(pain, f, baseline, x); } @@ -243,15 +245,15 @@ int InsetCollapsable::getMaxWidth(Painter & pain, return static_cast(owner())->getMaxWidth(pain,inset); if (owner()) return static_cast(owner())->getMaxWidth(pain,inset)- - width_collapsed(pain, labelfont) - 2 - widthOffset; + width_collapsed(pain, labelfont) - widthOffset; - return pain.paperWidth()-width_collapsed(pain, labelfont)-2-widthOffset; + return pain.paperWidth()-width_collapsed(pain, labelfont) - widthOffset; } int InsetCollapsable::getMaxTextWidth(Painter & pain, - UpdatableInset const * inset, int) const + UpdatableInset const * inset) const { return getMaxWidth(pain, inset) - - width_collapsed(pain, labelfont) - widthOffset - 2; + width_collapsed(pain, labelfont) - widthOffset; } diff --git a/src/insets/insetcollapsable.h b/src/insets/insetcollapsable.h index 0fe13d317a..1dc504afa1 100644 --- a/src/insets/insetcollapsable.h +++ b/src/insets/insetcollapsable.h @@ -87,7 +87,7 @@ protected: /// void UpdateLocal(BufferView *, bool); /// - int getMaxTextWidth(Painter & pain, UpdatableInset const *, int x=0) const; + int getMaxTextWidth(Painter & pain, UpdatableInset const *) const; /// bool collapsed; diff --git a/src/insets/insetlof.h b/src/insets/insetlof.h index 20e9790c5d..40a7107268 100644 --- a/src/insets/insetlof.h +++ b/src/insets/insetlof.h @@ -21,6 +21,8 @@ #pragma interface #endif +class Buffer; + /** Used to insert table of contents */ class InsetLOF : public InsetCommand { diff --git a/src/insets/insetlot.h b/src/insets/insetlot.h index b98789eff5..1d13914f42 100644 --- a/src/insets/insetlot.h +++ b/src/insets/insetlot.h @@ -21,6 +21,8 @@ // Created by Lgb 970527 +class Buffer; + /** Used to insert table of contents */ class InsetLOT : public InsetCommand { diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index f010299dbf..ca22dd95b4 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -32,7 +32,7 @@ #include "lyxfunc.h" #include "insets/insettext.h" -extern bool MenuLayoutTable(int); +extern void MenuLayoutTabular(bool, InsetTabular *); const int ADD_TO_HEIGHT = 2; const int ADD_TO_TABULAR_WIDTH = 2; @@ -49,30 +49,29 @@ InsetTabular::InsetTabular(Buffer * buf, int rows, int columns) rows = 1; if (columns <= 0) columns = 1; - tabular = new LyXTabular(rows,columns,buf); + buffer = buf; // set this first!!! + tabular = new LyXTabular(this, rows,columns); // for now make it always display as display() inset // just for test!!! - tabular->SetLongTabular(true); the_locking_inset = 0; - buffer = buf; cursor_visible = false; cursor.x_fix = -1; actcell = cursor.pos = sel_pos_start = sel_pos_end = 0; no_selection = false; - init = true; + init_inset = true; } InsetTabular::InsetTabular(InsetTabular const & tab, Buffer * buf) { - tabular = new LyXTabular(*(tab.tabular), buf); + buffer = buf; // set this first + tabular = new LyXTabular(this, *(tab.tabular)); the_locking_inset = 0; - buffer = buf; cursor_visible = false; cursor.x_fix = -1; actcell = cursor.pos = sel_pos_start = sel_pos_end = 0; no_selection = false; - init = true; + init_inset = true; } @@ -103,7 +102,7 @@ void InsetTabular::Read(LyXLex & lex) if (tabular) delete tabular; - tabular = new LyXTabular(lex, buffer); + tabular = new LyXTabular(this, lex); lex.nextToken(); token = lex.GetString(); @@ -115,16 +114,15 @@ void InsetTabular::Read(LyXLex & lex) lex.printError("Missing \\end_inset at this point. " "Read: `$$Token'"); } - tabular->SetLongTabular(true); - init = true; + init_inset = true; } int InsetTabular::ascent(Painter & pain, LyXFont const & font) const { - if (init) { + if (init_inset) { calculate_width_of_cells(pain, font); - init = false; + init_inset = false; } return tabular->GetAscentOfRow(0); } @@ -132,9 +130,9 @@ int InsetTabular::ascent(Painter & pain, LyXFont const & font) const int InsetTabular::descent(Painter & pain, LyXFont const & font) const { - if (init) { + if (init_inset) { calculate_width_of_cells(pain, font); - init = false; + init_inset = false; } return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0); } @@ -142,9 +140,9 @@ int InsetTabular::descent(Painter & pain, LyXFont const & font) const int InsetTabular::width(Painter & pain, LyXFont const & font) const { - if (init) { + if (init_inset) { calculate_width_of_cells(pain, font); - init = false; + init_inset = false; } return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH); } @@ -156,16 +154,25 @@ void InsetTabular::draw(Painter & pain, const LyXFont & font, int baseline, int i, j, cell=0; int nx; float cx; + bool reinit = false; UpdatableInset::draw(pain,font,baseline,x); - if ((top_x != int(x)) || (top_baseline != baseline)) { + if (init_inset || (top_x != int(x)) || (top_baseline != baseline)) { + int ox = top_x; + init_inset = false; top_x = int(x); top_baseline = baseline; + if (ox != top_x) + recomputeTextInsets(pain, font); + calculate_width_of_cells(pain, font); resetPos(pain); + reinit = true; } for(i=0;irows();++i) { nx = int(x); for(j=0;jcolumns();++j) { + if (tabular->IsPartOfMultiColumn(i,j)) + continue; cx = nx + tabular->GetBeginningOfTextInCell(cell); tabular->GetCellInset(cell)->draw(pain, font, baseline, cx); DrawCellLines(pain, nx, baseline, i, cell); @@ -175,6 +182,7 @@ void InsetTabular::draw(Painter & pain, const LyXFont & font, int baseline, baseline += tabular->GetDescentOfRow(i) + tabular->GetAscentOfRow(i+1) + tabular->GetAdditionalHeight(cell+1); } + x += width(pain, font); } @@ -257,11 +265,11 @@ void InsetTabular::InsetUnlock(BufferView * bv) void InsetTabular::UpdateLocal(BufferView * bv, bool flag) { - if (flag) { + if (flag) calculate_width_of_cells(bv->painter(), LyXFont(LyXFont::ALL_SANE)); - resetPos(bv->painter()); - } bv->updateInset(this, flag); + if (flag) + resetPos(bv->painter()); } bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset) @@ -328,11 +336,43 @@ int InsetTabular::InsetInInsetY() return (inset_y + the_locking_inset->InsetInInsetY()); } + +UpdatableInset * InsetTabular::GetLockingInset() +{ + return the_locking_inset ? the_locking_inset->GetLockingInset() : this; +} + + +UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c) +{ + if (c == LyxCode()) + return this; + if (the_locking_inset) + return the_locking_inset->GetFirstLockingInsetOfType(c); + return 0; +} + + +bool InsetTabular::InsertInset(BufferView * bv, Inset * inset) +{ + if (the_locking_inset) + return the_locking_inset->InsertInset(bv, inset); + return false; +} + + void InsetTabular::InsetButtonRelease(BufferView * bv, int x, int y, int button) { if (button == 3) { - LocalDispatch(bv, LFUN_LAYOUT_TABLE, "true"); + if (the_locking_inset) { + UpdatableInset * i; + if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) { + i->InsetButtonRelease(bv, x, y, button); + return; + } + } + MenuLayoutTabular(true, this); return; } if (the_locking_inset) { @@ -533,7 +573,7 @@ UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action, case LFUN_LAYOUT_TABLE: { int flag = (arg == "true"); - MenuLayoutTable(flag); + MenuLayoutTabular(flag, this); } break; default: @@ -554,9 +594,9 @@ UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action, } -int InsetTabular::Latex(ostream & os, bool, bool) const +int InsetTabular::Latex(ostream & os, bool fragile, bool fp) const { - return tabular->Latex(os); + return tabular->Latex(os, fragile, fp); } @@ -664,12 +704,13 @@ void InsetTabular::setPos(Painter & pain, int x, int y) const // first search the right row while((ly < y) && (actrow < tabular->rows())) { cursor.y += tabular->GetDescentOfRow(actrow) + - tabular->GetAscentOfRow(actrow+1) + - tabular->GetAdditionalHeight(tabular->GetCellNumber(actcol,actrow+1)); + tabular->GetAscentOfRow(actrow+1) + + tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow+1, + actcol)); ++actrow; ly = cursor.y + tabular->GetDescentOfRow(actrow); } - actcell = tabular->GetCellNumber(actcol, actrow); + actcell = tabular->GetCellNumber(actrow, actcol); // now search the right column int lx = tabular->GetWidthOfColumn(actcell) - @@ -688,12 +729,25 @@ void InsetTabular::setPos(Painter & pain, int x, int y) const resetPos(pain); } +int InsetTabular::getCellXPos(int cell) const +{ + int c; + + for(c=cell;!tabular->IsFirstCellInRow(c);--c) + ; + int lx = tabular->GetWidthOfColumn(cell); + for(; (c < cell); ++c) { + lx += tabular->GetWidthOfColumn(c); + } + return (lx - tabular->GetWidthOfColumn(cell) + top_x); +} void InsetTabular::resetPos(Painter & pain) const { - actrow = cursor.y = actcol = 0; + actcol = tabular->column_of_cell(actcell); int cell = 0; + actrow = cursor.y = 0; for(; (cellIsLastRow(cell); ++cell) { if (tabular->IsLastCellInRow(cell)) { cursor.y += tabular->GetDescentOfRow(actrow) + @@ -702,14 +756,7 @@ void InsetTabular::resetPos(Painter & pain) const ++actrow; } } - for(cell=actcell;!tabular->IsFirstCellInRow(cell);--cell) - ; - int lx = tabular->GetWidthOfColumn(actcell); - for(; (cell < actcell); ++cell) { - lx += tabular->GetWidthOfColumn(cell); - ++actcol; - } - cursor.x = lx - tabular->GetWidthOfColumn(actcell) + top_x + 2; + cursor.x = getCellXPos(actcell) + 2; if (cursor.pos % 2) { LyXFont font(LyXFont::ALL_SANE); cursor.x += tabular->GetCellInset(actcell)->width(pain,font) + @@ -766,7 +813,7 @@ UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock) if (cursor.pos % 2) { // behind the inset --actcell; } else if (lock) { // behind the inset - if (ActivateCellInset(bv, -1, -1)) + if (ActivateCellInset(bv, 0, 0, 0, true)) return DISPATCHED; } resetPos(bv->painter()); @@ -846,8 +893,13 @@ void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val) sel_pos_start = sel_pos_end = actcell; switch (feature) { case LyXTabular::SET_PWIDTH: + { + bool update = tabular->GetPWidth(actcell).empty(); tabular->SetPWidth(actcell,val); - break; + if (tabular->GetPWidth(actcell).empty() != update) + UpdateLocal(bv, true); + } + break; case LyXTabular::SET_SPECIAL_COLUMN: case LyXTabular::SET_SPECIAL_MULTI: tabular->SetAlignSpecial(actcell,val,feature); @@ -857,60 +909,60 @@ void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val) // append the row into the tabular tabular->AppendRow(actcell); UpdateLocal(bv, true); - return; + break; } case LyXTabular::APPEND_COLUMN: { // append the column into the tabular tabular->AppendColumn(actcell); UpdateLocal(bv, true); - return; + break; } case LyXTabular::DELETE_ROW: RemoveTabularRow(); UpdateLocal(bv, true); - return; + break; case LyXTabular::DELETE_COLUMN: { /* delete the column from the tabular */ tabular->DeleteColumn(actcell); UpdateLocal(bv, true); - return; + break; } case LyXTabular::TOGGLE_LINE_TOP: lineSet = !tabular->TopLine(actcell); for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetTopLine(i,lineSet); UpdateLocal(bv, true); - return; + break; case LyXTabular::TOGGLE_LINE_BOTTOM: lineSet = !tabular->BottomLine(actcell); for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetBottomLine(i,lineSet); UpdateLocal(bv, true); - return; + break; case LyXTabular::TOGGLE_LINE_LEFT: lineSet = !tabular->LeftLine(actcell); for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetLeftLine(i,lineSet); UpdateLocal(bv, true); - return; + break; case LyXTabular::TOGGLE_LINE_RIGHT: lineSet = !tabular->RightLine(actcell); for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetRightLine(i,lineSet); UpdateLocal(bv, true); - return; + break; case LyXTabular::ALIGN_LEFT: case LyXTabular::ALIGN_RIGHT: case LyXTabular::ALIGN_CENTER: for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetAlignment(i,setAlign); UpdateLocal(bv, true); - return; + break; case LyXTabular::MULTICOLUMN: { if (tabular->row_of_cell(sel_pos_start) != @@ -948,7 +1000,7 @@ void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val) cursor.pos = s_start; sel_cell_end = sel_cell_start; UpdateLocal(bv, true); - return; + break; } case LyXTabular::SET_ALL_LINES: setLines = 1; @@ -956,50 +1008,50 @@ void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val) for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetAllLines(i, setLines); UpdateLocal(bv, true); - return; + break; case LyXTabular::SET_LONGTABULAR: tabular->SetLongTabular(true); UpdateLocal(bv, true); // because this toggles displayed - return; + break; case LyXTabular::UNSET_LONGTABULAR: tabular->SetLongTabular(false); UpdateLocal(bv, true); // because this toggles displayed - return; + break; case LyXTabular::SET_ROTATE_TABULAR: tabular->SetRotateTabular(true); - return; + break; case LyXTabular::UNSET_ROTATE_TABULAR: tabular->SetRotateTabular(false); - return; + break; case LyXTabular::SET_ROTATE_CELL: for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetRotateCell(i,true); - return; + break; case LyXTabular::UNSET_ROTATE_CELL: for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetRotateCell(i,false); - return; + break; case LyXTabular::SET_LINEBREAKS: what = !tabular->GetLinebreaks(actcell); for(i=sel_pos_start; i<=sel_pos_end; ++i) tabular->SetLinebreaks(i,what); - return; + break; case LyXTabular::SET_LTFIRSTHEAD: tabular->SetLTHead(actcell,true); - return; + break; case LyXTabular::SET_LTHEAD: tabular->SetLTHead(actcell,false); - return; + break; case LyXTabular::SET_LTFOOT: tabular->SetLTFoot(actcell,false); - return; + break; case LyXTabular::SET_LTLASTFOOT: tabular->SetLTFoot(actcell,true); - return; + break; case LyXTabular::SET_LTNEWPAGE: what = !tabular->GetLTNewPage(actcell); tabular->SetLTNewPage(actcell,what); - return; + break; } } @@ -1007,7 +1059,8 @@ void InsetTabular::RemoveTabularRow() { } -bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button) +bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button, + bool behind) { // the cursor.pos has to be before the inset so if it isn't now just // reset the curor pos first! @@ -1018,10 +1071,10 @@ bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button) UpdatableInset * inset = static_cast(tabular->GetCellInset(actcell)); LyXFont font(LyXFont::ALL_SANE); - if (x < 0) - x = inset->width(bv->painter(), font) + top_x; - if (y < 0) + if (behind) { + x = inset->x() + inset->width(bv->painter(), font); y = inset->descent(bv->painter(), font); + } inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell); inset_y = cursor.y; inset->Edit(bv, x-inset_x, y-inset_y, button); @@ -1047,3 +1100,53 @@ bool InsetTabular::InsetHit(BufferView * bv, int x, int ) const LyXFont(LyXFont::ALL_SANE))))); } } + +// This returns paperWidth() if the cell-width is unlimited or the width +// in pixels if we have a pwidth for this cell. +int InsetTabular::GetMaxWidthOfCell(Painter & pain, int cell) const +{ + string w; + + if ((w=tabular->GetPWidth(cell)).empty()) + return pain.paperWidth(); + return VSpace(w).inPixels( 0, 0); +} + +int InsetTabular::getMaxWidth(Painter & pain, + UpdatableInset const * inset) const +{ + int cell; + int n = tabular->GetNumberOfCells(); + for(cell=0; cell < n; ++cell) { + if (tabular->GetCellInset(cell) == inset) + break; + } + if (cell >= n) + return pain.paperWidth(); + int w = GetMaxWidthOfCell(pain, cell); + // this because text insets remove the xpos from the maxwidth because + // otherwise the would not break good!!! +// w += getCellXPos(cell) + tabular->GetBeginningOfTextInCell(cell); +// w += inset->x(); + return w; +} + +void InsetTabular::recomputeTextInsets(Painter & pain, const LyXFont & font) const +{ + InsetText * inset; + int cx, cell; + + cx = top_x; + for(int j= 0; j < tabular->columns(); ++j) { + for(int i = 0; i < tabular->rows(); ++i) { + if (tabular->IsPartOfMultiColumn(i,j)) + continue; + cell = tabular->GetCellNumber(i,j); + inset = tabular->GetCellInset(cell); + inset->computeTextRows(pain); + tabular->SetWidthOfCell(cell, inset->width(pain, font)); + } + cell = tabular->GetCellNumber(0, j); + cx += tabular->GetWidthOfColumn(cell); + } +} diff --git a/src/insets/insettabular.h b/src/insets/insettabular.h index af3d0994cd..277988a4c0 100644 --- a/src/insets/insettabular.h +++ b/src/insets/insettabular.h @@ -98,6 +98,12 @@ public: /// int InsetInInsetY(); /// + UpdatableInset * GetLockingInset(); + /// + UpdatableInset * GetFirstLockingInsetOfType(Inset::Code); + /// + bool InsertInset(BufferView *, Inset *); + /// bool display() const { return tabular->IsLongTabular(); } /// void InsetButtonRelease(BufferView *, int, int, int); @@ -131,6 +137,11 @@ public: int GetActCell() { return actcell; } /// void SetFont(BufferView *, LyXFont const &, bool toggleall = false); + /// + int getMaxWidth(Painter & pain, UpdatableInset const *) const; + /// + Buffer * BufferOwner() const { return buffer; } + /// /// Public structures and variables /// @@ -157,6 +168,7 @@ private: bool movePrevCell(); bool Delete(); /// + int getCellXPos(int cell) const; void resetPos(Painter &) const; /// void RemoveTabularRow(); @@ -165,9 +177,14 @@ private: bool hasCellSelection() const {return hasCharSelection() && (sel_cell_start != sel_cell_end);} /// - bool ActivateCellInset(BufferView *, int x=0, int y=0, int button=0); + bool ActivateCellInset(BufferView *, int x=0, int y=0, int button=0, + bool behind = false); /// bool InsetHit(BufferView * bv, int x, int y) const; + /// + int GetMaxWidthOfCell(Painter &, int cell) const; + /// + void recomputeTextInsets(Painter &, const LyXFont &) const; /// /// Private structures and variables @@ -192,6 +209,6 @@ private: bool no_selection; mutable bool - init; + init_inset; }; #endif diff --git a/src/insets/insettext.C b/src/insets/insettext.C index e0b8f1f5b3..43d55e59be 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -21,40 +21,27 @@ #endif #include "insettext.h" +#include "lyxparagraph.h" #include "lyxlex.h" #include "debug.h" #include "lyxfont.h" -#include "lyxlex.h" #include "commandtags.h" #include "buffer.h" #include "LyXView.h" #include "BufferView.h" -#include "support/textutils.h" #include "layout.h" -#include "insetlatexaccent.h" -#include "insetquotes.h" -#include "mathed/formulamacro.h" -#include "figinset.h" -#include "insetinfo.h" -#include "insetinclude.h" -#include "insetbib.h" -#include "insetcommand.h" -#include "insetindex.h" -#include "insetlabel.h" -#include "insetref.h" -//#include "insettabular.h" -#include "insetert.h" -#include "insetspecialchar.h" #include "LaTeXFeatures.h" #include "Painter.h" #include "lyx_gui_misc.h" -#include "support/LAssert.h" #include "lyxtext.h" #include "lyxcursor.h" #include "CutAndPaste.h" #include "font.h" #include "minibuffer.h" #include "toolbar.h" +#include "LColor.h" +#include "support/textutils.h" +#include "support/LAssert.h" using std::ostream; using std::ifstream; @@ -92,7 +79,7 @@ void InsetText::init(Buffer * buf, InsetText const * ins) init_inset = true; maxAscent = maxDescent = insetWidth = 0; drawTextXOffset = drawTextYOffset = 0; - autoBreakRows = false; + autoBreakRows = drawLockedFrame = false; xpos = 0.0; if (ins) { SetParagraphData(ins->par); @@ -102,6 +89,8 @@ void InsetText::init(Buffer * buf, InsetText const * ins) cursor.par = par; cursor.pos = 0; selection_start_cursor = selection_end_cursor = cursor; + frame_color = LColor::insetframe; + locked = false; } @@ -172,12 +161,12 @@ void InsetText::Read(LyXLex & lex) int InsetText::ascent(Painter & pain, LyXFont const & font) const { if (init_inset) { - computeTextRows(pain, xpos); + computeTextRows(pain); resetPos(pain); init_inset = false; } if (maxAscent) - return maxAscent; + return maxAscent + 2; return lyxfont::maxAscent(font); } @@ -185,12 +174,12 @@ int InsetText::ascent(Painter & pain, LyXFont const & font) const int InsetText::descent(Painter & pain, LyXFont const & font) const { if (init_inset) { - computeTextRows(pain, xpos); + computeTextRows(pain); resetPos(pain); init_inset = false; } if (maxDescent) - return maxDescent; + return maxDescent + 2; return lyxfont::maxDescent(font); } @@ -198,7 +187,7 @@ int InsetText::descent(Painter & pain, LyXFont const & font) const int InsetText::width(Painter & pain, LyXFont const &) const { if (init_inset) { - computeTextRows(pain, xpos); + computeTextRows(pain); resetPos(pain); init_inset = false; } @@ -216,7 +205,7 @@ void InsetText::draw(Painter & pain, LyXFont const & f, top_baseline = baseline; if (init_inset || (top_x != int(x))) { top_x = int(x); - computeTextRows(pain, x); + computeTextRows(pain); init_inset = false; } computeBaselines(baseline); @@ -226,12 +215,17 @@ void InsetText::draw(Painter & pain, LyXFont const & f, inset_x = cursor.x - top_x + drawTextXOffset; inset_y = cursor.y + drawTextYOffset; } + if (drawLockedFrame && locked) { + pain.rectangle(int(x), baseline - ascent(pain, f), insetWidth, + ascent(pain,f) + descent(pain, f), frame_color); + } + x += TEXT_TO_INSET_OFFSET; // place for border for(RowList::size_type r = 0; r < rows.size() - 1; ++r) { drawRowSelection(pain, rows[r].pos, rows[r + 1].pos, r, rows[r].baseline, x); drawRowText(pain, rows[r].pos, rows[r + 1].pos, rows[r].baseline, x); } - x += insetWidth; + x += insetWidth - TEXT_TO_INSET_OFFSET; } @@ -351,6 +345,7 @@ void InsetText::Edit(BufferView * bv, int x, int y, unsigned int button) lyxerr[Debug::INSETS] << "Cannot lock inset" << endl; return; } + locked = true; the_locking_inset = 0; inset_pos = inset_x = inset_y = 0; setPos(bv->painter(), x, y); @@ -371,11 +366,10 @@ void InsetText::InsetUnlock(BufferView * bv) HideInsetCursor(bv); lyxerr[Debug::INSETS] << "InsetText::InsetUnlock(" << this << ")" << endl; - if (hasSelection()) { - selection_start_cursor = selection_end_cursor = cursor; - UpdateLocal(bv, false); - } + selection_start_cursor = selection_end_cursor = cursor; no_selection = false; + locked = false; + UpdateLocal(bv, true); } @@ -766,12 +760,6 @@ InsetText::LocalDispatch(BufferView * bv, } resetPos(bv->painter()); break; - case LFUN_MATH_MODE: - InsertInset(bv, new InsetFormula); - return DISPATCHED; - case LFUN_INSET_ERT: - InsertInset(bv, new InsetERT(buffer)); - return DISPATCHED; case LFUN_BREAKPARAGRAPH: case LFUN_BREAKLINE: if (!autoBreakRows) @@ -1060,8 +1048,8 @@ void InsetText::setPos(Painter & pain, int x, int y) const actrow = i; } cursor.y -= top_baseline; - cursor.x = top_x; - x += top_x; + cursor.x = top_x + 2; // 2 = frame width + x += cursor.x; int swh; int sw = swh = SingleWidth(pain, par,cursor.pos); @@ -1099,7 +1087,7 @@ void InsetText::resetPos(Painter & pain) const } cursor.y -= top_baseline; setPos(pain, 0, cursor.y); - cursor.x = top_x; + cursor.x = top_x + 2; // 2 = frame width while(cursor.pos < old_pos) { cursor.x += SingleWidth(pain, par,cursor.pos); ++cursor.pos; @@ -1175,6 +1163,11 @@ bool InsetText::Delete() bool InsetText::InsertInset(BufferView * bv, Inset * inset) { + if (the_locking_inset) { + if (the_locking_inset->InsertInsetAllowed(inset)) + return the_locking_inset->InsertInset(bv, inset); + return false; + } 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); @@ -1201,6 +1194,16 @@ UpdatableInset * InsetText::GetLockingInset() } +UpdatableInset * InsetText::GetFirstLockingInsetOfType(Inset::Code c) +{ + if (c == LyxCode()) + return this; + if (the_locking_inset) + return the_locking_inset->GetFirstLockingInsetOfType(c); + return 0; +} + + void InsetText::SetFont(BufferView * bv, LyXFont const & font, bool toggleall) { // if there is no selection just set the current_font @@ -1274,7 +1277,7 @@ void InsetText::SetCharFont(int pos, LyXFont const & f) } -void InsetText::computeTextRows(Painter & pain, float x) const +void InsetText::computeTextRows(Painter & pain) const { int p, nwp = 0, @@ -1282,7 +1285,6 @@ void InsetText::computeTextRows(Painter & pain, float x) const desc = 0, oasc = 0, odesc = 0, - owidth = 0, wordAscent, wordDescent; row_struct row; @@ -1303,6 +1305,7 @@ void InsetText::computeTextRows(Painter & pain, float x) const maxAscent = max(maxAscent, asc); maxDescent = max(maxDescent, desc); } + insetWidth += (2 * TEXT_TO_INSET_OFFSET); rows[0].asc = maxAscent; rows[0].desc = maxDescent; // alocate a dummy row for the endpos @@ -1313,99 +1316,100 @@ void InsetText::computeTextRows(Painter & pain, float x) const bool is_first_word_in_row = true; int cw, lastWordWidth = 0; - int maxWidth = getMaxTextWidth(pain, this, x); + int maxWidth = getMaxTextWidth(pain, this); + // if we auto break rows than the insetwidth should be always the max + // width as the display is stable it may get larger if we have a really + // large word below and we draw it!!! + insetWidth = maxWidth; for(p = 0; p < par->Last(); ++p) { - cw = SingleWidth(pain, par, p); - width += cw; - lastWordWidth += cw; - SingleHeight(pain, par, p, asc, desc); - wordAscent = max(wordAscent, asc); - wordDescent = max(wordDescent, desc); if (par->IsNewline(p)) { - if (!is_first_word_in_row && (width >= maxWidth)) { - // we have to split also the row above - rows.back().asc = oasc; - rows.back().desc = odesc; - row.pos = nwp; - rows.push_back(row); - oasc = wordAscent; - odesc = wordDescent; - insetWidth = max(insetWidth, owidth); - width = lastWordWidth; - lastWordWidth = 0; - } rows.back().asc = wordAscent; rows.back().desc = wordDescent; row.pos = ++p; rows.push_back(row); - SingleHeight(pain, par, p, oasc, odesc); - insetWidth = max(insetWidth, owidth); - width = 0; - is_first_word_in_row = true; - wordAscent = wordDescent = lastWordWidth = 0; nwp = p; + width = lastWordWidth = 0; + oasc = odesc = wordAscent = wordDescent = 0; + is_first_word_in_row = true; continue; } + cw = SingleWidth(pain, par, p); Inset * inset = 0; - if (((p + 1) < par->Last()) && - (par->GetChar(p + 1)==LyXParagraph::META_INSET)) - inset = par->GetInset(p + 1); - if (inset) { - inset->setOwner(const_cast(this)); // is this safe? - if (inset->display()) { - if (!is_first_word_in_row && (width >= maxWidth)) { - // we have to split also the row above - rows.back().asc = oasc; - rows.back().desc = odesc; - row.pos = nwp; - rows.push_back(row); - oasc = wordAscent; - odesc = wordDescent; - insetWidth = max(insetWidth, owidth); - width = lastWordWidth; - lastWordWidth = 0; - } else { - oasc = max(oasc, wordAscent); - odesc = max(odesc, wordDescent); - } + if (par->GetChar(p) == LyXParagraph::META_INSET) + inset = par->GetInset(p); + if (inset && inset->display()) { + inset->setOwner(const_cast(this)); + if (cw > maxWidth) + insetWidth = cw; + if (!is_first_word_in_row || (p != nwp)) { + oasc = max(oasc, wordAscent); + odesc = max(odesc, wordDescent); rows.back().asc = oasc; rows.back().desc = odesc; - row.pos = ++p; - rows.push_back(row); - SingleHeight(pain, par, p, asc, desc); - rows.back().asc = asc; - rows.back().desc = desc; - row.pos = nwp = p + 1; + row.pos = p; rows.push_back(row); - oasc = odesc = width = lastWordWidth = 0; - is_first_word_in_row = true; - wordAscent = wordDescent = 0; - continue; } - } else if (par->IsSeparator(p)) { - if (width >= maxWidth) { - if (is_first_word_in_row) { - rows.back().asc = wordAscent; - rows.back().desc = wordDescent; - row.pos = p + 1; + SingleHeight(pain, par, p, asc, desc); + rows.back().asc = asc; + rows.back().desc = desc; + row.pos = nwp = p + 1; + rows.push_back(row); + width = lastWordWidth = 0; + oasc = odesc = wordAscent = wordDescent = 0; + is_first_word_in_row = true; + continue; + } + SingleHeight(pain, par, p, asc, desc); + width += cw; + lastWordWidth += cw; + if (width > maxWidth) { + if (is_first_word_in_row) { + if (!(width-cw)) { // only this character in word + rows.back().asc = asc; + rows.back().desc = desc; + row.pos = p+1; rows.push_back(row); - oasc = odesc = width = 0; + oasc = 0; + odesc = 0; + wordAscent = 0; + wordDescent = 0; + nwp = p + 1; + lastWordWidth = width = 0; } else { - rows.back().asc = oasc; - rows.back().desc = odesc; - row.pos = nwp; + rows.back().asc = wordAscent; + rows.back().desc = wordDescent; + row.pos = p; rows.push_back(row); - oasc = wordAscent; - odesc = wordDescent; - insetWidth = max(insetWidth, owidth); - width = lastWordWidth; + oasc = 0; + odesc = 0; + wordAscent = asc; + wordDescent = desc; + lastWordWidth = width = cw; + nwp = p; } - wordAscent = wordDescent = lastWordWidth = 0; - nwp = p + 1; - continue; + } else { + rows.back().asc = oasc; + rows.back().desc = odesc; + row.pos = nwp; + rows.push_back(row); + oasc = wordAscent; + odesc = wordDescent; + width = lastWordWidth; + wordAscent = max(wordAscent, asc); + wordDescent = max(wordDescent, desc); + is_first_word_in_row = true; + } + } else { + wordAscent = max(wordAscent, asc); + wordDescent = max(wordDescent, desc); + } + if (par->IsSeparator(p) || inset) { + if (inset) { + inset->setOwner(const_cast(this)); + if (cw > maxWidth) + insetWidth = cw; } - owidth = width; oasc = max(oasc, wordAscent); odesc = max(odesc, wordDescent); wordAscent = wordDescent = lastWordWidth = 0; @@ -1415,23 +1419,11 @@ void InsetText::computeTextRows(Painter & pain, float x) const } // if we have some data in the paragraph we have ascent/descent if (p) { - if (width >= maxWidth) { - // assign upper row - rows.back().asc = oasc; - rows.back().desc = odesc; - // assign and allocate lower row - row.pos = nwp; - rows.push_back(row); - rows.back().asc = wordAscent; - rows.back().desc = wordDescent; - width -= lastWordWidth; - } else { - // assign last row data - rows.back().asc = max(oasc, wordAscent); - rows.back().desc = max(odesc, wordDescent); - } + // assign last row data + rows.back().asc = max(oasc, wordAscent); + rows.back().desc = max(odesc, wordDescent); } - insetWidth = max(insetWidth, width); + insetWidth += (2 * TEXT_TO_INSET_OFFSET); // alocate a dummy row for the endpos row.pos = par->Last(); rows.push_back(row); @@ -1457,7 +1449,7 @@ void InsetText::computeBaselines(int baseline) const void InsetText::UpdateLocal(BufferView * bv, bool flag) { if (flag) { - computeTextRows(bv->painter(), xpos); + computeTextRows(bv->painter()); computeBaselines(top_baseline); } bv->updateInset(this, flag); @@ -1548,10 +1540,11 @@ bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y, } -int InsetText::getMaxTextWidth(Painter & pain, UpdatableInset const * inset, - int x) const +int InsetText::getMaxTextWidth(Painter & pain, UpdatableInset const * inset) const { - return getMaxWidth(pain, inset) - x; +// int w=getMaxWidth(pain, inset); +// return (w - x); + return getMaxWidth(pain, inset) - 4; // 2+2 width of eventual border } void InsetText::SetParagraphData(LyXParagraph *p) @@ -1562,3 +1555,27 @@ void InsetText::SetParagraphData(LyXParagraph *p) par->SetInsetOwner(this); init_inset = true; } + +void InsetText::SetAutoBreakRows(bool flag) +{ + if (flag != autoBreakRows) { + autoBreakRows = flag; + init_inset = true; + } +} + +void InsetText::SetDrawLockedFrame(bool flag) +{ + if (flag != drawLockedFrame) { + drawLockedFrame = flag; + init_inset = true; + } +} + +void InsetText::SetFrameColor(LColor::color col) +{ + if (frame_color != col) { + frame_color = col; + init_inset = true; + } +} diff --git a/src/insets/insettext.h b/src/insets/insettext.h index b49374fa93..af481dec57 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -20,12 +20,14 @@ #include "lyxinset.h" #include "LString.h" -#include "lyxparagraph.h" #include "lyxcursor.h" class Painter; class BufferView; class Buffer; +class LyXCursor; +class LyXParagraph; +class LColor; /** A text inset is like a TeX box @@ -35,7 +37,7 @@ class Buffer; class InsetText : public UpdatableInset { public: /// - enum { TEXT_TO_INSET_OFFSET = 1 }; + enum { TEXT_TO_INSET_OFFSET = 2 }; /// explicit InsetText(Buffer *); @@ -104,11 +106,21 @@ public: /// UpdatableInset * GetLockingInset(); /// + UpdatableInset * GetFirstLockingInsetOfType(Inset::Code); + /// void SetFont(BufferView *, LyXFont const &, bool toggleall = false); /// void init(Buffer *, InsetText const * ins = 0); /// void SetParagraphData(LyXParagraph *); + /// + void SetAutoBreakRows(bool); + /// + void SetDrawLockedFrame(bool); + /// + void SetFrameColor(LColor::color); + /// + void computeTextRows(Painter &) const; LyXParagraph * par; @@ -131,8 +143,7 @@ protected: /// virtual LyXFont GetDrawFont(LyXParagraph * par, int pos) const; /// - virtual int getMaxTextWidth(Painter &, UpdatableInset const *, - int x=0) const; + virtual int getMaxTextWidth(Painter &, UpdatableInset const *) const; Buffer * buffer; /// @@ -150,6 +161,9 @@ protected: mutable int drawTextYOffset; /// bool autoBreakRows; + bool drawLockedFrame; + /// + LColor::color frame_color; private: /// @@ -159,8 +173,6 @@ private: void drawRowText(Painter &, int startpos, int endpos, int baseline, float x) const; /// - void computeTextRows(Painter &, float x = 0.0) const; - /// void computeBaselines(int) const; /// int BeginningOfMainBody(LyXParagraph * par) const; @@ -192,6 +204,8 @@ private: /* Private structures and variables */ /// + bool locked; + /// int inset_pos; /// mutable int inset_x; diff --git a/src/insets/lyxinset.h b/src/insets/lyxinset.h index 401884e6d7..26dba9c5ee 100644 --- a/src/insets/lyxinset.h +++ b/src/insets/lyxinset.h @@ -22,7 +22,6 @@ #include "lyxlex.h" class Painter; -class Buffer; class BufferView; struct LaTeXFeatures; @@ -101,7 +100,7 @@ public: }; /// - Inset() { owner_ = 0; } + Inset() { owner_ = 0; top_x = top_baseline = 0; } /// virtual ~Inset() {} /// @@ -187,6 +186,15 @@ public: /// virtual Inset * owner() const { return owner_; } /// + int x() const { return top_x; } + /// + int y() const { return top_baseline; } + +protected: + /// + mutable int top_x; + mutable int top_baseline; + private: /// Inset * owner_; @@ -289,6 +297,9 @@ public: /// virtual UpdatableInset * GetLockingInset() { return this; } /// + virtual UpdatableInset * GetFirstLockingInsetOfType(Inset::Code c) + { return (c == LyxCode()) ? this : 0; } + /// virtual int InsetInInsetY() { return 0; } /// virtual bool UpdateInsetInInset(BufferView *, Inset *) @@ -309,10 +320,6 @@ public: protected: /// - // virtual void UpdateLocal(bool flag=true); - /// - mutable int top_x; - mutable int top_baseline; mutable bool cursor_visible; private: diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 9a67ca8810..e119a160d1 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -825,28 +825,32 @@ string LyXFunc::Dispatch(int ac, case LFUN_TOC_INSERT: { Inset * new_inset = new InsetTOC(owner->buffer()); - owner->view()->insertInset(new_inset, "Standard", true); + if (!owner->view()->insertInset(new_inset, "Standard", true)) + delete new_inset; break; } case LFUN_LOF_INSERT: { Inset * new_inset = new InsetLOF(owner->buffer()); - owner->view()->insertInset(new_inset, "Standard", true); + if (!owner->view()->insertInset(new_inset, "Standard", true)) + delete new_inset; break; } case LFUN_LOA_INSERT: { Inset * new_inset = new InsetLOA(owner->buffer()); - owner->view()->insertInset(new_inset, "Standard", true); + if (!owner->view()->insertInset(new_inset, "Standard", true)) + delete new_inset; break; } case LFUN_LOT_INSERT: { Inset * new_inset = new InsetLOT(owner->buffer()); - owner->view()->insertInset(new_inset, "Standard", true); + if (!owner->view()->insertInset(new_inset, "Standard", true)) + delete new_inset; break; } @@ -861,7 +865,8 @@ string LyXFunc::Dispatch(int ac, case LFUN_INSERT_GRAPHICS: { Inset * new_inset = new InsetGraphics; - owner->view()->insertInset(new_inset); + if (!owner->view()->insertInset(new_inset)) + delete new_inset; break; } @@ -1377,11 +1382,12 @@ string LyXFunc::Dispatch(int ac, && txt->cursor.par->GetInset(txt->cursor.pos)->Editable() == Inset::HIGHLY_EDITABLE) { Inset * tmpinset = txt->cursor.par->GetInset(txt->cursor.pos); setMessage(tmpinset->EditMessage()); + LyXFont font = txt->GetFont(txt->cursor.par, + txt->cursor.pos); tmpinset->Edit(owner->view(), - tmpinset->width(owner->view()->painter(), - txt->GetFont(txt->cursor.par, - txt->cursor.pos)), - 0, 0); + tmpinset->x() + tmpinset->width(owner->view()->painter(),font), + tmpinset->descent(owner->view()->painter(),font), + 0); break; } if (is_rtl) @@ -1986,31 +1992,39 @@ string LyXFunc::Dispatch(int ac, new_inset = new InsetUrl("htmlurl", "", ""); else new_inset = new InsetUrl("url", "", ""); - owner->view()->insertInset(new_inset); - new_inset->Edit(owner->view(), 0, 0, 0); + if (owner->view()->insertInset(new_inset)) + new_inset->Edit(owner->view(), 0, 0, 0); + else + delete new_inset; } break; case LFUN_INSET_TEXT: { InsetText * new_inset = new InsetText(owner->buffer()); - owner->view()->insertInset(new_inset); - new_inset->Edit(owner->view(), 0, 0, 0); + if (owner->view()->insertInset(new_inset)) + new_inset->Edit(owner->view(), 0, 0, 0); + else + delete new_inset; } break; case LFUN_INSET_ERT: { InsetERT * new_inset = new InsetERT(owner->buffer()); - owner->view()->insertInset(new_inset); - new_inset->Edit(owner->view(), 0, 0, 0); + if (owner->view()->insertInset(new_inset)) + new_inset->Edit(owner->view(), 0, 0, 0); + else + delete new_inset; } break; case LFUN_INSET_FOOTNOTE: { InsetFoot * new_inset = new InsetFoot(owner->buffer()); - owner->view()->insertInset(new_inset); - new_inset->Edit(owner->view(), 0, 0, 0); + if (owner->view()->insertInset(new_inset)) + new_inset->Edit(owner->view(), 0, 0, 0); + else + delete new_inset; } break; @@ -2020,8 +2034,10 @@ string LyXFunc::Dispatch(int ac, if (!argument.empty()) sscanf(argument.c_str(),"%d%d",&r,&c); InsetTabular * new_inset = new InsetTabular(owner->buffer(),r,c); - owner->view()->insertInset(new_inset); - new_inset->Edit(owner->view(), 0, 0, 0); + if (owner->view()->insertInset(new_inset)) + new_inset->Edit(owner->view(), 0, 0, 0); + else + delete new_inset; } break; @@ -2314,10 +2330,13 @@ string LyXFunc::Dispatch(int ac, new_inset->setOptions(token(lsarg, '|', 1)); } else new_inset->setContents(lsarg); - owner->view()->insertInset(new_inset); + if (!owner->view()->insertInset(new_inset)) + delete new_inset; } else { - owner->view()->insertInset(new_inset); - new_inset->Edit(owner->view(), 0, 0, 0); + if (owner->view()->insertInset(new_inset)) + new_inset->Edit(owner->view(), 0, 0, 0); + else + delete new_inset; } } break; @@ -2336,10 +2355,11 @@ string LyXFunc::Dispatch(int ac, bibstyle, owner->buffer()); - owner->view()->insertInset(new_inset); - if (lsarg.empty()) { - new_inset->Edit(owner->view(), 0, 0, 0); - } + if (owner->view()->insertInset(new_inset)) { + if (lsarg.empty()) + new_inset->Edit(owner->view(), 0, 0, 0); + } else + delete new_inset; } break; @@ -2385,7 +2405,8 @@ string LyXFunc::Dispatch(int ac, if (!argument.empty()) { string lsarg(argument); new_inset->setContents(lsarg); - owner->view()->insertInset(new_inset); + if (!owner->view()->insertInset(new_inset)) + delete new_inset; } else { //reh 98/09/21 //get the current word for an argument @@ -2417,7 +2438,8 @@ string LyXFunc::Dispatch(int ac, //put the new inset into the buffer. // there should be some way of knowing the user //cancelled & avoiding this, but i don't know how - owner->view()->insertInset(new_inset); + if (!owner->view()->insertInset(new_inset)) + delete new_inset; } } break; @@ -2425,7 +2447,8 @@ string LyXFunc::Dispatch(int ac, case LFUN_INDEX_PRINT: { Inset * new_inset = new InsetPrintIndex(owner->buffer()); - owner->view()->insertInset(new_inset, "Standard", true); + if (!owner->view()->insertInset(new_inset, "Standard", true)) + delete new_inset; } break; @@ -2433,7 +2456,8 @@ string LyXFunc::Dispatch(int ac, { lyxerr << "arg " << argument << endl; Inset * new_inset = new InsetParent(argument, owner->buffer()); - owner->view()->insertInset(new_inset, "Standard", true); + if (!owner->view()->insertInset(new_inset, "Standard", true)) + delete new_inset; } break; @@ -2441,8 +2465,10 @@ string LyXFunc::Dispatch(int ac, { Inset * new_inset = new InsetInclude(argument, owner->buffer()); - owner->view()->insertInset(new_inset, "Standard", true); - new_inset->Edit(owner->view(), 0, 0, 0); + if (owner->view()->insertInset(new_inset, "Standard", true)) + new_inset->Edit(owner->view(), 0, 0, 0); + else + delete new_inset; } break; diff --git a/src/mathed/formula.C b/src/mathed/formula.C index 46be0e44af..8282d54757 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -369,6 +369,12 @@ void InsetFormula::Read(LyXLex & lex) label = mathed_label; mathed_label = 0; } + // reading of end_inset in the inset!!! + while (lex.IsOK()) { + lex.nextToken(); + if (lex.GetString() == "\\end_inset") + break; + } #ifdef DEBUG Write(lyxerr); diff --git a/src/mathed/formula.h b/src/mathed/formula.h index 365000021f..6e6ffab616 100644 --- a/src/mathed/formula.h +++ b/src/mathed/formula.h @@ -27,6 +27,7 @@ class MathParInset; class MathedCursor; +class Buffer; /// class InsetFormula: public UpdatableInset { diff --git a/src/mathed/formulamacro.C b/src/mathed/formulamacro.C index 27e28d51b1..5e44baa19e 100644 --- a/src/mathed/formulamacro.C +++ b/src/mathed/formulamacro.C @@ -105,6 +105,12 @@ void InsetFormulaMacro::Read(LyXLex & lex) MathMacroTable::mathMTable.addTemplate(tmacro); name = tmacro->GetName(); par = tmacro; + // reading of end_inset in the inset!!! + while (lex.IsOK()) { + lex.nextToken(); + if (lex.GetString() == "\\end_inset") + break; + } } diff --git a/src/mathed/math_write.C b/src/mathed/math_write.C index 7eb309f24f..f7d2e06984 100644 --- a/src/mathed/math_write.C +++ b/src/mathed/math_write.C @@ -287,7 +287,8 @@ void MathParInset::Write(ostream & os, bool fragile) } #else // Something like this should work too: - os << string(brace, '}'); // not one-off error I hope. + if (brace > 0) + os << string(brace, '}'); // not one-off error I hope. #endif } diff --git a/src/tabular.C b/src/tabular.C index 2c284cf444..8966171910 100644 --- a/src/tabular.C +++ b/src/tabular.C @@ -21,9 +21,10 @@ #include "debug.h" #include "vspace.h" #include "layout.h" +#include "lyx_gui_misc.h" #include "support/lstrings.h" #include "support/lyxmanip.h" -#include "lyx_gui_misc.h" +#include "insets/insettabular.h" #include "insets/insettext.h" using std::ostream; @@ -141,25 +142,25 @@ LyXTabular::columnstruct::columnstruct() /* konstruktor */ -LyXTabular::LyXTabular(int rows_arg, int columns_arg, Buffer *buf) +LyXTabular::LyXTabular(InsetTabular * inset, int rows_arg, int columns_arg) { - buffer = buf; - Init(buf, rows_arg, columns_arg); + owner_ = inset; + Init(rows_arg, columns_arg); } -LyXTabular::LyXTabular(LyXTabular const & lt, Buffer * buf) +LyXTabular::LyXTabular(InsetTabular * inset, LyXTabular const & lt) { - buffer = buf; - Init(buf, lt.rows_, lt.columns_); + owner_ = inset; + Init(lt.rows_, lt.columns_); operator=(lt); } -LyXTabular::LyXTabular(LyXLex & lex, Buffer *buf) +LyXTabular::LyXTabular(InsetTabular * inset, LyXLex & lex) { - buffer = buf; + owner_ = inset; Read(lex); } @@ -168,12 +169,6 @@ LyXTabular::~LyXTabular() { delete[] rowofcell; delete[] columnofcell; -// delete[] column_info; -// delete[] row_info; -// for (int i = 0; i < rows_; ++i) { -// delete[] cell_info[i]; -// } -// delete[] cell_info; } @@ -184,68 +179,49 @@ LyXTabular & LyXTabular::operator=(LyXTabular const & lt) // call abort() Assert(rows_ == lt.rows_ && columns_ == lt.columns_); - int row = 0, column = 0; +// int row = 0, column = 0; - // Why not just: - // cell_info = lt.cell_info; - for (row = 0; row < rows_; ++row) { - for (column = 0; column < columns_; ++column) { - cell_info[row][column] = lt.cell_info[row][column]; - } - } + cell_info = lt.cell_info; +// for (row = 0; row < rows_; ++row) { +// for (column = 0; column < columns_; ++column) { +// cell_info[row][column] = lt.cell_info[row][column]; +// } +// } - // why not just: - // row_info = lt.row_info; - for (row = 0; row < rows_; ++row) { - row_info[row] = lt.row_info[row]; - } + row_info = lt.row_info; +// for (row = 0; row < rows_; ++row) { +// row_info[row] = lt.row_info[row]; +// } - // why not just: - // column_info = lt.column_info; - for (column = 0; column < columns_; ++column) { - column_info[column] = lt.column_info[column]; - } + column_info = lt.column_info; +// for (column = 0; column < columns_; ++column) { +// column_info[column] = lt.column_info[column]; +// } + // long tabular stuff SetLongTabular(lt.is_long_tabular); + endhead = lt.endhead; + endfoot = lt.endfoot; + endfirsthead = lt.endfirsthead; + endlastfoot = lt.endlastfoot; + rotate = lt.rotate; + Reinit(); return *this; } -LyXTabular * LyXTabular::Clone(Buffer * buf) +LyXTabular * LyXTabular::Clone(InsetTabular * inset) { - LyXTabular * result = new LyXTabular(rows_, columns_, buf); - int row, column;; - - for (row = 0; row < rows_; ++row) { - for (column = 0; column < columns_; ++column) { - result->cell_info[row][column] = cell_info[row][column]; - } - } - - for (row = 0; row < rows_; ++row) { - result->row_info[row] = row_info[row]; - } - - for (column = 0; column < columns_; ++column) { - result->column_info[column].left_line = column_info[column].left_line; - result->column_info[column].right_line = column_info[column].right_line; - result->column_info[column].alignment = column_info[column].alignment; - result->column_info[column].p_width = column_info[column].p_width; - result->column_info[column].align_special = column_info[column].align_special; - } - - result->SetLongTabular(is_long_tabular); - result->rotate = rotate; - result->Reinit(); + LyXTabular * result = new LyXTabular(inset, *this); return result; } /* activates all lines and sets all widths to 0 */ -void LyXTabular::Init(Buffer * buf, int rows_arg, int columns_arg) +void LyXTabular::Init(int rows_arg, int columns_arg) { int i, j; int cellno = 0; @@ -260,7 +236,9 @@ void LyXTabular::Init(Buffer * buf, int rows_arg, int columns_arg) // Jürgen, use iterators. for (i = 0; i < rows_; ++i) { for (j = 0; j < columns_; ++j) { - cell_info[i][j].inset = new InsetText(buf); + cell_info[i][j].inset = new InsetText(owner_->BufferOwner()); + cell_info[i][j].inset->setOwner(owner_); + cell_info[i][j].inset->SetDrawLockedFrame(true); cell_info[i][j].cellno = cellno++; } } @@ -303,7 +281,7 @@ void LyXTabular::AppendRow(int /* cell */) row_info2[i + 1] = row_info[i]; } row_info2[row + 1].top_line = row_info[i].top_line; - cell_info2[row + 1] = new cellstruct[columns_](buffer); + cell_info2[row + 1] = new cellstruct[columns_](owner_->BufferOwner()); for (i = 0; i < columns_; ++i) { cell_info2[row + 1][i].width_of_cell = 0; cell_info2[row + 1][i] = cell_info2[row][i]; @@ -371,7 +349,7 @@ void LyXTabular::AppendColumn(int /*cell*/) for (i = 0; i < rows_; ++i) { cellstruct * tmp = cell_info[i]; - cell_info[i] = new cellstruct[columns_ + 1](buffer); + cell_info[i] = new cellstruct[columns_ + 1](owner_->BufferOwner()); for (j = 0; j <= column; ++j) { cell_info[i][j] = tmp[j]; } @@ -434,7 +412,7 @@ void LyXTabular::delete_column(int /*column*/) for (i = 0; i < rows_; ++i) { cellstruct * tmp = cell_info[i]; - cell_info[i] = new cellstruct[columns_ - 1](buffer); + cell_info[i] = new cellstruct[columns_ - 1](owner_->BufferOwner()); for (j = 0; j < column; ++j) { cell_info[i][j] = tmp[j]; } @@ -785,12 +763,22 @@ bool LyXTabular::SetAlignment(int cell, char align) bool LyXTabular::SetPWidth(int cell, string width) { + bool flag = !width.empty(); + if (IsMultiColumn(cell)) { cellinfo_of_cell(cell)->p_width = width; + GetCellInset(cell)->SetAutoBreakRows(flag); } else { - column_info[column_of_cell(cell)].p_width = width; - if (!width.empty()) // do this only if there is a width + int j = column_of_cell(cell); + int c; + column_info[j].p_width = width; + if (flag) // do this only if there is a width SetAlignment(cell, LYX_ALIGN_LEFT); + for(int i=0; i < rows_; ++i) { + c = GetCellNumber(i, j); + flag = !GetPWidth(c).empty(); // because of multicolumns! + GetCellInset(c)->SetAutoBreakRows(flag); + } } return true; } @@ -893,7 +881,6 @@ int LyXTabular::GetWidthOfCell(int cell) const return result; } - int LyXTabular::GetBeginningOfTextInCell(int cell) const { int x = 0; @@ -922,12 +909,27 @@ bool LyXTabular::IsFirstCellInRow(int cell) const } +int LyXTabular::GetFirstCellInRow(int row) const +{ + if (row > (rows_-1)) + row = rows_ - 1; + return cell_info[row][0].cellno; +} + bool LyXTabular::IsLastCellInRow(int cell) const { return (right_column_of_cell(cell) == (columns_ - 1)); } +int LyXTabular::GetLastCellInRow(int row) const +{ + if (row > (rows_-1)) + row = rows_ - 1; + return cell_info[row][columns_-1].cellno; +} + + bool LyXTabular::calculate_width_of_column(int column) { int old_column_width = column_info[column].width_of_column; @@ -946,7 +948,7 @@ bool LyXTabular::calculate_width_of_column_NMC(int column) int old_column_width = column_info[column].width_of_column; int max = 0; for (int i = 0; i < rows_; ++i) { - if (!IsMultiColumn(GetCellNumber(column, i)) && + if (!IsMultiColumn(GetCellNumber(i, column)) && (cell_info[i][column].width_of_cell > max)) { max = cell_info[i][column].width_of_cell; } @@ -1148,7 +1150,7 @@ void LyXTabular::Read(LyXLex & lex) return; if (!getTokenValue(line, "columns", columns_arg)) return; - Init(buffer, rows_arg, columns_arg); + Init(rows_arg, columns_arg); l_getline(is, line); if (!prefixIs(line, " got" << @@ -1198,6 +1200,9 @@ void LyXTabular::Read(LyXLex & lex) (void)getTokenValue(line, "rotate", cell_info[i][j].rotate); (void)getTokenValue(line, "linebreaks", cell_info[i][j].linebreaks); (void)getTokenValue(line, "width", cell_info[i][j].p_width); + if (!(cell_info[i][j].p_width.empty() && + column_info[j].p_width.empty())) + cell_info[i][j].inset->SetAutoBreakRows(true); (void)getTokenValue(line, "special", cell_info[i][j].align_special); l_getline(is, line); if (prefixIs(line, "\\begin_inset")) { @@ -1265,7 +1270,7 @@ void LyXTabular::OldFormatRead(istream & is, string fl) >> rotate_arg >> a >> b >> c >> d; } else is >> rows_arg >> columns_arg; - Init(buffer, rows_arg, columns_arg); + Init(rows_arg, columns_arg); SetLongTabular(is_long_tabular_arg); SetRotateTabular(rotate_arg); string tmp; @@ -1285,7 +1290,7 @@ void LyXTabular::OldFormatRead(istream & is, string fl) } is >> rows_arg >> columns_arg >> is_long_tabular_arg >> rotate_arg >> a >> b >> c >> d; - Init(buffer, rows_arg, columns_arg); + Init(rows_arg, columns_arg); SetLongTabular(is_long_tabular_arg); SetRotateTabular(rotate_arg); endhead = a; @@ -1340,6 +1345,7 @@ void LyXTabular::OldFormatRead(istream & is, string fl) } +#if 0 // cell < 0 will tex the preamble // returns the number of printed newlines int LyXTabular::TexEndOfCell(ostream & os, int cell) const @@ -1623,7 +1629,7 @@ int LyXTabular::TexEndOfCell(ostream & os, int cell) const ++ret; } } else { - os << "&\n"; + os << "&\n"; ++ret; if (nvcell < numberofcells && GetRotateCell(nvcell)) { os << "\\begin{sideways}\n"; @@ -1674,7 +1680,6 @@ int LyXTabular::TexEndOfCell(ostream & os, int cell) const } -#if 0 // cell <0 will tex the preamble // returns the number of printed newlines int LyXTabular::RoffEndOfCell(ostream & os, int cell) @@ -1767,6 +1772,7 @@ int LyXTabular::RoffEndOfCell(ostream & os, int cell) } return ret; } + #endif @@ -1968,6 +1974,8 @@ void LyXTabular::SetMultiColumn(int cell, int number) } set_row_column_number_info(); SetWidthOfCell(cell, new_width); + if (GetPWidth(cell).empty()) + GetCellInset(cell)->SetAutoBreakRows(false); } @@ -2007,6 +2015,8 @@ int LyXTabular::UnsetMultiColumn(int cell) } } set_row_column_number_info(); + if (GetPWidth(cell).empty()) + GetCellInset(cell)->SetAutoBreakRows(false); return result; } @@ -2077,7 +2087,7 @@ int LyXTabular::GetCellAbove(int cell) const } -int LyXTabular::GetCellNumber(int column, int row) const +int LyXTabular::GetCellNumber(int row, int column) const { if (column >= columns_) column = columns_ - 1; @@ -2220,11 +2230,11 @@ int LyXTabular::GetDescentOfRow(int row) const int LyXTabular::GetHeightOfTabular() const { - int height = 0; + int height = 0; for(int row = 0; row < rows_; ++row) height += GetAscentOfRow(row) + GetDescentOfRow(row) + - GetAdditionalHeight(GetCellNumber(0, row)); + GetAdditionalHeight(GetCellNumber(row, 0)); return height; } @@ -2237,12 +2247,240 @@ bool LyXTabular::IsPartOfMultiColumn(int row, int column) const } -int LyXTabular::Latex(ostream &) const +int LyXTabular::TeXTopHLine(ostream & os, int row) const { + int fcell = GetFirstCellInRow(row); + int n = NumberOfCellsInRow(fcell) + fcell; + int tmp=0; + int i; + + for (i = fcell; i < n; ++i) { + if (TopLine(i)) + ++tmp; + } + if (tmp == (n - fcell)){ + os << "\\hline "; + } else { + for (i = fcell; i < n; ++i) { + if (TopLine(i)) { + os << "\\cline{" + << column_of_cell(i) + 1 + << '-' + << right_column_of_cell(i) + 1 + << "} "; + } + } + } + if (tmp) { + os << endl; + return 1; + } return 0; } +int LyXTabular::TeXBottomHLine(ostream & os, int row) const +{ + int fcell = GetFirstCellInRow(row); + int n = NumberOfCellsInRow(fcell) + fcell; + int tmp = 0; + int i; + + for (i = fcell; i < n; ++i) { + if (BottomLine(i)) + ++tmp; + } + if (tmp == (n-fcell)){ + os << "\\hline"; + } else { + for (i = fcell; i < n; ++i) { + if (BottomLine(i)) { + os << "\\cline{" + << column_of_cell(i) + 1 + << '-' + << right_column_of_cell(i) + 1 + << "} "; + } + } + } + if (tmp) { + os << endl; + return 1; + } + return 0; +} + + +int LyXTabular::TeXCellPreamble(ostream & os, int cell) const +{ + int ret = 0; + + if (GetRotateCell(cell)) { + os << "\\begin{sideways}" << endl; + ++ret; + } + if (IsMultiColumn(cell)) { + os << "\\multicolumn{" << cells_in_multicolumn(cell) << "}{"; + if (!cellinfo_of_cell(cell+1)->align_special.empty()) { + os << cellinfo_of_cell(cell+1)->align_special << "}{"; + } else { + if (LeftLine(cell)) + os << '|'; + if (!GetPWidth(cell).empty()) { + os << "p{" << GetPWidth(cell) << '}'; + } else { + switch (GetAlignment(cell)) { + case LYX_ALIGN_LEFT: + os << 'l'; + break; + case LYX_ALIGN_RIGHT: + os << 'r'; + break; + default: + os << 'c'; + break; + } + } + if (RightLine(cell)) + os << '|'; + if (((cell + 1) < numberofcells) && !IsFirstCellInRow(cell+1) && + LeftLine(cell+1)) + os << '|'; + os << "}{"; + } + } + if (GetLinebreaks(cell)) { + os << "\\parbox[t]{" << GetPWidth(cell) << "}{\\smallskip{}"; + } + return ret; +} + + +int LyXTabular::TeXCellPostamble(ostream & os, int cell) const +{ + int ret = 0; + + // usual cells + if (GetLinebreaks(cell)) + os << "\\smallskip{}}"; + if (IsMultiColumn(cell)){ + os << '}'; + } + if (GetRotateCell(cell)) { + os << endl << "\\end{sideways}"; + ++ret; + } + return ret; +} + + +int LyXTabular::Latex(ostream & os, bool fragile, bool fp) const +{ + int ret = 0; + int i,j; + int cell = 0; + + //+--------------------------------------------------------------------- + //+ first the opening preamble + + //+--------------------------------------------------------------------- + + if (rotate) { + os << "\\begin{sideways}" << endl; + ++ret; + } + if (is_long_tabular) + os << "\\begin{longtable}{"; + else + os << "\\begin{tabular}{"; + for (i = 0; i < columns_; ++i) { + if (column_info[i].left_line) + os << '|'; + if (!column_info[i].align_special.empty()) { + os << column_info[i].align_special; + } else if (!column_info[i].p_width.empty()) { + os << "p{" + << column_info[i].p_width + << '}'; + } else { + switch (column_info[i].alignment) { + case LYX_ALIGN_LEFT: + os << 'l'; + break; + case LYX_ALIGN_RIGHT: + os << 'r'; + break; + default: + os << 'c'; + break; + } + } + if (column_info[i].right_line) + os << '|'; + } + os << "}" << endl; + ++ret; + + //+--------------------------------------------------------------------- + //+ the single row and columns (cells) + + //+--------------------------------------------------------------------- + + for(i=0; i < rows_; ++i) { + ret += TeXTopHLine(os, i); + for(j=0; j < columns_; ++j) { + if (IsPartOfMultiColumn(i,j)) + continue; + ret += TeXCellPreamble(os, cell); + ret += GetCellInset(cell)->Latex(os, fragile, fp); + ret += TeXCellPostamble(os, cell); + if (j < (columns_ - 1)) { // not last cell in row + os << "&" << endl; + ++ret; + } + ++cell; + } + os << "\\\\" << endl; + ret += TeXBottomHLine(os, i); + if (IsLongTabular()) { + if (i == endhead) { + os << "\\endhead\n"; + ++ret; + } + if (i == endfirsthead) { + os << "\\endfirsthead\n"; + ++ret; + } + if (i == endfoot) { + os << "\\endfoot\n"; + ++ret; + } + if (i == endlastfoot) { + os << "\\endlastfoot\n"; + ++ret; + } + if (row_info[i].newpage) { + os << "\\newpage\n"; + ++ret; + } + } + } + + //+--------------------------------------------------------------------- + //+ the closing of the tabular + + //+--------------------------------------------------------------------- + + if (is_long_tabular) + os << "\\end{longtable}"; + else + os << "\\end{tabular}"; + if (rotate) { + os << "\n\\end{sideways}"; + ++ret; + } + + return ret; +} + + InsetText * LyXTabular::GetCellInset(int cell) const { return cell_info[row_of_cell(cell)][column_of_cell(cell)].inset; diff --git a/src/tabular.h b/src/tabular.h index 6665a83768..46ef2e5149 100644 --- a/src/tabular.h +++ b/src/tabular.h @@ -20,8 +20,8 @@ #include "lyxlex.h" #include "LString.h" +class InsetTabular; class InsetText; -class Buffer; /* The features the text class offers for tables */ @@ -69,19 +69,19 @@ public: }; /* konstruktor */ /// - LyXTabular(int columns_arg, int rows_arg, Buffer *buf); + LyXTabular(InsetTabular *, int columns_arg, int rows_arg); /// /// - LyXTabular(LyXTabular const &, Buffer *buf); + LyXTabular(InsetTabular *, LyXTabular const &); /// explicit - LyXTabular(LyXLex & lex, Buffer *buf); + LyXTabular(InsetTabular *, LyXLex & lex); /// ~LyXTabular(); /// LyXTabular & operator=(LyXTabular const &); /// - LyXTabular * Clone(Buffer * buf); + LyXTabular * Clone(InsetTabular *); /// Returns true if there is a topline, returns false if not bool TopLine(int cell) const; @@ -158,8 +158,12 @@ public: /// bool IsFirstCellInRow(int cell) const; /// + int GetFirstCellInRow(int row) const; + /// bool IsLastCellInRow(int cell) const; /// + int GetLastCellInRow(int row) const; + /// int GetNumberOfCells() const; /// int AppendCellAfterCell(int append_cell, int question_cell); @@ -168,22 +172,20 @@ public: /// int NumberOfCellsInRow(int cell) const; /// - void Reinit(); - /// - void Init(Buffer * buf, int columns_arg, int rows_arg); - /// void Write(std::ostream &) const; /// void Read(LyXLex &); /// void OldFormatRead(std::istream &, string); /// - int Latex(std::ostream &) const; - - // cell <0 will tex the preamble - // returns the number of printed newlines + /// helper function for Latex returns number of newlines /// - int TexEndOfCell(std::ostream &, int cell) const; + int TeXTopHLine(std::ostream &, int row) const; + int TeXBottomHLine(std::ostream &, int row) const; + int TeXCellPreamble(std::ostream &, int cell) const; + int TeXCellPostamble(std::ostream &, int cell) const; + /// + int Latex(std::ostream &, bool, bool) const; /// int DocBookEndOfCell(std::ostream &, int cell, int & depth) const; #if 0 @@ -224,7 +226,7 @@ public: /// int GetCellAbove(int cell) const; /// - int GetCellNumber(int column, int row) const; + int GetCellNumber(int row, int column) const; /// void SetLinebreaks(int cell, bool what); /// @@ -253,6 +255,8 @@ public: int rows() const { return rows_; } /// int columns() const { return columns_;} + /// + InsetTabular * owner() const { return owner_; } private: ////////////////////////////////////////////////////////////////// /// @@ -346,8 +350,12 @@ private: ////////////////////////////////////////////////////////////////// int endfoot; // row of endfoot int endlastfoot; // row of endlastfoot /// - Buffer * buffer; + InsetTabular * owner_; + /// + void Init(int columns_arg, int rows_arg); + /// + void Reinit(); /// void set_row_column_number_info(); /// Returns true if a complete update is necessary, otherwise false diff --git a/src/text.C b/src/text.C index a702305f0a..8feb545ea6 100644 --- a/src/text.C +++ b/src/text.C @@ -777,7 +777,6 @@ int LyXText::LeftMargin(Row const * row) const atoi(row->par->pextra_widthp.c_str()) / 100; } else if (!row->par->pextra_width.empty()) { int xx = VSpace(row->par->pextra_width).inPixels(owner_); - if (xx > paperwidth) xx = paperwidth * 80 / 100; x += xx; diff --git a/src/vspace.C b/src/vspace.C index 5128d52d1e..50f4a94fe5 100644 --- a/src/vspace.C +++ b/src/vspace.C @@ -536,7 +536,18 @@ int VSpace::inPixels(BufferView * bv) const { // Height of a normal line in pixels (zoom factor considered) int height = bv->text->DefaultHeight(); // [pixels] + int skip = 0; + if (kin == DEFSKIP) + skip = bv->buffer()->params.getDefSkip().inPixels(bv); + return inPixels(height, skip); +} + +int VSpace::inPixels(int default_height, int default_skip) const +{ + // Height of a normal line in pixels (zoom factor considered) + int height = default_height; // [pixels] + // Zoom factor specified by user in percent float const zoom = lyxrc.zoom / 100.0; // [percent] @@ -550,7 +561,7 @@ int VSpace::inPixels(BufferView * bv) const case NONE: return 0; case DEFSKIP: - return bv->buffer()->params.getDefSkip().inPixels(bv); + return default_skip; // This is how the skips are normally defined by // LateX. But there should be some way to change diff --git a/src/vspace.h b/src/vspace.h index c4cde2fbce..7b0de93d5b 100644 --- a/src/vspace.h +++ b/src/vspace.h @@ -211,6 +211,8 @@ public: string asLatexCommand(BufferParams const & params) const; /// int inPixels(BufferView * bv) const; + /// + int inPixels(int default_height, int default_skip) const; private: /// vspace_kind kin; -- 2.39.5