]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
LFUN to toggle branch inversion status, now available from the
[lyx.git] / src / insets / InsetTabular.cpp
index 2d967bcc3f2b4f0cb4ebf032bd66f838d20ff63c..0834f1a68fa13384e88c4b72e37ecb07e21b1283 100644 (file)
@@ -45,6 +45,8 @@
 #include "Paragraph.h"
 #include "ParagraphParameters.h"
 #include "ParIterator.h"
+#include "TexRow.h"
+#include "texstream.h"
 #include "TextClass.h"
 #include "TextMetrics.h"
 
@@ -61,8 +63,7 @@
 #include "support/gettext.h"
 #include "support/lassert.h"
 #include "support/lstrings.h"
-
-#include <boost/scoped_ptr.hpp>
+#include "support/unique_ptr.h"
 
 #include <cstring>
 #include <iostream>
@@ -96,7 +97,7 @@ int const WIDTH_OF_LINE = 5; // space between double lines
 
 
 ///
-boost::scoped_ptr<Tabular> paste_tabular;
+unique_ptr<Tabular> paste_tabular;
 
 
 struct TabularFeature {
@@ -526,7 +527,7 @@ string const featureAsString(Tabular::Feature action)
 }
 
 
-DocIterator separatorPos(InsetTableCell * cell, docstring const & align_d)
+DocIterator separatorPos(InsetTableCell const * cell, docstring const & align_d)
 {
        DocIterator dit = doc_iterator_begin(&(cell->buffer()), cell);
        for (; dit; dit.forwardChar())
@@ -1103,7 +1104,7 @@ void Tabular::setAlignment(idx_type cell, LyXAlignment align,
                        dpoint = from_utf8(lyxrc.default_decimal_point);
        } else {
                cellInfo(cell).alignment = align;
-               cellInset(cell).get()->setContentAlignment(align);
+               cellInset(cell)->setContentAlignment(align);
        }
 }
 
@@ -1669,7 +1670,13 @@ bool Tabular::hasMultiColumn(col_type c) const
 }
 
 
-Tabular::CellData & Tabular::cellInfo(idx_type cell) const
+Tabular::CellData const & Tabular::cellInfo(idx_type cell) const
+{
+       return cell_info[cellRow(cell)][cellColumn(cell)];
+}
+
+
+Tabular::CellData & Tabular::cellInfo(idx_type cell)
 {
        return cell_info[cellRow(cell)][cellColumn(cell)];
 }
@@ -2309,7 +2316,7 @@ void Tabular::TeXCellPreamble(otexstream & os, idx_type cell,
        // we center in multicol when no decimal point
        if (column_info[c].alignment == LYX_ALIGN_DECIMAL) {
                docstring const align_d = column_info[c].decimal_point;
-               DocIterator const dit = separatorPos(cellInset(cell).get(), align_d);
+               DocIterator const dit = separatorPos(cellInset(cell), align_d);
                ismulticol |= !dit;
        }
 
@@ -2534,7 +2541,7 @@ void Tabular::TeXRow(otexstream & os, row_type row,
                     OutputParams const & runparams) const
 {
        idx_type cell = cellIndex(row, 0);
-       shared_ptr<InsetTableCell> inset = cellInset(cell);
+       InsetTableCell const * inset = cellInset(cell);
        Paragraph const & par = inset->paragraphs().front();
        string const lang = par.getParLanguage(buffer().params())->lang();
 
@@ -2573,7 +2580,7 @@ void Tabular::TeXRow(otexstream & os, row_type row,
                }
 
                TeXCellPreamble(os, cell, ismulticol, ismultirow);
-               shared_ptr<InsetTableCell> inset = cellInset(cell);
+               InsetTableCell const * inset = cellInset(cell);
 
                Paragraph const & par = inset->paragraphs().front();
 
@@ -2606,8 +2613,8 @@ void Tabular::TeXRow(otexstream & os, row_type row,
 
                if (getAlignment(cell) == LYX_ALIGN_DECIMAL) {
                        // copy cell and split in 2
-                       InsetTableCell head = InsetTableCell(*cellInset(cell).get());
-                       head.setBuffer(buffer());
+                       InsetTableCell head = InsetTableCell(*cellInset(cell));
+                       head.setBuffer(const_cast<Buffer &>(buffer()));
                        DocIterator dit = cellInset(cell)->getText(0)->macrocontextPosition();
                        dit.pop_back();
                        dit.push_back(CursorSlice(head));
@@ -2680,8 +2687,7 @@ void Tabular::TeXRow(otexstream & os, row_type row,
 void Tabular::latex(otexstream & os, OutputParams const & runparams) const
 {
        bool const is_tabular_star = !tabular_width.zero();
-       TexRow::RowEntry pos = TexRow::textEntry(runparams.lastid,
-                                                                                        runparams.lastpos);
+       RowEntry pos = TexRow::textEntry(runparams.lastid, runparams.lastpos);
 
        //+---------------------------------------------------------------------
        //+                      first the opening preamble                    +
@@ -2988,6 +2994,13 @@ docstring Tabular::xhtmlRow(XHTMLStream & xs, row_type row,
                        continue;
 
                stringstream attr;
+               
+               Length const cwidth = column_info[c].p_width;
+               if (!cwidth.zero()) {
+                       string const hwidth = cwidth.asHTMLString();
+                       attr << "style =\"width: " << hwidth << ";\" ";
+               }
+               
                attr << "align='";
                switch (getAlignment(cell)) {
                case LYX_ALIGN_LEFT:
@@ -3019,7 +3032,7 @@ docstring Tabular::xhtmlRow(XHTMLStream & xs, row_type row,
                else if (isMultiRow(cell))
                        attr << " rowspan='" << rowSpan(cell) << "'";
 
-               xs << html::StartTag(celltag, attr.str()) << html::CR();
+               xs << html::StartTag(celltag, attr.str(), true) << html::CR();
                ret += cellInset(cell)->xhtml(xs, runparams);
                xs << html::EndTag(celltag) << html::CR();
                ++cell;
@@ -3322,21 +3335,26 @@ void Tabular::plaintext(odocstringstream & os,
 }
 
 
-shared_ptr<InsetTableCell> Tabular::cellInset(idx_type cell) const
+shared_ptr<InsetTableCell> Tabular::cellInset(idx_type cell)
 {
        return cell_info[cellRow(cell)][cellColumn(cell)].inset;
 }
 
 
-shared_ptr<InsetTableCell> Tabular::cellInset(row_type row,
-                                              col_type column) const
+shared_ptr<InsetTableCell> Tabular::cellInset(row_type row, col_type column)
 {
        return cell_info[row][column].inset;
 }
 
 
+InsetTableCell const * Tabular::cellInset(idx_type cell) const
+{
+       return cell_info[cellRow(cell)][cellColumn(cell)].inset.get();
+}
+
+
 void Tabular::setCellInset(row_type row, col_type column,
-                             shared_ptr<InsetTableCell> ins) const
+                           shared_ptr<InsetTableCell> ins)
 {
        CellData & cd = cell_info[row][column];
        cd.inset = ins;
@@ -3413,13 +3431,6 @@ bool InsetTableCell::getStatus(Cursor & cur, FuncRequest const & cmd,
 {
        bool enabled = true;
        switch (cmd.action()) {
-       case LFUN_LAYOUT:
-               enabled = !forcePlainLayout();
-               break;
-       case LFUN_LAYOUT_PARAGRAPH:
-               enabled = allowParagraphCustomization();
-               break;
-
        case LFUN_MATH_DISPLAY:
                if (!hasFixedWidth()) {
                        enabled = false;
@@ -3482,7 +3493,8 @@ InsetTabular::InsetTabular(Buffer * buf, row_type rows,
 
 
 InsetTabular::InsetTabular(InsetTabular const & tab)
-       : Inset(tab), tabular(tab.tabular)
+       : Inset(tab), tabular(tab.tabular),
+         first_visible_cell_(0), offset_valign_(0), rowselect_(false), colselect_(false)
 {
 }
 
@@ -3521,7 +3533,7 @@ bool InsetTabular::insetAllowed(InsetCode code) const
 bool InsetTabular::allowsCaptionVariation(std::string const & newtype) const
 {
        return tabular.is_long_tabular &&
-               (newtype == "Standard" || newtype == "LongTableNoNumber");
+               (newtype == "Standard" || newtype == "Unnumbered");
 }
 
 
@@ -3623,7 +3635,7 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                        // determine horizontal offset because of decimal align (if necessary)
                        int decimal_width = 0;
                        if (tabular.getAlignment(cell) == LYX_ALIGN_DECIMAL) {
-                               InsetTableCell tail = InsetTableCell(*tabular.cellInset(cell).get());
+                               InsetTableCell tail = InsetTableCell(*tabular.cellInset(cell));
                                tail.setBuffer(tabular.buffer());
                                // we need to set macrocontext position everywhere
                                // otherwise we crash with nested insets (e.g. footnotes)
@@ -3951,6 +3963,29 @@ void InsetTabular::addToToc(DocIterator const & cpit, bool output_active,
 }
 
 
+bool InsetTabular::hitSelectRow(BufferView const & bv, int x) const
+{
+       int const x0 = xo(bv) + ADD_TO_TABULAR_WIDTH;
+       return x < x0 || x > x0 + tabular.width();
+}
+
+
+bool InsetTabular::hitSelectColumn(BufferView const & bv, int y) const
+{
+       int const y0 = yo(bv) - tabular.rowAscent(0) + offset_valign_;
+       // FIXME: using ADD_TO_TABULAR_WIDTH is not really correct since
+       // there is no margin added vertically to tabular insets.
+       // However, it works for now.
+       return y < y0 + ADD_TO_TABULAR_WIDTH || y > y0 + tabular.height() - ADD_TO_TABULAR_WIDTH;
+}
+
+
+bool InsetTabular::clickable(BufferView const & bv, int x, int y) const
+{
+       return hitSelectRow(bv, x) || hitSelectColumn(bv, y);
+}
+
+
 void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 {
        LYXERR(Debug::DEBUG, "# InsetTabular::doDispatch: cmd: " << cmd
@@ -3965,8 +4000,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_MOUSE_PRESS: {
                //lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl;
                // select row
-               if (cmd.x() < xo(cur.bv()) + ADD_TO_TABULAR_WIDTH
-                       || cmd.x() > xo(cur.bv()) + tabular.width()) {
+               if (hitSelectRow(cur.bv(), cmd.x())) {
                        row_type r = rowFromY(cur, cmd.y());
                        cur.idx() = tabular.getFirstCellInRow(r);
                        cur.pit() = 0;
@@ -3975,15 +4009,13 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                        cur.idx() = tabular.getLastCellInRow(r);
                        cur.pit() = cur.lastpit();
                        cur.pos() = cur.lastpos();
-                       cur.setSelection(true);
+                       cur.selection(true);
                        bvcur = cur;
                        rowselect_ = true;
                        break;
                }
                // select column
-               int const y0 = yo(cur.bv()) - tabular.rowAscent(0) + offset_valign_;
-               if (cmd.y() < y0 + ADD_TO_TABULAR_WIDTH
-                       || cmd.y() > y0 + tabular.height()) {
+               if (hitSelectColumn(cur.bv(), cmd.y())) {
                        col_type c = columnFromX(cur, cmd.x());
                        cur.idx() = tabular.cellIndex(0, c);
                        cur.pit() = 0;
@@ -3992,7 +4024,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                        cur.idx() = tabular.cellIndex(tabular.nrows() - 1, c);
                        cur.pit() = cur.lastpit();
                        cur.pos() = cur.lastpos();
-                       cur.setSelection(true);
+                       cur.selection(true);
                        bvcur = cur;
                        colselect_ = true;
                        break;
@@ -4025,7 +4057,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                                cur.pit() = 0;
                                cur.pos() = 0;
                                bvcur.setCursor(cur);
-                               bvcur.setSelection(true);
+                               bvcur.selection(true);
                                break;
                        }
                        // select (additional) column
@@ -4037,7 +4069,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                                cur.pit() = 0;
                                cur.pos() = 0;
                                bvcur.setCursor(cur);
-                               bvcur.setSelection(true);
+                               bvcur.selection(true);
                                break;
                        }
                        // only update if selection changes
@@ -4046,7 +4078,7 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                                cur.noScreenUpdate();
                        setCursorFromCoordinates(cur, cmd.x(), cmd.y());
                        bvcur.setCursor(cur);
-                       bvcur.setSelection(true);
+                       bvcur.selection(true);
                        // if this is a multicell selection, we just set the cursor to
                        // the beginning of the cell's text.
                        if (bvcur.selIsMultiCell()) {
@@ -4063,12 +4095,12 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 
        case LFUN_CELL_BACKWARD:
                movePrevCell(cur);
-               cur.setSelection(false);
+               cur.selection(false);
                break;
 
        case LFUN_CELL_FORWARD:
                moveNextCell(cur);
-               cur.setSelection(false);
+               cur.selection(false);
                break;
 
        case LFUN_CHAR_FORWARD_SELECT:
@@ -4922,7 +4954,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
                }
                // check if there is already a caption
                bool have_caption = false;
-               InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()).get());
+               InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()));
                ParagraphList::const_iterator pit = itc.paragraphs().begin();
                ParagraphList::const_iterator pend = itc.paragraphs().end();
                for (; pit != pend; ++pit) {
@@ -5166,7 +5198,7 @@ int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const
 Inset * InsetTabular::editXY(Cursor & cur, int x, int y)
 {
        //lyxerr << "InsetTabular::editXY: " << this << endl;
-       cur.setSelection(false);
+       cur.selection(false);
        cur.push(*this);
        cur.idx() = getNearestCell(cur.bv(), x, y);
        return cur.bv().textMetrics(&cell(cur.idx())->text()).editXY(cur, x, y);
@@ -5335,6 +5367,8 @@ void InsetTabular::movePrevCell(Cursor & cur, EntryDirection entry_from)
 
 void InsetTabular::tabularFeatures(Cursor & cur, string const & argument)
 {
+       cur.recordUndoInset(this);
+
        istringstream is(argument);
        string s;
        // Safe guard.
@@ -5461,8 +5495,6 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                break;
        }
 
-       cur.recordUndoInset(this);
-
        getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
        row_type const row = tabular.cellRow(cur.idx());
        col_type const column = tabular.cellColumn(cur.idx());
@@ -5525,7 +5557,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                cur.idx() = tabular.cellIndex(sel_row_start, column);
                cur.pit() = 0;
                cur.pos() = 0;
-               cur.setSelection(false);
+               cur.selection(false);
                break;
 
        case Tabular::DELETE_COLUMN:
@@ -5548,7 +5580,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                cur.idx() = tabular.cellIndex(row, sel_col_start);
                cur.pit() = 0;
                cur.pos() = 0;
-               cur.setSelection(false);
+               cur.selection(false);
                break;
 
        case Tabular::COPY_ROW:
@@ -5664,7 +5696,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                                                   tabular.rightLine(cur.selEnd().idx()));
                cur.pit() = 0;
                cur.pos() = 0;
-               cur.setSelection(false);
+               cur.selection(false);
                break;
        }
 
@@ -5721,7 +5753,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                                                tabular.getAlignment(cur.selEnd().idx()));
                cur.pit() = 0;
                cur.pos() = 0;
-               cur.setSelection(false);
+               cur.selection(false);
                break;
        }
 
@@ -5926,7 +5958,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                cur.idx() = tabular.setLTCaption(row, true);
                cur.pit() = 0;
                cur.pos() = 0;
-               cur.setSelection(false);
+               cur.selection(false);
                // If a row is set as caption, then also insert
                // a caption. Otherwise the LaTeX output is broken.
                // Select cell if it is non-empty
@@ -5942,7 +5974,7 @@ void InsetTabular::tabularFeatures(Cursor & cur,
                cur.idx() = tabular.setLTCaption(row, false);
                cur.pit() = 0;
                cur.pos() = 0;
-               cur.setSelection(false);
+               cur.selection(false);
                FuncRequest fr(LFUN_INSET_DISSOLVE, "caption");
                if (lyx::getStatus(fr).enabled())
                        lyx::dispatch(fr);