]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetTabular.cpp
This should be the last of the commits refactoring the InsetLayout code.
[lyx.git] / src / insets / InsetTabular.cpp
index 8a2fa91208119c0f7d804ea0eb6ad8e0ce9b337e..f69da2b74bf8f967929aea94691a48bce380343d 100644 (file)
 #include "Buffer.h"
 #include "BufferParams.h"
 #include "BufferView.h"
-#include "Color.h"
 #include "CoordCache.h"
 #include "Counters.h"
 #include "Cursor.h"
 #include "CutAndPaste.h"
-#include "debug.h"
 #include "DispatchResult.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
-#include "gettext.h"
 #include "Language.h"
 #include "LaTeXFeatures.h"
 #include "Lexer.h"
+#include "LyXFunc.h"
 #include "MetricsInfo.h"
 #include "OutputParams.h"
 #include "paragraph_funcs.h"
 #include "Paragraph.h"
 #include "ParagraphParameters.h"
 #include "ParIterator.h"
+#include "TextClass.h"
 #include "TextMetrics.h"
 
-#include "support/convert.h"
-#include "support/lstrings.h"
-
 #include "frontends/alert.h"
 #include "frontends/Clipboard.h"
 #include "frontends/Painter.h"
 #include "frontends/Selection.h"
 
+
+#include "support/convert.h"
+#include "support/debug.h"
+#include "support/docstream.h"
+#include "support/FileName.h"
+#include "support/gettext.h"
+#include "support/lstrings.h"
+
+#include <boost/scoped_ptr.hpp>
+
 #include <sstream>
 #include <iostream>
 #include <limits>
+#include <cstring>
 
-using std::abs;
-using std::endl;
-using std::getline;
-using std::istream;
-using std::istringstream;
-using std::max;
-using std::ostream;
-using std::ostringstream;
-using std::string;
-using std::swap;
-using std::vector;
-
-#ifndef CXX_GLOBAL_CSTD
-using std::strlen;
-#endif
+using namespace std;
+using namespace lyx::support;
 
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
 namespace lyx {
 
-using support::prefixIs;
-using support::ltrim;
-using support::rtrim;
-using support::suffixIs;
-
 using cap::dirtyTabularStack;
 using cap::tabularStackDirty;
 
@@ -175,7 +164,7 @@ TabularFeature tabularFeature[] =
 };
 
 
-class FeatureEqual : public std::unary_function<TabularFeature, bool> {
+class FeatureEqual : public unary_function<TabularFeature, bool> {
 public:
        FeatureEqual(Tabular::Feature feature)
                : feature_(feature) {}
@@ -469,7 +458,7 @@ string const featureAsString(Tabular::Feature feature)
 {
        TabularFeature * end = tabularFeature +
                sizeof(tabularFeature) / sizeof(TabularFeature);
-       TabularFeature * it = std::find_if(tabularFeature, end,
+       TabularFeature * it = find_if(tabularFeature, end,
                                           FeatureEqual(feature));
        return (it == end) ? string() : it->feature;
 }
@@ -496,7 +485,9 @@ Tabular::cellstruct::cellstruct(BufferParams const & bp)
          usebox(BOX_NONE),
          rotate(false),
          inset(new InsetText(bp))
-{}
+{
+       inset->paragraphs().back().layout(bp.getTextClass().emptyLayout());
+}
 
 
 Tabular::cellstruct::cellstruct(cellstruct const & cs)
@@ -1102,7 +1093,7 @@ void toggleFixedWidth(Cursor & cur, InsetText * inset, bool fixedWidth)
        cur.push(*inset);
        // undo information has already been recorded
        inset->getText(0)->setLayout(cur.bv().buffer(), 0, cur.lastpit() + 1,
-                       bp.getTextClass().defaultLayoutName());
+                       bp.getTextClass().emptyLayoutName());
        cur.pop();
 }
 
@@ -1973,7 +1964,8 @@ int Tabular::TeXTopHLine(odocstream & os, row_type row) const
                        ++tmp;
        }
        if (use_booktabs && row == 0) {
-               os << "\\toprule ";
+               if (topLine(fcell))
+                       os << "\\toprule ";
        } else if (tmp == n - fcell) {
                os << (use_booktabs ? "\\midrule " : "\\hline ");
        } else if (tmp) {
@@ -2009,7 +2001,8 @@ int Tabular::TeXBottomHLine(odocstream & os, row_type row) const
                        ++tmp;
        }
        if (use_booktabs && row == rowCount() - 1) {
-               os << "\\bottomrule";
+               if (bottomLine(fcell))
+                       os << "\\bottomrule";
        } else if (tmp == n - fcell) {
                os << (use_booktabs ? "\\midrule" : "\\hline");
        } else if (tmp) {
@@ -2728,7 +2721,7 @@ void Tabular::plaintextPrintCell(Buffer const & buf, odocstream & os,
 
 void Tabular::plaintext(Buffer const & buf, odocstream & os,
                           OutputParams const & runparams, int const depth,
-                          bool onlydata, unsigned char delim) const
+                          bool onlydata, char_type delim) const
 {
        // first calculate the width of the single columns
        vector<unsigned int> clen(columnCount());
@@ -2772,7 +2765,9 @@ void Tabular::plaintext(Buffer const & buf, odocstream & os,
                        if (isPartOfMultiColumn(i, j))
                                continue;
                        if (onlydata && j > 0)
-                               os << delim;
+                               // we don't use operator<< for single UCS4 character.
+                               // see explanation in docstream.h
+                               os.put(delim);
                        plaintextPrintCell(buf, os, runparams,
                                           cell, i, j, clen, onlydata);
                        ++cell;
@@ -2818,8 +2813,8 @@ Tabular::getCellFromInset(Inset const * inset) const
 
        for (idx_type cell = 0, n = cellCount(); cell < n; ++cell)
                if (getCellInset(cell).get() == inset) {
-                       LYXERR(Debug::INSETTEXT) << "Tabular::getCellFromInset: "
-                               << "cell=" << cell << endl;
+                       LYXERR(Debug::INSETTEXT, "Tabular::getCellFromInset: "
+                               << "cell=" << cell);
                        return cell;
                }
 
@@ -2908,6 +2903,15 @@ void InsetTabular::buffer(Buffer const * b)
 }
 
 
+bool InsetTabular::insetAllowed(InsetCode code) const
+{
+       if (code == MATHMACRO_CODE)
+               return false;
+
+       return true;
+}
+
+
 void InsetTabular::write(Buffer const & buf, ostream & os) const
 {
        os << "Tabular" << endl;
@@ -3008,6 +3012,8 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
        x += scx_;
        x += ADD_TO_TABULAR_WIDTH;
 
+       bool const original_drawing_state = pi.pain.isDrawingEnabled();
+
        idx_type idx = 0;
        first_visible_cell = Tabular::npos;
        for (row_type i = 0; i < tabular.rowCount(); ++i) {
@@ -3031,7 +3037,7 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const
                                pi.pain.setDrawingEnabled(false);
                                cell(idx)->draw(pi, cx, y);
                                drawCellLines(pi.pain, nx, y, i, idx, pi.erased_);
-                               pi.pain.setDrawingEnabled(true);
+                               pi.pain.setDrawingEnabled(original_drawing_state);
                        } else {
                                cell(idx)->draw(pi, cx, y);
                                drawCellLines(pi.pain, nx, y, i, idx, pi.erased_);
@@ -3064,7 +3070,7 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
 
        if (!cur.selection())
                return;
-       if (!ptr_cmp(&cur.inset(), this))
+       if (&cur.inset() != this)
                return;
 
        //resetPos(cur);
@@ -3088,7 +3094,7 @@ void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
                                int const w = tabular.columnWidth(cell);
                                if (i >= cs && i <= ce && j >= rs && j <= re)
                                        pi.pain.fillRectangle(xx, y, w, h,
-                                                             Color::selection);
+                                                             Color_selection);
                                xx += w;
                        }
                        y += h;
@@ -3107,12 +3113,12 @@ void InsetTabular::drawCellLines(Painter & pain, int x, int y,
 {
        int x2 = x + tabular.columnWidth(cell);
        bool on_off = false;
-       Color::color col = Color::tabularline;
-       Color::color onoffcol = Color::tabularonoffline;
+       ColorCode col = Color_tabularline;
+       ColorCode onoffcol = Color_tabularonoffline;
 
        if (erased) {
-               col = Color::deletedtext;
-               onoffcol = Color::deletedtext;
+               col = Color_deletedtext;
+               onoffcol = Color_deletedtext;
        }
 
        if (!tabular.topAlreadyDrawn(cell)) {
@@ -3150,13 +3156,13 @@ docstring const InsetTabular::editMessage() const
 }
 
 
-void InsetTabular::edit(Cursor & cur, bool left)
+void InsetTabular::edit(Cursor & cur, bool front, EntryDirection)
 {
        //lyxerr << "InsetTabular::edit: " << this << endl;
        cur.finishUndo();
        cur.selection() = false;
        cur.push(*this);
-       if (left) {
+       if (front) {
                if (isRightToLeft(cur))
                        cur.idx() = tabular.getLastCellInRow(0);
                else
@@ -3199,8 +3205,8 @@ void InsetTabular::updateLabels(Buffer const & buf, ParIterator const & it)
 
 void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
 {
-       LYXERR(Debug::DEBUG) << "# InsetTabular::doDispatch: cmd: " << cmd
-                            << "\n  cur:" << cur << endl;
+       LYXERR(Debug::DEBUG, "# InsetTabular::doDispatch: cmd: " << cmd
+                            << "\n  cur:" << cur);
        CursorSlice sl = cur.top();
        Cursor & bvcur = cur.bv().cursor();
 
@@ -3256,9 +3262,9 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CHAR_FORWARD:
                cell(cur.idx())->dispatch(cur, cmd);
                if (!cur.result().dispatched()) {
-                       isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur);
+                       moveNextCell(cur);
                        if (sl == cur.top())
-                               cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                               cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        else
                                cur.dispatched();
                }
@@ -3268,14 +3274,40 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_CHAR_BACKWARD:
                cell(cur.idx())->dispatch(cur, cmd);
                if (!cur.result().dispatched()) {
-                       isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur);
+                       movePrevCell(cur);
                        if (sl == cur.top())
-                               cmd = FuncRequest(LFUN_FINISHED_LEFT);
+                               cmd = FuncRequest(LFUN_FINISHED_BACKWARD);
                        else
                                cur.dispatched();
                }
                break;
 
+       case LFUN_CHAR_RIGHT_SELECT:
+       case LFUN_CHAR_RIGHT:
+               //FIXME: for visual cursor, really move right
+               if (isRightToLeft(cur))
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ?
+                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD));
+               else
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_RIGHT_SELECT ?
+                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD));
+               break;
+
+       case LFUN_CHAR_LEFT_SELECT:
+       case LFUN_CHAR_LEFT:
+               //FIXME: for visual cursor, really move left
+               if (isRightToLeft(cur))
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ?
+                                       LFUN_CHAR_FORWARD_SELECT : LFUN_CHAR_FORWARD));
+               else
+                       lyx::dispatch(FuncRequest(
+                               cmd.action == LFUN_CHAR_LEFT_SELECT ?
+                                       LFUN_CHAR_BACKWARD_SELECT : LFUN_CHAR_BACKWARD));
+               break;
+
        case LFUN_DOWN_SELECT:
        case LFUN_DOWN:
                cell(cur.idx())->dispatch(cur, cmd);
@@ -3292,9 +3324,9 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                                cur.pos() = tm.x2pos(cur.pit(), 0, cur.targetX());
                        }
                if (sl == cur.top()) {
-                       // we trick it to go to the RIGHT after leaving the
+                       // we trick it to go to forward after leaving the
                        // tabular.
-                       cmd = FuncRequest(LFUN_FINISHED_RIGHT);
+                       cmd = FuncRequest(LFUN_FINISHED_FORWARD);
                        cur.undispatched();
                }
                break;
@@ -3374,8 +3406,18 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        case LFUN_FILE_INSERT_PLAINTEXT_PARA:
        case LFUN_FILE_INSERT_PLAINTEXT: {
                // FIXME UNICODE
-               docstring const tmpstr = cur.bv().contentsOfPlaintextFile(to_utf8(cmd.argument()), false);
-               if (!tmpstr.empty() && !insertPlaintextString(cur.bv(), tmpstr, false))
+               docstring const tmpstr = cur.bv().contentsOfPlaintextFile(
+                       FileName(to_utf8(cmd.argument())));
+               if (tmpstr.empty())
+                       break;
+               cur.recordUndoInset(INSERT_UNDO);
+               if (insertPlaintextString(cur.bv(), tmpstr, false)) {
+                       // content has been replaced,
+                       // so cursor might be invalid
+                       cur.pos() = cur.lastpos();
+                       cur.pit() = cur.lastpit();
+                       bvcur.setCursor(cur);
+               } else
                        cur.undispatched();
                break;
        }
@@ -3421,10 +3463,12 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
                // pass to InsertPlaintextString, but
                // only if we have multi-cell content
                if (clip.find_first_of(from_ascii("\t\n")) != docstring::npos) {
+                       cur.recordUndoInset(INSERT_UNDO);
                        if (insertPlaintextString(cur.bv(), clip, false)) {
                                // content has been replaced,
                                // so cursor might be invalid
                                cur.pos() = cur.lastpos();
+                               cur.pit() = cur.lastpit();
                                bvcur.setCursor(cur);
                                break;
                        }
@@ -3435,7 +3479,8 @@ void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
        }
 
        case LFUN_PASTE:
-               if (tabularStackDirty() && theClipboard().isInternal()) {
+               if (tabularStackDirty() && theClipboard().isInternal() ||
+                   !theClipboard().hasInternal() && theClipboard().hasLyXContents()) {
                        cur.recordUndoInset(INSERT_UNDO);
                        pasteClipboard(cur);
                        break;
@@ -3734,7 +3779,7 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
        }
 
        // disable in non-fixed-width cells
-       case LFUN_BREAK_LINE:
+       case LFUN_NEW_LINE:
        case LFUN_BREAK_PARAGRAPH:
        case LFUN_BREAK_PARAGRAPH_SKIP: {
                if (tabular.getPWidth(cur.idx()).zero()) {
@@ -3911,7 +3956,7 @@ void InsetTabular::setCursorFromCoordinates(Cursor & cur, int x, int y) const
 InsetTabular::idx_type InsetTabular::getNearestCell(BufferView & bv, int x, int y) const
 {
        idx_type idx_min = 0;
-       int dist_min = std::numeric_limits<int>::max();
+       int dist_min = numeric_limits<int>::max();
        for (idx_type i = 0, n = nargs(); i != n; ++i) {
                if (bv.coordCache().getInsets().has(tabular.getCellInset(i).get())) {
                        int const d = dist(bv, i, x, y);
@@ -4661,7 +4706,7 @@ void InsetTabular::rejectChanges(BufferParams const & bparams)
 }
 
 
-bool InsetTabular::forceDefaultParagraphs(idx_type cell) const
+bool InsetTabular::allowParagraphCustomization(idx_type cell) const
 {
        return tabular.getPWidth(cell).zero();
 }