#include "InsetTabular.h"
-#include "Buffer.h"
#include "buffer_funcs.h"
+#include "Buffer.h"
#include "BufferParams.h"
#include "BufferView.h"
+#include "CoordCache.h"
#include "Counters.h"
#include "Cursor.h"
#include "CutAndPaste.h"
-#include "CoordCache.h"
-#include "debug.h"
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
-#include "gettext.h"
#include "Language.h"
#include "LaTeXFeatures.h"
-#include "Color.h"
-#include "callback.h"
#include "Lexer.h"
+#include "LyXFunc.h"
#include "MetricsInfo.h"
#include "OutputParams.h"
-#include "Paragraph.h"
#include "paragraph_funcs.h"
+#include "Paragraph.h"
#include "ParagraphParameters.h"
#include "ParIterator.h"
-#include "Undo.h"
-
-#include "support/convert.h"
-#include "support/lstrings.h"
+#include "TextClass.h"
+#include "TextMetrics.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;
};
-class FeatureEqual : public std::unary_function<TabularFeature, bool> {
+class FeatureEqual : public unary_function<TabularFeature, bool> {
public:
FeatureEqual(Tabular::Feature feature)
: feature_(feature) {}
bool getTokenValue(string const & str, char const * token, Length & len)
{
- // set the lenght to be zero() as default as this it should be if not
+ // set the length to be zero() as default as this it should be if not
// in the file format.
len = Length();
string tmp;
{
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;
}
usebox(BOX_NONE),
rotate(false),
inset(new InsetText(bp))
-{}
+{
+ inset->paragraphs().back().layout(bp.getTextClass().emptyLayout());
+}
Tabular::cellstruct::cellstruct(cellstruct const & cs)
{}
+Tabular::Tabular()
+{
+ // unusable now!
+}
+
+
Tabular::Tabular(BufferParams const & bp, row_type rows_arg,
col_type columns_arg)
{
row_type row = cellRow(cell);
while (--column &&
(cell_info[row][column].multicolumn ==
- Tabular::CELL_PART_OF_MULTICOLUMN));
+ Tabular::CELL_PART_OF_MULTICOLUMN)) { }
if (getAdditionalWidth(cell_info[row][column].cellno))
return false;
return rightLine(cell_info[row][column].cellno);
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();
}
++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) {
++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) {
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());
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;
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;
}
}
+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;
}
-bool InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
+void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
{
//lyxerr << "InsetTabular::metrics: " << mi.base.bv << " width: " <<
// mi.base.textwidth << "\n";
dim.asc = tabular.rowAscent(0);
dim.des = tabular.height() - dim.asc;
dim.wid = tabular.width() + 2 * ADD_TO_TABULAR_WIDTH;
- bool const changed = dim_ != dim;
- dim_ = dim;
- return changed;
}
void InsetTabular::draw(PainterInfo & pi, int x, int y) const
{
- setPosCache(pi, x, y);
-
//lyxerr << "InsetTabular::draw: " << x << " " << y << endl;
BufferView * bv = pi.base.bv;
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) {
first_visible_cell = idx;
int const cx = nx + tabular.getBeginningOfTextInCell(idx);
+ // Cache the Inset position.
+ bv->coordCache().insets().add(cell(idx).get(), cx, y);
if (nx + tabular.columnWidth(idx) < 0
|| nx > bv->workWidth()
|| y + d < 0
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_);
void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
{
- setPosCache(pi, x, y);
-
Cursor & cur = pi.base.bv->cursor();
x += scx_ + ADD_TO_TABULAR_WIDTH;
if (!cur.selection())
return;
- if (!ptr_cmp(&cur.inset(), this))
+ if (&cur.inset() != this)
return;
//resetPos(cur);
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;
{
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)) {
}
-void InsetTabular::edit(Cursor & cur, bool left)
+void InsetTabular::edit(Cursor & cur, bool front, EntryDirection)
{
//lyxerr << "InsetTabular::edit: " << this << endl;
- finishUndo();
+ cur.finishUndo();
cur.selection() = false;
cur.push(*this);
- if (left) {
+ if (front) {
if (isRightToLeft(cur))
cur.idx() = tabular.getLastCellInRow(0);
else
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();
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();
}
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);
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;
case LFUN_FILE_INSERT_PLAINTEXT_PARA:
case LFUN_FILE_INSERT_PLAINTEXT: {
// FIXME UNICODE
- docstring const tmpstr = getContentsOfPlaintextFile(&cur.bv(), 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;
}
case LFUN_CUT:
if (tablemode(cur)) {
if (copySelection(cur)) {
- recordUndoInset(cur, Undo::DELETE);
+ cur.recordUndoInset(DELETE_UNDO);
cutSelection(cur);
}
}
case LFUN_CHAR_DELETE_BACKWARD:
case LFUN_CHAR_DELETE_FORWARD:
if (tablemode(cur)) {
- recordUndoInset(cur, Undo::DELETE);
+ cur.recordUndoInset(DELETE_UNDO);
cutSelection(cur);
}
else
if (!cur.selection())
break;
if (tablemode(cur)) {
- finishUndo();
+ cur.finishUndo();
copySelection(cur);
} else
cell(cur.idx())->dispatch(cur, 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;
}
}
case LFUN_PASTE:
- if (tabularStackDirty() && theClipboard().isInternal()) {
- recordUndoInset(cur, Undo::INSERT);
+ if (tabularStackDirty() && theClipboard().isInternal() ||
+ !theClipboard().hasInternal() && theClipboard().hasLyXContents()) {
+ cur.recordUndoInset(INSERT_UNDO);
pasteClipboard(cur);
break;
}
case LFUN_FONT_NOUN:
case LFUN_FONT_ITAL:
case LFUN_FONT_FRAK:
- case LFUN_FONT_CODE:
+ case LFUN_FONT_TYPEWRITER:
case LFUN_FONT_SANS:
case LFUN_FONT_FREE_APPLY:
case LFUN_FONT_FREE_UPDATE:
// disable these with multiple cells selected
case LFUN_INSET_INSERT:
case LFUN_TABULAR_INSERT:
- case LFUN_CHARSTYLE_INSERT:
+ case LFUN_FLEX_INSERT:
case LFUN_FLOAT_INSERT:
case LFUN_FLOAT_WIDE_INSERT:
case LFUN_FOOTNOTE_INSERT:
}
// disable in non-fixed-width cells
- case LFUN_BREAK_LINE:
+ case LFUN_NEW_LINE:
case LFUN_BREAK_PARAGRAPH:
- case LFUN_BREAK_PARAGRAPH_KEEP_LAYOUT:
case LFUN_BREAK_PARAGRAPH_SKIP: {
if (tabular.getPWidth(cur.idx()).zero()) {
status.enabled(false);
return cell(cur.idx())->getStatus(cur, cmd, status);
case LFUN_INSET_MODIFY:
- if (translate(cmd.getArg(0)) == TABULAR_CODE) {
+ if (insetCode(cmd.getArg(0)) == TABULAR_CODE) {
status.enabled(true);
return true;
}
// if the table is inside a float it doesn't need the informaltable
// wrapper. Search for it.
for (master = owner(); master; master = master->owner())
- if (master->lyxCode() == Inset::FLOAT_CODE)
+ if (master->lyxCode() == FLOAT_CODE)
break;
#endif
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);
break;
}
- recordUndoInset(cur, Undo::ATOMIC);
+ cur.recordUndoInset(ATOMIC_UNDO);
getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
row_type const row = tabular.cellRow(cur.idx());
}
-bool InsetTabular::forceDefaultParagraphs(idx_type cell) const
+bool InsetTabular::allowParagraphCustomization(idx_type cell) const
{
return tabular.getPWidth(cell).zero();
}