]> git.lyx.org Git - lyx.git/blobdiff - src/tabular.C
citation patch from Angus
[lyx.git] / src / tabular.C
index 7acb56729297ec60fcbbea8fc060c57536f2756f..8077204d1c032c1e264fd4391beaec55d1bb4449 100644 (file)
@@ -3,20 +3,22 @@
  * 
  *           LyX, The Document Processor
  *      
- *        Copyright 2000 The LyX Team.
+ *           Copyright 2000 The LyX Team.
+ *
+ *           @author: Jürgen Vigna
  *
  * ====================================================== 
  */
 
 #include <config.h>
 
-#include <algorithm>
-#include <cstdlib>
-
 #ifdef __GNUG__
 #pragma implementation
 #endif
 
+#include <algorithm>
+#include <cstdlib>
+
 #include "tabular.h"
 #include "debug.h"
 #include "vspace.h"
@@ -46,14 +48,17 @@ extern BufferView * current_view;
 
 LyXTabular::cellstruct::cellstruct() 
 {
-    cellno = 0; //should be initilaized correctly later.
+    cellno = 0;
     width_of_cell = 0;
     multicolumn = LyXTabular::CELL_NORMAL;
     alignment = LYX_ALIGN_CENTER;
-    top_line = true;
+    valignment = LYX_VALIGN_TOP;
+    top_line = false;
     bottom_line = false;
+    left_line = false;
+    right_line = false;
+    usebox = BOX_NONE;
     rotate = false;
-    linebreaks = false;
 }
 
 
@@ -72,6 +77,7 @@ LyXTabular::columnstruct::columnstruct()
     left_line = true;
     right_line = false;
     alignment = LYX_ALIGN_CENTER;
+    valignment = LYX_VALIGN_TOP;
     width_of_column = 0;
 }
 
@@ -186,7 +192,7 @@ void LyXTabular::Init(int rows_arg, int columns_arg)
     columnofcell = 0;
     set_row_column_number_info();
     is_long_tabular = false;
-    rotate = 0;
+    rotate = false;
     endhead = 0;
     endfirsthead = 0;
     endfoot = 0;
@@ -249,7 +255,7 @@ void LyXTabular::AppendColumn(int cell)
                                                          cellstruct()));
     int column = column_of_cell(cell);
     int i, j;
-    column_vector::iterator cit = column_info.begin() + column;
+    column_vector::iterator cit = column_info.begin() + column + 1;
     column_info.insert(cit, columnstruct());
 
     for (i = 0; i < rows_; ++i) {
@@ -544,11 +550,13 @@ bool LyXTabular::SetWidthOfMulticolCell(int cell, int new_width)
     }
     // set the width to MAX_WIDTH until width > 0
     int width = (new_width + 2 * WIDTH_OF_LINE);
-    for (i = column1; (i < column2) && (width > 0); ++i) {
+    for (i = column1; (i < column2) && (width>column_info[i].width_of_column);
+        ++i)
+    {
         cell_info[row][i].width_of_cell = column_info[i].width_of_column;
         width -= column_info[i].width_of_column;
     }
-    if (i == column2) {
+    if (width > 0) {
         cell_info[row][i].width_of_cell = width;
     }
     return true;
@@ -578,10 +586,12 @@ bool LyXTabular::SetWidthOfCell(int cell, int new_width)
 {
     int row = row_of_cell(cell);
     int column1 = column_of_cell(cell);
-    int tmp = 0;
+    bool tmp = false;
     int width = 0;
 
-    if (IsMultiColumn(cell)) {
+    if (GetWidthOfCell(cell) == (new_width+2*WIDTH_OF_LINE))
+       return false;
+    if (IsMultiColumn(cell, true)) {
         tmp = SetWidthOfMulticolCell(cell, new_width);
     } else {
        width = (new_width + 2*WIDTH_OF_LINE);
@@ -779,9 +789,6 @@ int LyXTabular::GetWidthOfCell(int cell) const
     for (; i <= column2; ++i) {
        result += cell_info[row][i].width_of_cell;
     }
-    
-//    result += GetAdditionalWidth(cell);
-    
     return result;
 }
 
@@ -847,12 +854,16 @@ bool LyXTabular::calculate_width_of_column(int column)
 }
 
 
+///
+/// calculate the with of the column without regarding REAL MultiColumn
+/// cells. This means MultiColumn-cells spanning more than 1 column.
+///
 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(i, column)) &&
+        if (!IsMultiColumn(GetCellNumber(i, column), true) &&
             (cell_info[i][column].width_of_cell > max)) {
             max = cell_info[i][column].width_of_cell;
         }
@@ -940,7 +951,7 @@ void LyXTabular::Write(Buffer const * buf, ostream & os) const
                " leftline=" << cell_info[i][j].left_line <<
                " rightline=" << cell_info[i][j].right_line <<
                " rotate=" << cell_info[i][j].rotate <<
-               " linebreaks=" << cell_info[i][j].linebreaks <<
+               " usebox=" << (int)cell_info[i][j].usebox <<
                " width=\"" << cell_info[i][j].p_width <<
                "\" special=\"" << cell_info[i][j].align_special <<
                "\">" << endl;
@@ -1110,7 +1121,7 @@ void LyXTabular::Read(Buffer const * buf, LyXLex & lex)
            (void)getTokenValue(line, "leftline", cell_info[i][j].left_line);
            (void)getTokenValue(line, "rightline", cell_info[i][j].right_line);
            (void)getTokenValue(line, "rotate", cell_info[i][j].rotate);
-           (void)getTokenValue(line, "linebreaks", cell_info[i][j].linebreaks);
+           (void)getTokenValue(line, "usebox", cell_info[i][j].usebox);
            (void)getTokenValue(line, "width", cell_info[i][j].p_width);
            (void)getTokenValue(line, "special", cell_info[i][j].align_special);
            l_getline(is, line);
@@ -1248,7 +1259,7 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl)
                cell_info[i][j].top_line = static_cast<char>(c);
                cell_info[i][j].bottom_line = static_cast<char>(d);
                cell_info[i][j].rotate = static_cast<bool>(f);
-               cell_info[i][j].linebreaks = static_cast<bool>(g);
+               cell_info[i][j].usebox = static_cast<bool>(g);
                cell_info[i][j].align_special = s1;
                cell_info[i][j].p_width = s2;
            }
@@ -1326,7 +1337,7 @@ void LyXTabular::OldFormatRead(LyXLex & lex, string const & fl)
            }
            inset = GetCellInset(cell);
            row = row_of_cell(cell);
-           if (!cell_info[row_of_cell(cell)][column_of_cell(cell)].linebreaks)
+           if (!cell_info[row_of_cell(cell)][column_of_cell(cell)].usebox)
            {
                // insert a space instead
                par->Erase(i);
@@ -1509,9 +1520,10 @@ int LyXTabular::DocBookEndOfCell(ostream & os, int cell, int & depth) const
 }
 
 
-bool LyXTabular::IsMultiColumn(int cell) const
+bool LyXTabular::IsMultiColumn(int cell, bool real) const
 {
-    return (cellinfo_of_cell(cell)->multicolumn != LyXTabular::CELL_NORMAL);
+    return ((!real || (column_of_cell(cell) != right_column_of_cell(cell))) &&
+       (cellinfo_of_cell(cell)->multicolumn !=LyXTabular::CELL_NORMAL));
 }
 
 
@@ -1587,9 +1599,9 @@ bool LyXTabular::IsLongTabular() const
 }
 
 
-void LyXTabular::SetRotateTabular(int what)
+void LyXTabular::SetRotateTabular(bool flag)
 {
-    rotate = what;
+    rotate = flag;
 }
 
 
@@ -1599,9 +1611,9 @@ bool LyXTabular::GetRotateTabular() const
 }
 
 
-void LyXTabular::SetRotateCell(int cell, int what)
+void LyXTabular::SetRotateCell(int cell, bool flag)
 {
-    cellinfo_of_cell(cell)->rotate = what;
+    cellinfo_of_cell(cell)->rotate = flag;
 }
 
 
@@ -1684,18 +1696,20 @@ int LyXTabular::GetCellNumber(int row, int column) const
 }
 
 
-void LyXTabular::SetLinebreaks(int cell, bool what)
+void LyXTabular::SetUsebox(int cell, BoxType type)
 {
-    cellinfo_of_cell(cell)->linebreaks = what;
+    cellinfo_of_cell(cell)->usebox = type;
 }
 
 
-bool LyXTabular::GetLinebreaks(int cell) const
+int LyXTabular::GetUsebox(int cell) const
 {
     if (column_info[column_of_cell(cell)].p_width.empty() &&
         !(IsMultiColumn(cell) && !cellinfo_of_cell(cell)->p_width.empty()))
-        return false;
-    return cellinfo_of_cell(cell)->linebreaks;
+        return BOX_NONE;
+    if (cellinfo_of_cell(cell)->usebox > 1)
+       return cellinfo_of_cell(cell)->usebox;
+    return UseParbox(cell);
 }
 
 
@@ -1950,7 +1964,7 @@ int LyXTabular::TeXCellPreamble(ostream & os, int cell) const
            os << "}{";
        }
     }
-    if (GetLinebreaks(cell)) {
+    if (GetUsebox(cell) == BOX_PARBOX) {
        os << "\\parbox[";
        switch(GetVAlignment(cell)) {
        case LYX_VALIGN_TOP:
@@ -1963,7 +1977,22 @@ int LyXTabular::TeXCellPreamble(ostream & os, int cell) const
            os << "b";
            break;
        }
-       os << "]{" << GetPWidth(cell) << "}{\\smallskip{}";
+       os << "]{" << GetPWidth(cell) << "}{";
+    } else if (GetUsebox(cell) == BOX_MINIPAGE) {
+       os << "\\begin{minipage}[";
+       switch(GetVAlignment(cell)) {
+       case LYX_VALIGN_TOP:
+           os << "t";
+           break;
+       case LYX_VALIGN_CENTER:
+           os << "m";
+           break;
+       case LYX_VALIGN_BOTTOM:
+           os << "b";
+           break;
+       }
+       os << "]{" << GetPWidth(cell) << "}\n";
+       ++ret;
     }
     return ret;
 }
@@ -1974,13 +2003,17 @@ int LyXTabular::TeXCellPostamble(ostream & os, int cell) const
     int ret = 0;
 
     // usual cells
-    if (GetLinebreaks(cell))
-       os << "\\smallskip{}}";
+    if (GetUsebox(cell) == BOX_PARBOX)
+       os << "}";
+    else if (GetUsebox(cell) == BOX_MINIPAGE) {
+       os << "%\n\\end{minipage}";
+       ret += 2;
+    }
     if (IsMultiColumn(cell)){
        os << '}';
     }
     if (GetRotateCell(cell)) {
-       os << endl << "\\end{sideways}";
+       os << "%\n\\end{sideways}";
        ++ret;
     }
     return ret;
@@ -2150,3 +2183,17 @@ void LyXTabular::Validate(LaTeXFeatures & features) const
        GetCellInset(cell)->Validate(features);
     }
 }
+
+
+bool LyXTabular::UseParbox(int cell) const
+{
+    LyXParagraph *par = GetCellInset(cell)->par;
+
+    for(;par; par = par->next) {
+       for(int i = 0; i < par->Last(); ++i) {
+           if (par->GetChar(i) == LyXParagraph::META_NEWLINE)
+               return true;
+       }
+    }
+    return false;
+}