2002-09-25 14:26:13 +00:00
|
|
|
/**
|
2007-04-25 01:24:38 +00:00
|
|
|
* \file InsetTabular.cpp
|
2002-09-25 14:26:13 +00:00
|
|
|
* This file is part of LyX, the document processor.
|
|
|
|
* Licence details can be found in the file COPYING.
|
2002-03-21 17:09:55 +00:00
|
|
|
*
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author Lars Gullik Bjønnes
|
2007-04-26 12:54:21 +00:00
|
|
|
* \author Matthias Ettrich
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author José Matos
|
2007-04-26 12:54:21 +00:00
|
|
|
* \author Jean-Marc Lasgouttes
|
|
|
|
* \author Angus Leeming
|
|
|
|
* \author John Levon
|
2008-11-14 15:58:50 +00:00
|
|
|
* \author André Pönitz
|
|
|
|
* \author Jürgen Vigna
|
2009-07-13 23:25:47 +00:00
|
|
|
* \author Uwe Stöhr
|
2010-02-11 01:07:54 +00:00
|
|
|
* \author Edwin Leuven
|
2012-12-24 10:51:28 +00:00
|
|
|
* \author Scott Kostyshak
|
2000-04-19 14:42:19 +00:00
|
|
|
*
|
2003-08-23 00:17:00 +00:00
|
|
|
* Full author contact details are available in file CREDITS.
|
2000-04-19 14:42:19 +00:00
|
|
|
*/
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "InsetTabular.h"
|
|
|
|
|
2007-08-12 21:43:58 +00:00
|
|
|
#include "buffer_funcs.h"
|
2007-10-03 20:18:58 +00:00
|
|
|
#include "Buffer.h"
|
2007-04-26 12:54:21 +00:00
|
|
|
#include "BufferParams.h"
|
|
|
|
#include "BufferView.h"
|
2007-10-03 20:18:58 +00:00
|
|
|
#include "CoordCache.h"
|
2007-08-12 21:43:58 +00:00
|
|
|
#include "Counters.h"
|
2007-04-26 14:56:30 +00:00
|
|
|
#include "Cursor.h"
|
2007-04-26 12:54:21 +00:00
|
|
|
#include "CutAndPaste.h"
|
|
|
|
#include "DispatchResult.h"
|
|
|
|
#include "FuncRequest.h"
|
|
|
|
#include "FuncStatus.h"
|
2012-12-29 09:31:41 +00:00
|
|
|
#include "InsetList.h"
|
2007-04-26 12:54:21 +00:00
|
|
|
#include "Language.h"
|
|
|
|
#include "LaTeXFeatures.h"
|
|
|
|
#include "Lexer.h"
|
2010-02-09 16:11:13 +00:00
|
|
|
#include "LyX.h"
|
2008-03-15 12:22:28 +00:00
|
|
|
#include "LyXRC.h"
|
2007-04-26 12:54:21 +00:00
|
|
|
#include "MetricsInfo.h"
|
|
|
|
#include "OutputParams.h"
|
2009-12-14 15:39:13 +00:00
|
|
|
#include "output_xhtml.h"
|
2007-10-03 20:18:58 +00:00
|
|
|
#include "Paragraph.h"
|
2007-04-26 12:54:21 +00:00
|
|
|
#include "ParagraphParameters.h"
|
2007-08-12 21:43:58 +00:00
|
|
|
#include "ParIterator.h"
|
2007-11-07 23:25:08 +00:00
|
|
|
#include "TextClass.h"
|
2007-10-11 09:59:01 +00:00
|
|
|
#include "TextMetrics.h"
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-03-27 22:26:24 +00:00
|
|
|
#include "frontends/Application.h"
|
2007-04-28 20:44:46 +00:00
|
|
|
#include "frontends/alert.h"
|
2007-04-26 12:54:21 +00:00
|
|
|
#include "frontends/Clipboard.h"
|
|
|
|
#include "frontends/Painter.h"
|
|
|
|
#include "frontends/Selection.h"
|
|
|
|
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/convert.h"
|
|
|
|
#include "support/debug.h"
|
|
|
|
#include "support/docstream.h"
|
|
|
|
#include "support/FileName.h"
|
|
|
|
#include "support/gettext.h"
|
2008-06-18 18:54:31 +00:00
|
|
|
#include "support/lassert.h"
|
2008-02-18 07:14:42 +00:00
|
|
|
#include "support/lstrings.h"
|
|
|
|
|
2007-10-25 12:41:02 +00:00
|
|
|
#include <boost/scoped_ptr.hpp>
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
#include <cstring>
|
2007-04-26 12:54:21 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <limits>
|
2013-03-08 19:52:18 +00:00
|
|
|
#include <sstream>
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2007-12-12 10:16:00 +00:00
|
|
|
using namespace std;
|
2007-12-12 18:57:56 +00:00
|
|
|
using namespace lyx::support;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2007-07-17 17:33:36 +00:00
|
|
|
|
2008-03-27 22:26:24 +00:00
|
|
|
|
2007-07-17 17:33:36 +00:00
|
|
|
namespace lyx {
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
using cap::dirtyTabularStack;
|
|
|
|
using cap::tabularStackDirty;
|
|
|
|
|
|
|
|
using graphics::PreviewLoader;
|
|
|
|
|
|
|
|
using frontend::Painter;
|
|
|
|
using frontend::Clipboard;
|
|
|
|
|
|
|
|
namespace Alert = frontend::Alert;
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
int const ADD_TO_HEIGHT = 2; // in cell
|
2010-11-25 22:06:31 +00:00
|
|
|
int const ADD_TO_TABULAR_WIDTH = 6; // horizontal space before and after the table
|
2008-03-18 18:08:32 +00:00
|
|
|
int const default_line_space = 10; // ?
|
|
|
|
int const WIDTH_OF_LINE = 5; // space between double lines
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
boost::scoped_ptr<Tabular> paste_tabular;
|
|
|
|
|
|
|
|
|
|
|
|
struct TabularFeature {
|
|
|
|
Tabular::Feature action;
|
|
|
|
string feature;
|
2010-02-18 08:28:46 +00:00
|
|
|
bool need_value;
|
2007-04-26 12:54:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
TabularFeature tabularFeature[] =
|
|
|
|
{
|
2010-11-01 16:16:40 +00:00
|
|
|
// the SET/UNSET actions are used by the table dialog,
|
|
|
|
// the TOGGLE actions by the table toolbar buttons
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::APPEND_ROW, "append-row", false },
|
|
|
|
{ Tabular::APPEND_COLUMN, "append-column", false },
|
|
|
|
{ Tabular::DELETE_ROW, "delete-row", false },
|
|
|
|
{ Tabular::DELETE_COLUMN, "delete-column", false },
|
|
|
|
{ Tabular::COPY_ROW, "copy-row", false },
|
|
|
|
{ Tabular::COPY_COLUMN, "copy-column", false },
|
2012-12-24 10:51:28 +00:00
|
|
|
{ Tabular::MOVE_COLUMN_RIGHT, "move-column-right", false },
|
|
|
|
{ Tabular::MOVE_COLUMN_LEFT, "move-column-left", false },
|
|
|
|
{ Tabular::MOVE_ROW_DOWN, "move-row-down", false },
|
|
|
|
{ Tabular::MOVE_ROW_UP, "move-row-up", false },
|
2010-02-19 10:03:03 +00:00
|
|
|
{ Tabular::SET_LINE_TOP, "set-line-top", true },
|
|
|
|
{ Tabular::SET_LINE_BOTTOM, "set-line-bottom", true },
|
|
|
|
{ Tabular::SET_LINE_LEFT, "set-line-left", true },
|
|
|
|
{ Tabular::SET_LINE_RIGHT, "set-line-right", true },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::TOGGLE_LINE_TOP, "toggle-line-top", false },
|
|
|
|
{ Tabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom", false },
|
|
|
|
{ Tabular::TOGGLE_LINE_LEFT, "toggle-line-left", false },
|
|
|
|
{ Tabular::TOGGLE_LINE_RIGHT, "toggle-line-right", false },
|
|
|
|
{ Tabular::ALIGN_LEFT, "align-left", false },
|
|
|
|
{ Tabular::ALIGN_RIGHT, "align-right", false },
|
|
|
|
{ Tabular::ALIGN_CENTER, "align-center", false },
|
|
|
|
{ Tabular::ALIGN_BLOCK, "align-block", false },
|
2010-06-05 07:44:44 +00:00
|
|
|
{ Tabular::ALIGN_DECIMAL, "align-decimal", false },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::VALIGN_TOP, "valign-top", false },
|
|
|
|
{ Tabular::VALIGN_BOTTOM, "valign-bottom", false },
|
|
|
|
{ Tabular::VALIGN_MIDDLE, "valign-middle", false },
|
|
|
|
{ Tabular::M_ALIGN_LEFT, "m-align-left", false },
|
|
|
|
{ Tabular::M_ALIGN_RIGHT, "m-align-right", false },
|
|
|
|
{ Tabular::M_ALIGN_CENTER, "m-align-center", false },
|
|
|
|
{ Tabular::M_VALIGN_TOP, "m-valign-top", false },
|
|
|
|
{ Tabular::M_VALIGN_BOTTOM, "m-valign-bottom", false },
|
|
|
|
{ Tabular::M_VALIGN_MIDDLE, "m-valign-middle", false },
|
|
|
|
{ Tabular::MULTICOLUMN, "multicolumn", false },
|
2010-10-29 04:09:49 +00:00
|
|
|
{ Tabular::SET_MULTICOLUMN, "set-multicolumn", false },
|
|
|
|
{ Tabular::UNSET_MULTICOLUMN, "unset-multicolumn", false },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::MULTIROW, "multirow", false },
|
2010-10-29 04:09:49 +00:00
|
|
|
{ Tabular::SET_MULTIROW, "set-multirow", false },
|
|
|
|
{ Tabular::UNSET_MULTIROW, "unset-multirow", false },
|
2010-11-07 05:32:28 +00:00
|
|
|
{ Tabular::SET_MROFFSET, "set-mroffset", true },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::SET_ALL_LINES, "set-all-lines", false },
|
|
|
|
{ Tabular::UNSET_ALL_LINES, "unset-all-lines", false },
|
|
|
|
{ Tabular::SET_LONGTABULAR, "set-longtabular", false },
|
|
|
|
{ Tabular::UNSET_LONGTABULAR, "unset-longtabular", false },
|
|
|
|
{ Tabular::SET_PWIDTH, "set-pwidth", true },
|
|
|
|
{ Tabular::SET_MPWIDTH, "set-mpwidth", true },
|
2012-03-19 00:21:26 +00:00
|
|
|
{ Tabular::SET_ROTATE_TABULAR, "set-rotate-tabular", true },
|
|
|
|
{ Tabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular", true },
|
|
|
|
{ Tabular::TOGGLE_ROTATE_TABULAR, "toggle-rotate-tabular", true },
|
2012-03-16 01:29:37 +00:00
|
|
|
{ Tabular::SET_ROTATE_CELL, "set-rotate-cell", true },
|
|
|
|
{ Tabular::UNSET_ROTATE_CELL, "unset-rotate-cell", true },
|
|
|
|
{ Tabular::TOGGLE_ROTATE_CELL, "toggle-rotate-cell", true },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::SET_USEBOX, "set-usebox", true },
|
|
|
|
{ Tabular::SET_LTHEAD, "set-lthead", true },
|
|
|
|
{ Tabular::UNSET_LTHEAD, "unset-lthead", true },
|
|
|
|
{ Tabular::SET_LTFIRSTHEAD, "set-ltfirsthead", true },
|
|
|
|
{ Tabular::UNSET_LTFIRSTHEAD, "unset-ltfirsthead", true },
|
|
|
|
{ Tabular::SET_LTFOOT, "set-ltfoot", true },
|
|
|
|
{ Tabular::UNSET_LTFOOT, "unset-ltfoot", true },
|
|
|
|
{ Tabular::SET_LTLASTFOOT, "set-ltlastfoot", true },
|
|
|
|
{ Tabular::UNSET_LTLASTFOOT, "unset-ltlastfoot", true },
|
|
|
|
{ Tabular::SET_LTNEWPAGE, "set-ltnewpage", false },
|
2012-05-31 11:56:07 +00:00
|
|
|
{ Tabular::UNSET_LTNEWPAGE, "unset-ltnewpage", false },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::TOGGLE_LTCAPTION, "toggle-ltcaption", false },
|
2010-10-29 04:09:49 +00:00
|
|
|
{ Tabular::SET_LTCAPTION, "set-ltcaption", false },
|
|
|
|
{ Tabular::UNSET_LTCAPTION, "unset-ltcaption", false },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::SET_SPECIAL_COLUMN, "set-special-column", true },
|
|
|
|
{ Tabular::SET_SPECIAL_MULTICOLUMN, "set-special-multicolumn", true },
|
|
|
|
{ Tabular::SET_BOOKTABS, "set-booktabs", false },
|
|
|
|
{ Tabular::UNSET_BOOKTABS, "unset-booktabs", false },
|
|
|
|
{ Tabular::SET_TOP_SPACE, "set-top-space", true },
|
|
|
|
{ Tabular::SET_BOTTOM_SPACE, "set-bottom-space", true },
|
|
|
|
{ Tabular::SET_INTERLINE_SPACE, "set-interline-space", true },
|
|
|
|
{ Tabular::SET_BORDER_LINES, "set-border-lines", false },
|
2010-02-23 08:00:29 +00:00
|
|
|
{ Tabular::TABULAR_VALIGN_TOP, "tabular-valign-top", false},
|
|
|
|
{ Tabular::TABULAR_VALIGN_MIDDLE, "tabular-valign-middle", false},
|
|
|
|
{ Tabular::TABULAR_VALIGN_BOTTOM, "tabular-valign-bottom", false},
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::LONGTABULAR_ALIGN_LEFT, "longtabular-align-left", false },
|
|
|
|
{ Tabular::LONGTABULAR_ALIGN_CENTER, "longtabular-align-center", false },
|
|
|
|
{ Tabular::LONGTABULAR_ALIGN_RIGHT, "longtabular-align-right", false },
|
2010-06-05 07:44:44 +00:00
|
|
|
{ Tabular::SET_DECIMAL_POINT, "set-decimal-point", true },
|
2011-02-03 23:11:26 +00:00
|
|
|
{ Tabular::SET_TABULAR_WIDTH, "set-tabular-width", true },
|
2010-02-18 08:28:46 +00:00
|
|
|
{ Tabular::LAST_ACTION, "", false }
|
2007-04-26 12:54:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
string const tostr(LyXAlignment const & num)
|
|
|
|
{
|
|
|
|
switch (num) {
|
|
|
|
case LYX_ALIGN_NONE:
|
|
|
|
return "none";
|
|
|
|
case LYX_ALIGN_BLOCK:
|
|
|
|
return "block";
|
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
return "left";
|
|
|
|
case LYX_ALIGN_CENTER:
|
|
|
|
return "center";
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
return "right";
|
|
|
|
case LYX_ALIGN_LAYOUT:
|
|
|
|
return "layout";
|
|
|
|
case LYX_ALIGN_SPECIAL:
|
|
|
|
return "special";
|
2010-06-05 07:44:44 +00:00
|
|
|
case LYX_ALIGN_DECIMAL:
|
|
|
|
return "decimal";
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-11 13:09:45 +00:00
|
|
|
string const tostr(Tabular::HAlignment const & num)
|
|
|
|
{
|
|
|
|
switch (num) {
|
|
|
|
case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
|
|
|
|
return "left";
|
|
|
|
case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
|
|
|
|
return "center";
|
|
|
|
case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
|
|
|
|
return "right";
|
|
|
|
}
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
string const tostr(Tabular::VAlignment const & num)
|
|
|
|
{
|
|
|
|
switch (num) {
|
|
|
|
case Tabular::LYX_VALIGN_TOP:
|
|
|
|
return "top";
|
|
|
|
case Tabular::LYX_VALIGN_MIDDLE:
|
|
|
|
return "middle";
|
|
|
|
case Tabular::LYX_VALIGN_BOTTOM:
|
|
|
|
return "bottom";
|
|
|
|
}
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string const tostr(Tabular::BoxType const & num)
|
|
|
|
{
|
|
|
|
switch (num) {
|
|
|
|
case Tabular::BOX_NONE:
|
|
|
|
return "none";
|
|
|
|
case Tabular::BOX_PARBOX:
|
|
|
|
return "parbox";
|
|
|
|
case Tabular::BOX_MINIPAGE:
|
|
|
|
return "minipage";
|
|
|
|
}
|
|
|
|
return string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// I would have liked a fromstr template a lot better. (Lgb)
|
2014-07-05 17:13:10 +00:00
|
|
|
bool string2type(string const & str, LyXAlignment & num)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (str == "none")
|
|
|
|
num = LYX_ALIGN_NONE;
|
|
|
|
else if (str == "block")
|
|
|
|
num = LYX_ALIGN_BLOCK;
|
|
|
|
else if (str == "left")
|
|
|
|
num = LYX_ALIGN_LEFT;
|
|
|
|
else if (str == "center")
|
|
|
|
num = LYX_ALIGN_CENTER;
|
|
|
|
else if (str == "right")
|
|
|
|
num = LYX_ALIGN_RIGHT;
|
2010-06-05 07:44:44 +00:00
|
|
|
else if (str == "decimal")
|
|
|
|
num = LYX_ALIGN_DECIMAL;
|
2007-04-26 12:54:21 +00:00
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-05 17:13:10 +00:00
|
|
|
bool string2type(string const & str, Tabular::HAlignment & num)
|
2009-07-11 13:09:45 +00:00
|
|
|
{
|
|
|
|
if (str == "left")
|
|
|
|
num = Tabular::LYX_LONGTABULAR_ALIGN_LEFT;
|
|
|
|
else if (str == "center" )
|
|
|
|
num = Tabular::LYX_LONGTABULAR_ALIGN_CENTER;
|
|
|
|
else if (str == "right")
|
|
|
|
num = Tabular::LYX_LONGTABULAR_ALIGN_RIGHT;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-05 17:13:10 +00:00
|
|
|
bool string2type(string const & str, Tabular::VAlignment & num)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (str == "top")
|
|
|
|
num = Tabular::LYX_VALIGN_TOP;
|
|
|
|
else if (str == "middle" )
|
|
|
|
num = Tabular::LYX_VALIGN_MIDDLE;
|
|
|
|
else if (str == "bottom")
|
|
|
|
num = Tabular::LYX_VALIGN_BOTTOM;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-05 17:13:10 +00:00
|
|
|
bool string2type(string const & str, Tabular::BoxType & num)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (str == "none")
|
|
|
|
num = Tabular::BOX_NONE;
|
|
|
|
else if (str == "parbox")
|
|
|
|
num = Tabular::BOX_PARBOX;
|
|
|
|
else if (str == "minipage")
|
|
|
|
num = Tabular::BOX_MINIPAGE;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-05 17:13:10 +00:00
|
|
|
bool string2type(string const & str, bool & num)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (str == "true")
|
|
|
|
num = true;
|
|
|
|
else if (str == "false")
|
|
|
|
num = false;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool getTokenValue(string const & str, char const * token, string & ret)
|
|
|
|
{
|
|
|
|
ret.erase();
|
|
|
|
size_t token_length = strlen(token);
|
2008-02-27 23:03:26 +00:00
|
|
|
size_t pos = str.find(token);
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
if (pos == string::npos || pos + token_length + 1 >= str.length()
|
|
|
|
|| str[pos + token_length] != '=')
|
|
|
|
return false;
|
|
|
|
pos += token_length + 1;
|
|
|
|
char ch = str[pos];
|
|
|
|
if (ch != '"' && ch != '\'') { // only read till next space
|
|
|
|
ret += ch;
|
|
|
|
ch = ' ';
|
|
|
|
}
|
|
|
|
while (pos < str.length() - 1 && str[++pos] != ch)
|
|
|
|
ret += str[pos];
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool getTokenValue(string const & str, char const * token, docstring & ret)
|
|
|
|
{
|
|
|
|
string tmp;
|
|
|
|
bool const success = getTokenValue(str, token, tmp);
|
|
|
|
ret = from_utf8(tmp);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool getTokenValue(string const & str, char const * token, int & num)
|
|
|
|
{
|
|
|
|
string tmp;
|
|
|
|
num = 0;
|
|
|
|
if (!getTokenValue(str, token, tmp))
|
|
|
|
return false;
|
|
|
|
num = convert<int>(tmp);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool getTokenValue(string const & str, char const * token, LyXAlignment & num)
|
|
|
|
{
|
|
|
|
string tmp;
|
|
|
|
return getTokenValue(str, token, tmp) && string2type(tmp, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-11 13:09:45 +00:00
|
|
|
bool getTokenValue(string const & str, char const * token,
|
|
|
|
Tabular::HAlignment & num)
|
|
|
|
{
|
|
|
|
string tmp;
|
|
|
|
return getTokenValue(str, token, tmp) && string2type(tmp, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
bool getTokenValue(string const & str, char const * token,
|
|
|
|
Tabular::VAlignment & num)
|
|
|
|
{
|
|
|
|
string tmp;
|
|
|
|
return getTokenValue(str, token, tmp) && string2type(tmp, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool getTokenValue(string const & str, char const * token,
|
|
|
|
Tabular::BoxType & num)
|
|
|
|
{
|
|
|
|
string tmp;
|
|
|
|
return getTokenValue(str, token, tmp) && string2type(tmp, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool getTokenValue(string const & str, char const * token, bool & flag)
|
|
|
|
{
|
|
|
|
// set the flag always to false as this should be the default for bools
|
|
|
|
// not in the file-format.
|
|
|
|
flag = false;
|
|
|
|
string tmp;
|
|
|
|
return getTokenValue(str, token, tmp) && string2type(tmp, flag);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-28 12:58:49 +00:00
|
|
|
bool getTokenValue(string const & str, char const * token, Length & len)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2007-09-27 20:19:06 +00:00
|
|
|
// set the length to be zero() as default as this it should be if not
|
2007-04-26 12:54:21 +00:00
|
|
|
// in the file format.
|
2007-04-28 12:58:49 +00:00
|
|
|
len = Length();
|
2007-04-26 12:54:21 +00:00
|
|
|
string tmp;
|
|
|
|
return getTokenValue(str, token, tmp) && isValidLength(tmp, &len);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-28 12:58:49 +00:00
|
|
|
bool getTokenValue(string const & str, char const * token, Length & len, bool & flag)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2007-04-28 12:58:49 +00:00
|
|
|
len = Length();
|
2007-04-26 12:54:21 +00:00
|
|
|
flag = false;
|
|
|
|
string tmp;
|
|
|
|
if (!getTokenValue(str, token, tmp))
|
|
|
|
return false;
|
|
|
|
if (tmp == "default") {
|
|
|
|
flag = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return isValidLength(tmp, &len);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void l_getline(istream & is, string & str)
|
|
|
|
{
|
|
|
|
str.erase();
|
|
|
|
while (str.empty()) {
|
|
|
|
getline(is, str);
|
|
|
|
if (!str.empty() && str[str.length() - 1] == '\r')
|
|
|
|
str.erase(str.length() - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-07 03:09:55 +00:00
|
|
|
template <class T>
|
|
|
|
string const write_attribute(string const & name, T const & t)
|
|
|
|
{
|
|
|
|
string const s = tostr(t);
|
|
|
|
return s.empty() ? s : " " + name + "=\"" + s + "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
string const write_attribute(string const & name, string const & t)
|
|
|
|
{
|
|
|
|
return t.empty() ? t : " " + name + "=\"" + t + "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
string const write_attribute(string const & name, docstring const & t)
|
|
|
|
{
|
|
|
|
return t.empty() ? string() : " " + name + "=\"" + to_utf8(t) + "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
string const write_attribute(string const & name, bool const & b)
|
|
|
|
{
|
|
|
|
// we write only true attribute values so we remove a bit of the
|
|
|
|
// file format bloat for tabulars.
|
|
|
|
return b ? write_attribute(name, convert<string>(b)) : string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
string const write_attribute(string const & name, int const & i)
|
|
|
|
{
|
|
|
|
// we write only true attribute values so we remove a bit of the
|
|
|
|
// file format bloat for tabulars.
|
|
|
|
return i ? write_attribute(name, convert<string>(i)) : string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
string const write_attribute(string const & name, Tabular::idx_type const & i)
|
|
|
|
{
|
|
|
|
// we write only true attribute values so we remove a bit of the
|
|
|
|
// file format bloat for tabulars.
|
|
|
|
return i ? write_attribute(name, convert<string>(i)) : string();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <>
|
|
|
|
string const write_attribute(string const & name, Length const & value)
|
|
|
|
{
|
|
|
|
// we write only the value if we really have one same reson as above.
|
|
|
|
return value.zero() ? string() : write_attribute(name, value.asString());
|
|
|
|
}
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
2010-02-19 08:11:09 +00:00
|
|
|
string const featureAsString(Tabular::Feature action)
|
2007-04-26 14:56:30 +00:00
|
|
|
{
|
2010-02-19 08:11:09 +00:00
|
|
|
for (size_t i = 0; i != Tabular::LAST_ACTION; ++i) {
|
|
|
|
if (tabularFeature[i].action == action)
|
|
|
|
return tabularFeature[i].feature;
|
|
|
|
}
|
|
|
|
return string();
|
2007-04-26 14:56:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-05-09 12:33:32 +00:00
|
|
|
DocIterator separatorPos(InsetTableCell * cell, docstring const & align_d)
|
2010-06-05 07:44:44 +00:00
|
|
|
{
|
2011-05-09 12:33:32 +00:00
|
|
|
DocIterator dit = doc_iterator_begin(&(cell->buffer()), cell);
|
2010-06-05 07:44:44 +00:00
|
|
|
for (; dit; dit.forwardChar())
|
2011-04-25 01:46:37 +00:00
|
|
|
if (dit.inTexted() && dit.depth() == 1
|
2010-06-05 07:44:44 +00:00
|
|
|
&& dit.paragraph().find(align_d, false, false, dit.pos()))
|
|
|
|
break;
|
|
|
|
|
2011-05-09 12:33:32 +00:00
|
|
|
return dit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-05 17:13:10 +00:00
|
|
|
InsetTableCell splitCell(InsetTableCell & head, docstring const & align_d, bool & hassep)
|
2011-05-09 12:33:32 +00:00
|
|
|
{
|
|
|
|
InsetTableCell tail = InsetTableCell(head);
|
|
|
|
DocIterator const dit = separatorPos(&head, align_d);
|
2010-06-05 07:44:44 +00:00
|
|
|
hassep = dit;
|
2010-08-14 14:32:52 +00:00
|
|
|
if (hassep) {
|
2011-05-09 12:33:32 +00:00
|
|
|
pit_type const psize = head.paragraphs().front().size();
|
2010-06-05 07:44:44 +00:00
|
|
|
head.paragraphs().front().eraseChars(dit.pos(), psize, false);
|
2014-07-26 14:29:23 +00:00
|
|
|
tail.paragraphs().front().eraseChars(0,
|
2010-08-14 14:32:52 +00:00
|
|
|
dit.pos() < psize ? dit.pos() + 1 : psize, false);
|
|
|
|
}
|
2010-06-05 07:44:44 +00:00
|
|
|
|
|
|
|
return tail;
|
|
|
|
}
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Tabular
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
2009-11-08 15:53:21 +00:00
|
|
|
Tabular::CellData::CellData(Buffer * buf)
|
2007-04-26 12:54:21 +00:00
|
|
|
: cellno(0),
|
2007-09-04 10:52:08 +00:00
|
|
|
width(0),
|
2007-04-26 12:54:21 +00:00
|
|
|
multicolumn(Tabular::CELL_NORMAL),
|
2010-02-11 01:07:54 +00:00
|
|
|
multirow(Tabular::CELL_NORMAL),
|
2007-04-26 12:54:21 +00:00
|
|
|
alignment(LYX_ALIGN_CENTER),
|
|
|
|
valignment(LYX_VALIGN_TOP),
|
2010-06-05 07:44:44 +00:00
|
|
|
decimal_hoffset(0),
|
|
|
|
decimal_width(0),
|
2010-03-19 09:41:31 +00:00
|
|
|
voffset(0),
|
2008-03-18 18:08:32 +00:00
|
|
|
top_line(false),
|
2007-04-26 12:54:21 +00:00
|
|
|
bottom_line(false),
|
2008-03-18 18:08:32 +00:00
|
|
|
left_line(false),
|
2007-04-26 12:54:21 +00:00
|
|
|
right_line(false),
|
|
|
|
usebox(BOX_NONE),
|
2012-03-16 01:29:37 +00:00
|
|
|
rotate(0),
|
2008-07-16 14:23:32 +00:00
|
|
|
inset(new InsetTableCell(buf))
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
{
|
2009-11-08 15:53:21 +00:00
|
|
|
inset->setBuffer(*buf);
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
|
2008-02-27 20:59:44 +00:00
|
|
|
Tabular::CellData::CellData(CellData const & cs)
|
2007-04-26 12:54:21 +00:00
|
|
|
: cellno(cs.cellno),
|
2007-09-04 10:52:08 +00:00
|
|
|
width(cs.width),
|
2007-04-26 12:54:21 +00:00
|
|
|
multicolumn(cs.multicolumn),
|
2010-02-11 01:07:54 +00:00
|
|
|
multirow(cs.multirow),
|
2010-11-07 05:32:28 +00:00
|
|
|
mroffset(cs.mroffset),
|
2007-04-26 12:54:21 +00:00
|
|
|
alignment(cs.alignment),
|
|
|
|
valignment(cs.valignment),
|
2010-06-05 07:44:44 +00:00
|
|
|
decimal_hoffset(cs.decimal_hoffset),
|
|
|
|
decimal_width(cs.decimal_width),
|
2010-03-20 10:20:28 +00:00
|
|
|
voffset(cs.voffset),
|
2007-04-26 12:54:21 +00:00
|
|
|
top_line(cs.top_line),
|
|
|
|
bottom_line(cs.bottom_line),
|
|
|
|
left_line(cs.left_line),
|
|
|
|
right_line(cs.right_line),
|
|
|
|
usebox(cs.usebox),
|
|
|
|
rotate(cs.rotate),
|
|
|
|
align_special(cs.align_special),
|
|
|
|
p_width(cs.p_width),
|
Remove unneccessary uses of dynamic_cast from the code.
A dynamic_cast is necessary when:
- the object to be casted is from an external library because we can't add Qxxx::asXxxx() to Qt e.g.:
* QAbstractListModel to GuiIdListModel,
* QValidator to PathValidator,
* QWidget to TabWorkArea,
* QWidget to GuiWorkArea;
- the object is to be casted from an interface to the implementing class, because the Interface does not know by whom it is implemented:
* ProgressInterface to GuiProgress,
* Application to GuiApplication.
A dynamic_cast can be replaced by:
- already existing as***Inset() functions, e.g.:
* asHullInset(),
* asInsetMath()->asMacro(),
* asInsetText();
- a static_cast when we are sure this can't go wrong, e.g.:
* we are sure that CellData::inset->clone() is an InsetTableCell,
* in cases where we explicitly check it->lyxCode().
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@35855 a592a061-630c-0410-9148-cb99ea01b6c8
2010-10-26 15:03:51 +00:00
|
|
|
inset(static_cast<InsetTableCell *>(cs.inset->clone()))
|
2008-07-23 12:13:41 +00:00
|
|
|
{
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2014-07-05 09:44:13 +00:00
|
|
|
Tabular::CellData & Tabular::CellData::operator=(CellData const & cs)
|
|
|
|
{
|
|
|
|
if (&cs == this)
|
|
|
|
return *this;
|
|
|
|
cellno = cs.cellno;
|
|
|
|
width = cs.width;
|
|
|
|
multicolumn = cs.multicolumn;
|
|
|
|
multirow = cs.multirow;
|
|
|
|
mroffset = cs.mroffset;
|
|
|
|
alignment = cs.alignment;
|
|
|
|
valignment = cs.valignment;
|
|
|
|
decimal_hoffset = cs.decimal_hoffset;
|
|
|
|
decimal_width = cs.decimal_width;
|
|
|
|
voffset = cs.voffset;
|
|
|
|
top_line = cs.top_line;
|
|
|
|
bottom_line = cs.bottom_line;
|
|
|
|
left_line = cs.left_line;
|
|
|
|
right_line = cs.right_line;
|
|
|
|
usebox = cs.usebox;
|
|
|
|
rotate = cs.rotate;
|
|
|
|
align_special = cs.align_special;
|
|
|
|
p_width = cs.p_width;
|
|
|
|
inset.reset(static_cast<InsetTableCell *>(cs.inset->clone()));
|
2007-04-26 12:54:21 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2008-02-27 20:59:44 +00:00
|
|
|
Tabular::RowData::RowData()
|
2007-09-04 10:52:08 +00:00
|
|
|
: ascent(0),
|
|
|
|
descent(0),
|
2007-04-26 12:54:21 +00:00
|
|
|
top_space_default(false),
|
|
|
|
bottom_space_default(false),
|
|
|
|
interline_space_default(false),
|
|
|
|
endhead(false),
|
|
|
|
endfirsthead(false),
|
|
|
|
endfoot(false),
|
|
|
|
endlastfoot(false),
|
2008-05-04 07:51:50 +00:00
|
|
|
newpage(false),
|
2010-03-18 19:02:01 +00:00
|
|
|
caption(false)
|
2007-04-26 12:54:21 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
2008-02-27 20:59:44 +00:00
|
|
|
Tabular::ColumnData::ColumnData()
|
2007-04-26 12:54:21 +00:00
|
|
|
: alignment(LYX_ALIGN_CENTER),
|
|
|
|
valignment(LYX_VALIGN_TOP),
|
2007-09-04 10:52:08 +00:00
|
|
|
width(0)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Tabular::ltType::ltType()
|
|
|
|
: topDL(false),
|
|
|
|
bottomDL(false),
|
|
|
|
empty(false)
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
2009-11-08 15:53:21 +00:00
|
|
|
Tabular::Tabular(Buffer * buffer, row_type rows_arg, col_type columns_arg)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-02-27 20:43:16 +00:00
|
|
|
init(buffer, rows_arg, columns_arg);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-23 12:13:41 +00:00
|
|
|
void Tabular::setBuffer(Buffer & buffer)
|
|
|
|
{
|
|
|
|
buffer_ = &buffer;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type i = 0; i < nrows(); ++i)
|
|
|
|
for (col_type j = 0; j < ncols(); ++j)
|
2008-07-23 12:13:41 +00:00
|
|
|
cell_info[i][j].inset->setBuffer(*buffer_);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
// activates all lines and sets all widths to 0
|
2009-11-08 15:53:21 +00:00
|
|
|
void Tabular::init(Buffer * buf, row_type rows_arg,
|
2007-04-26 12:54:21 +00:00
|
|
|
col_type columns_arg)
|
|
|
|
{
|
2009-11-08 15:53:21 +00:00
|
|
|
buffer_ = buf;
|
2007-09-04 10:52:08 +00:00
|
|
|
row_info = row_vector(rows_arg);
|
|
|
|
column_info = column_vector(columns_arg);
|
2008-07-16 14:23:32 +00:00
|
|
|
cell_info = cell_vvector(rows_arg, cell_vector(columns_arg, CellData(buf)));
|
2007-04-26 12:54:21 +00:00
|
|
|
row_info.reserve(10);
|
|
|
|
column_info.reserve(10);
|
|
|
|
cell_info.reserve(100);
|
2008-03-23 11:35:46 +00:00
|
|
|
updateIndexes();
|
2007-04-26 12:54:21 +00:00
|
|
|
is_long_tabular = false;
|
2009-01-03 18:33:09 +00:00
|
|
|
tabular_valignment = LYX_VALIGN_MIDDLE;
|
2011-02-03 23:11:26 +00:00
|
|
|
tabular_width = Length();
|
2009-07-11 13:09:45 +00:00
|
|
|
longtabular_alignment = LYX_LONGTABULAR_ALIGN_CENTER;
|
2012-03-19 00:21:26 +00:00
|
|
|
rotate = 0;
|
2007-04-26 12:54:21 +00:00
|
|
|
use_booktabs = false;
|
2008-03-18 18:08:32 +00:00
|
|
|
// set silly default lines
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r)
|
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
cell_info[r][c].inset->setBuffer(*buffer_);
|
|
|
|
cell_info[r][c].top_line = true;
|
|
|
|
cell_info[r][c].left_line = true;
|
|
|
|
cell_info[r][c].bottom_line = r == 0 || r == nrows() - 1;
|
|
|
|
cell_info[r][c].right_line = c == ncols() - 1;
|
2008-03-18 18:08:32 +00:00
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::deleteRow(row_type const row)
|
|
|
|
{
|
|
|
|
// Not allowed to delete last row
|
2010-03-05 18:10:34 +00:00
|
|
|
if (nrows() == 1)
|
2007-04-26 12:54:21 +00:00
|
|
|
return;
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2010-02-11 01:07:54 +00:00
|
|
|
// Care about multirow cells
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row + 1 < nrows() &&
|
|
|
|
cell_info[row][c].multirow == CELL_BEGIN_OF_MULTIROW &&
|
2010-03-16 21:42:16 +00:00
|
|
|
cell_info[row + 1][c].multirow == CELL_PART_OF_MULTIROW) {
|
|
|
|
cell_info[row + 1][c].multirow = CELL_BEGIN_OF_MULTIROW;
|
2010-02-11 01:07:54 +00:00
|
|
|
}
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
row_info.erase(row_info.begin() + row);
|
|
|
|
cell_info.erase(cell_info.begin() + row);
|
2008-03-23 11:35:46 +00:00
|
|
|
updateIndexes();
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void Tabular::copyRow(row_type const row)
|
2012-01-22 22:16:03 +00:00
|
|
|
{
|
|
|
|
insertRow(row, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::appendRow(row_type row)
|
|
|
|
{
|
|
|
|
insertRow(row, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::insertRow(row_type const row, bool copy)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2012-01-22 21:44:27 +00:00
|
|
|
row_info.insert(row_info.begin() + row + 1, RowData(row_info[row]));
|
2014-07-26 14:29:23 +00:00
|
|
|
cell_info.insert(cell_info.begin() + row + 1,
|
2012-01-22 21:44:27 +00:00
|
|
|
cell_vector(0, CellData(buffer_)));
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2012-01-22 21:44:27 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
cell_info[row + 1].insert(cell_info[row + 1].begin() + c,
|
2012-01-22 22:16:03 +00:00
|
|
|
copy ? CellData(cell_info[row][c]) : CellData(buffer_));
|
2014-03-29 22:52:36 +00:00
|
|
|
if (buffer().params().track_changes)
|
2010-03-05 18:10:34 +00:00
|
|
|
cell_info[row + 1][c].inset->setChange(Change(Change::INSERTED));
|
2012-01-22 21:44:27 +00:00
|
|
|
if (cell_info[row][c].multirow == CELL_BEGIN_OF_MULTIROW)
|
|
|
|
cell_info[row + 1][c].multirow = CELL_PART_OF_MULTIROW;
|
|
|
|
}
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2007-09-04 18:13:19 +00:00
|
|
|
updateIndexes();
|
2012-01-22 21:44:27 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
if (isPartOfMultiRow(row, c))
|
|
|
|
continue;
|
|
|
|
// inherit line settings
|
|
|
|
idx_type const i = cellIndex(row + 1, c);
|
|
|
|
idx_type const j = cellIndex(row, c);
|
|
|
|
setLeftLine(i, leftLine(j));
|
|
|
|
setRightLine(i, rightLine(j));
|
|
|
|
setTopLine(i, topLine(j));
|
|
|
|
if (topLine(j) && bottomLine(j)) {
|
|
|
|
setBottomLine(i, true);
|
|
|
|
setBottomLine(j, false);
|
|
|
|
}
|
|
|
|
// mark track changes
|
2014-03-29 22:52:36 +00:00
|
|
|
if (buffer().params().track_changes)
|
2012-01-22 21:44:27 +00:00
|
|
|
cellInfo(i).inset->setChange(Change(Change::INSERTED));
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-24 10:51:28 +00:00
|
|
|
void Tabular::moveColumn(col_type col, ColDirection direction)
|
|
|
|
{
|
|
|
|
if (direction == Tabular::LEFT)
|
|
|
|
col = col - 1;
|
|
|
|
|
2014-02-18 18:39:45 +00:00
|
|
|
std::swap(column_info[col], column_info[col + 1]);
|
|
|
|
|
2012-12-24 10:51:28 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
std::swap(cell_info[r][col], cell_info[r][col + 1]);
|
|
|
|
std::swap(cell_info[r][col].left_line, cell_info[r][col + 1].left_line);
|
|
|
|
std::swap(cell_info[r][col].right_line, cell_info[r][col + 1].right_line);
|
|
|
|
|
|
|
|
// FIXME track changes is broken for tabular features (#8469)
|
|
|
|
idx_type const i = cellIndex(r, col);
|
|
|
|
idx_type const j = cellIndex(r, col + 1);
|
2014-03-29 22:52:36 +00:00
|
|
|
if (buffer().params().track_changes) {
|
2012-12-24 10:51:28 +00:00
|
|
|
cellInfo(i).inset->setChange(Change(Change::INSERTED));
|
|
|
|
cellInfo(j).inset->setChange(Change(Change::INSERTED));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateIndexes();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::moveRow(row_type row, RowDirection direction)
|
|
|
|
{
|
|
|
|
if (direction == Tabular::UP)
|
|
|
|
row = row - 1;
|
|
|
|
|
2014-02-18 18:39:45 +00:00
|
|
|
std::swap(row_info[row], row_info[row + 1]);
|
|
|
|
|
2012-12-24 10:51:28 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
std::swap(cell_info[row][c], cell_info[row + 1][c]);
|
|
|
|
std::swap(cell_info[row][c].top_line, cell_info[row + 1][c].top_line);
|
|
|
|
std::swap(cell_info[row][c].bottom_line, cell_info[row + 1][c].bottom_line);
|
|
|
|
|
|
|
|
// FIXME track changes is broken for tabular features (#8469)
|
|
|
|
idx_type const i = cellIndex(row, c);
|
|
|
|
idx_type const j = cellIndex(row + 1, c);
|
2014-03-29 22:52:36 +00:00
|
|
|
if (buffer().params().track_changes) {
|
2012-12-24 10:51:28 +00:00
|
|
|
cellInfo(i).inset->setChange(Change(Change::INSERTED));
|
|
|
|
cellInfo(j).inset->setChange(Change(Change::INSERTED));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateIndexes();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
void Tabular::deleteColumn(col_type const col)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
// Not allowed to delete last column
|
2010-03-05 18:10:34 +00:00
|
|
|
if (ncols() == 1)
|
2007-04-26 12:54:21 +00:00
|
|
|
return;
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2007-08-12 13:25:36 +00:00
|
|
|
// Care about multicolumn cells
|
2010-03-05 18:10:34 +00:00
|
|
|
if (col + 1 < ncols() &&
|
2010-02-11 01:07:54 +00:00
|
|
|
cell_info[r][col].multicolumn == CELL_BEGIN_OF_MULTICOLUMN &&
|
|
|
|
cell_info[r][col + 1].multicolumn == CELL_PART_OF_MULTICOLUMN) {
|
|
|
|
cell_info[r][col + 1].multicolumn = CELL_BEGIN_OF_MULTICOLUMN;
|
2007-08-12 13:25:36 +00:00
|
|
|
}
|
2010-02-11 01:07:54 +00:00
|
|
|
cell_info[r].erase(cell_info[r].begin() + col);
|
2007-08-12 13:25:36 +00:00
|
|
|
}
|
2010-02-11 01:07:54 +00:00
|
|
|
column_info.erase(column_info.begin() + col);
|
2008-03-23 11:35:46 +00:00
|
|
|
updateIndexes();
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
void Tabular::copyColumn(col_type const col)
|
2012-01-22 22:16:03 +00:00
|
|
|
{
|
|
|
|
insertColumn(col, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::appendColumn(col_type col)
|
2014-07-26 14:29:23 +00:00
|
|
|
{
|
2012-01-22 22:16:03 +00:00
|
|
|
insertColumn(col, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::insertColumn(col_type const col, bool copy)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-02-27 20:43:16 +00:00
|
|
|
BufferParams const & bp = buffer().params();
|
2012-01-22 21:44:27 +00:00
|
|
|
column_info.insert(column_info.begin() + col + 1, ColumnData(column_info[col]));
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2012-01-22 22:16:03 +00:00
|
|
|
cell_info[r].insert(cell_info[r].begin() + col + 1,
|
|
|
|
copy ? CellData(cell_info[r][col]) : CellData(buffer_));
|
2014-03-29 22:52:36 +00:00
|
|
|
if (bp.track_changes)
|
2010-02-11 01:07:54 +00:00
|
|
|
cell_info[r][col + 1].inset->setChange(Change(Change::INSERTED));
|
2012-01-22 21:44:27 +00:00
|
|
|
if (cell_info[r][col].multicolumn == CELL_BEGIN_OF_MULTICOLUMN)
|
|
|
|
cell_info[r][col + 1].multicolumn = CELL_PART_OF_MULTICOLUMN;
|
2010-02-11 01:07:54 +00:00
|
|
|
}
|
2008-03-23 11:35:46 +00:00
|
|
|
updateIndexes();
|
2012-01-22 21:44:27 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
// inherit line settings
|
|
|
|
idx_type const i = cellIndex(r, col + 1);
|
|
|
|
idx_type const j = cellIndex(r, col);
|
|
|
|
setBottomLine(i, bottomLine(j));
|
|
|
|
setTopLine(i, topLine(j));
|
|
|
|
setLeftLine(i, leftLine(j));
|
2014-04-04 19:53:27 +00:00
|
|
|
if (rightLine(i) && rightLine(j)) {
|
2012-01-22 21:44:27 +00:00
|
|
|
setRightLine(i, true);
|
|
|
|
setRightLine(j, false);
|
|
|
|
}
|
2014-03-29 22:52:36 +00:00
|
|
|
if (buffer().params().track_changes)
|
2012-01-22 21:44:27 +00:00
|
|
|
cellInfo(i).inset->setChange(Change(Change::INSERTED));
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-04 18:13:19 +00:00
|
|
|
void Tabular::updateIndexes()
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2009-11-16 00:18:52 +00:00
|
|
|
setBuffer(buffer());
|
2007-04-26 12:54:21 +00:00
|
|
|
numberofcells = 0;
|
2010-11-01 17:09:38 +00:00
|
|
|
// reset cell number
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type row = 0; row < nrows(); ++row)
|
|
|
|
for (col_type column = 0; column < ncols(); ++column) {
|
2010-02-11 01:07:54 +00:00
|
|
|
if (!isPartOfMultiColumn(row, column)
|
|
|
|
&& !isPartOfMultiRow(row, column))
|
2007-04-26 12:54:21 +00:00
|
|
|
++numberofcells;
|
2010-02-11 01:07:54 +00:00
|
|
|
if (isPartOfMultiRow(row, column))
|
|
|
|
cell_info[row][column].cellno = cell_info[row - 1][column].cellno;
|
|
|
|
else
|
|
|
|
cell_info[row][column].cellno = numberofcells - 1;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
rowofcell.resize(numberofcells);
|
|
|
|
columnofcell.resize(numberofcells);
|
2008-03-23 11:35:46 +00:00
|
|
|
idx_type i = 0;
|
2010-11-01 17:09:38 +00:00
|
|
|
// reset column and row of cells and update their width and alignment
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type row = 0; row < nrows(); ++row)
|
|
|
|
for (col_type column = 0; column < ncols(); ++column) {
|
2010-10-30 18:11:37 +00:00
|
|
|
if (isPartOfMultiColumn(row, column))
|
2007-04-26 12:54:21 +00:00
|
|
|
continue;
|
2010-11-01 17:12:46 +00:00
|
|
|
// columnofcell needs to be called before setting width and aligment
|
2010-11-01 17:09:38 +00:00
|
|
|
// multirow cells inherit the width from the column width
|
2010-10-30 18:11:37 +00:00
|
|
|
if (!isPartOfMultiRow(row, column)) {
|
|
|
|
columnofcell[i] = column;
|
|
|
|
rowofcell[i] = row;
|
2010-11-01 16:16:40 +00:00
|
|
|
}
|
|
|
|
setFixedWidth(row, column);
|
|
|
|
if (isPartOfMultiRow(row, column))
|
2010-10-30 18:11:37 +00:00
|
|
|
continue;
|
2010-11-01 17:09:38 +00:00
|
|
|
cell_info[row][column].inset->setContentAlignment(
|
|
|
|
getAlignment(cellIndex(row, column)));
|
2008-03-23 11:35:46 +00:00
|
|
|
++i;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-12 18:36:20 +00:00
|
|
|
Tabular::idx_type Tabular::numberOfCellsInRow(row_type const row) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
idx_type result = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c)
|
|
|
|
if (cell_info[row][c].multicolumn != Tabular::CELL_PART_OF_MULTICOLUMN)
|
2007-04-26 12:54:21 +00:00
|
|
|
++result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
bool Tabular::topLine(idx_type const cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).top_line;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
bool Tabular::bottomLine(idx_type const cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).bottom_line;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
bool Tabular::leftLine(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (use_booktabs)
|
|
|
|
return false;
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).left_line;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
bool Tabular::rightLine(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (use_booktabs)
|
|
|
|
return false;
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).right_line;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
int Tabular::interRowSpace(row_type row) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-03-05 18:10:34 +00:00
|
|
|
if (!row || row >= nrows())
|
2007-04-26 12:54:21 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
int const interline_space = row_info[row - 1].interline_space_default ?
|
|
|
|
default_line_space :
|
2007-09-04 10:52:08 +00:00
|
|
|
row_info[row - 1].interline_space.inPixels(width());
|
2008-03-18 18:08:32 +00:00
|
|
|
if (rowTopLine(row) && rowBottomLine(row - 1))
|
2007-04-26 12:54:21 +00:00
|
|
|
return interline_space + WIDTH_OF_LINE;
|
|
|
|
return interline_space;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
int Tabular::interColumnSpace(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 20:48:48 +00:00
|
|
|
col_type const nextcol = cellColumn(cell) + columnSpan(cell);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (rightLine(cell) && nextcol < ncols()
|
2010-02-11 01:07:54 +00:00
|
|
|
&& leftLine(cellIndex(cellRow(cell), nextcol)))
|
2007-04-26 12:54:21 +00:00
|
|
|
return WIDTH_OF_LINE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-06-14 10:42:42 +00:00
|
|
|
int Tabular::cellWidth(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-24 14:03:00 +00:00
|
|
|
int w = 0;
|
|
|
|
col_type const span = columnSpan(cell);
|
|
|
|
col_type const col = cellColumn(cell);
|
|
|
|
for(col_type c = col; c < col + span ; ++c)
|
|
|
|
w += column_info[c].width;
|
|
|
|
return w;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-16 21:42:16 +00:00
|
|
|
int Tabular::cellHeight(idx_type cell) const
|
2010-02-11 01:07:54 +00:00
|
|
|
{
|
2010-03-08 04:08:11 +00:00
|
|
|
row_type const span = rowSpan(cell);
|
|
|
|
row_type const row = cellRow(cell);
|
2010-03-13 10:49:26 +00:00
|
|
|
int h = 0;
|
2010-03-08 04:08:11 +00:00
|
|
|
for(row_type r = row; r < row + span ; ++r) {
|
2010-03-13 10:49:26 +00:00
|
|
|
h += rowAscent(r) + rowDescent(r);
|
|
|
|
if (r != row + span - 1)
|
|
|
|
h += interRowSpace(r + 1);
|
2010-03-08 04:08:11 +00:00
|
|
|
}
|
2010-03-13 10:49:26 +00:00
|
|
|
|
2010-03-08 04:08:11 +00:00
|
|
|
return h;
|
2010-02-11 01:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-24 14:03:00 +00:00
|
|
|
bool Tabular::updateColumnWidths()
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-06-05 07:44:44 +00:00
|
|
|
vector<int> max_dwidth(ncols(), 0);
|
|
|
|
for(col_type c = 0; c < ncols(); ++c)
|
|
|
|
for(row_type r = 0; r < nrows(); ++r) {
|
|
|
|
idx_type const i = cellIndex(r, c);
|
|
|
|
if (getAlignment(i) == LYX_ALIGN_DECIMAL)
|
|
|
|
max_dwidth[c] = max(max_dwidth[c], cell_info[r][c].decimal_width);
|
|
|
|
}
|
|
|
|
|
2008-03-24 14:03:00 +00:00
|
|
|
bool update = false;
|
|
|
|
// for each col get max of single col cells
|
2010-03-05 18:10:34 +00:00
|
|
|
for(col_type c = 0; c < ncols(); ++c) {
|
2008-03-24 14:03:00 +00:00
|
|
|
int new_width = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for(row_type r = 0; r < nrows(); ++r) {
|
2008-03-24 14:03:00 +00:00
|
|
|
idx_type const i = cellIndex(r, c);
|
2010-06-08 13:38:12 +00:00
|
|
|
if (columnSpan(i) == 1) {
|
2010-06-12 16:44:50 +00:00
|
|
|
if (getAlignment(i) == LYX_ALIGN_DECIMAL
|
|
|
|
&& cell_info[r][c].decimal_width!=0)
|
2014-07-26 14:29:23 +00:00
|
|
|
new_width = max(new_width, cellInfo(i).width
|
2010-06-05 07:44:44 +00:00
|
|
|
+ max_dwidth[c] - cellInfo(i).decimal_width);
|
|
|
|
else
|
|
|
|
new_width = max(new_width, cellInfo(i).width);
|
2010-06-08 13:38:12 +00:00
|
|
|
}
|
2008-03-24 14:03:00 +00:00
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-03-24 14:03:00 +00:00
|
|
|
if (column_info[c].width != new_width) {
|
|
|
|
column_info[c].width = new_width;
|
|
|
|
update = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// update col widths to fit merged cells
|
2010-03-05 18:10:34 +00:00
|
|
|
for(col_type c = 0; c < ncols(); ++c)
|
|
|
|
for(row_type r = 0; r < nrows(); ++r) {
|
2008-03-24 14:03:00 +00:00
|
|
|
idx_type const i = cellIndex(r, c);
|
|
|
|
int const span = columnSpan(i);
|
|
|
|
if (span == 1 || c > cellColumn(i))
|
|
|
|
continue;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-03-24 14:03:00 +00:00
|
|
|
int old_width = 0;
|
|
|
|
for(col_type j = c; j < c + span ; ++j)
|
|
|
|
old_width += column_info[j].width;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
if (cellInfo(i).width > old_width) {
|
|
|
|
column_info[c + span - 1].width += cellInfo(i).width - old_width;
|
2008-03-24 14:03:00 +00:00
|
|
|
update = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return update;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-24 14:03:00 +00:00
|
|
|
int Tabular::width() const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-24 14:03:00 +00:00
|
|
|
int width = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c)
|
|
|
|
width += column_info[c].width;
|
2008-03-24 14:03:00 +00:00
|
|
|
return width;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::setAlignment(idx_type cell, LyXAlignment align,
|
2010-11-20 07:57:35 +00:00
|
|
|
bool has_width)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-06-05 07:44:44 +00:00
|
|
|
col_type const col = cellColumn(cell);
|
2010-11-21 04:45:07 +00:00
|
|
|
// set alignment for the whole row if we are not in a multicolumn cell,
|
2010-11-20 04:53:34 +00:00
|
|
|
// exclude possible multicolumn cells in the row
|
|
|
|
if (!isMultiColumn(cell)) {
|
2010-11-19 03:31:13 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2010-11-20 07:57:35 +00:00
|
|
|
// only if the column has no width the multirow inherits the
|
|
|
|
// alignment of the column, otherwise it is left aligned
|
|
|
|
if (!(isMultiRow(cellIndex(r, col)) && has_width)
|
2010-11-20 04:53:34 +00:00
|
|
|
&& !isMultiColumn(cellIndex(r, col))) {
|
2010-11-19 03:31:13 +00:00
|
|
|
cell_info[r][col].alignment = align;
|
|
|
|
cell_info[r][col].inset->setContentAlignment(align);
|
|
|
|
}
|
2010-11-20 07:57:35 +00:00
|
|
|
if ((isMultiRow(cellIndex(r, col)) && has_width)
|
|
|
|
&& !isMultiColumn(cellIndex(r, col))) {
|
|
|
|
cell_info[r][col].alignment = LYX_ALIGN_LEFT;
|
|
|
|
cell_info[r][col].inset->setContentAlignment(LYX_ALIGN_LEFT);
|
|
|
|
}
|
2010-11-19 03:31:13 +00:00
|
|
|
}
|
2010-11-20 04:19:13 +00:00
|
|
|
column_info[col].alignment = align;
|
|
|
|
docstring & dpoint = column_info[col].decimal_point;
|
|
|
|
if (align == LYX_ALIGN_DECIMAL && dpoint.empty())
|
|
|
|
dpoint = from_utf8(lyxrc.default_decimal_point);
|
2010-11-20 04:53:34 +00:00
|
|
|
} else {
|
2014-07-26 14:29:23 +00:00
|
|
|
cellInfo(cell).alignment = align;
|
|
|
|
cellInset(cell).get()->setContentAlignment(align);
|
2010-06-05 07:44:44 +00:00
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::setVAlignment(idx_type cell, VAlignment align,
|
|
|
|
bool onlycolumn)
|
|
|
|
{
|
|
|
|
if (!isMultiColumn(cell) || onlycolumn)
|
2007-09-04 10:52:08 +00:00
|
|
|
column_info[cellColumn(cell)].valignment = align;
|
2007-04-26 12:54:21 +00:00
|
|
|
if (!onlycolumn)
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(cell).valignment = align;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Allow line and paragraph breaks for fixed width cells or disallow them,
|
|
|
|
* merge cell paragraphs and reset layout to standard for variable width
|
|
|
|
* cells.
|
|
|
|
*/
|
2008-03-21 06:16:05 +00:00
|
|
|
void toggleFixedWidth(Cursor & cur, InsetTableCell * inset, bool fixedWidth)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-07-16 14:23:32 +00:00
|
|
|
inset->toggleFixedWidth(fixedWidth);
|
2007-04-26 12:54:21 +00:00
|
|
|
if (fixedWidth)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// merge all paragraphs to one
|
2007-08-21 13:03:55 +00:00
|
|
|
BufferParams const & bp = cur.bv().buffer().params();
|
2007-04-26 12:54:21 +00:00
|
|
|
while (inset->paragraphs().size() > 1)
|
|
|
|
mergeParagraph(bp, inset->paragraphs(), 0);
|
|
|
|
|
|
|
|
// reset layout
|
|
|
|
cur.push(*inset);
|
|
|
|
// undo information has already been recorded
|
2009-08-09 15:29:34 +00:00
|
|
|
inset->getText(0)->setLayout(0, cur.lastpit() + 1,
|
2008-08-01 20:57:27 +00:00
|
|
|
bp.documentClass().plainLayoutName());
|
2007-04-26 12:54:21 +00:00
|
|
|
cur.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void Tabular::setColumnPWidth(Cursor & cur, idx_type cell,
|
2007-04-28 12:58:49 +00:00
|
|
|
Length const & width)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-03-05 18:10:34 +00:00
|
|
|
col_type const c = cellColumn(cell);
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
column_info[c].p_width = width;
|
2014-02-14 02:17:20 +00:00
|
|
|
// reset the vertical alignment to top if the fixed width
|
2010-03-04 03:55:13 +00:00
|
|
|
// is removed or zero because only fixed width columns can
|
|
|
|
// have a vertical alignment
|
2010-03-05 18:10:34 +00:00
|
|
|
if (column_info[c].p_width.zero())
|
|
|
|
column_info[c].valignment = LYX_VALIGN_TOP;
|
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
idx_type const cell = cellIndex(r, c);
|
2007-04-26 12:54:21 +00:00
|
|
|
// because of multicolumns
|
2008-03-25 13:32:38 +00:00
|
|
|
toggleFixedWidth(cur, cellInset(cell).get(),
|
2007-04-26 12:54:21 +00:00
|
|
|
!getPWidth(cell).zero());
|
2014-02-14 02:17:20 +00:00
|
|
|
if (isMultiRow(cell))
|
|
|
|
setAlignment(cell, LYX_ALIGN_LEFT, false);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
// cur paragraph can become invalid after paragraphs were merged
|
|
|
|
if (cur.pit() > cur.lastpit())
|
|
|
|
cur.pit() = cur.lastpit();
|
|
|
|
// cur position can become invalid after newlines were removed
|
|
|
|
if (cur.pos() > cur.lastpos())
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-21 02:07:54 +00:00
|
|
|
bool Tabular::setFixedWidth(row_type r, col_type c)
|
|
|
|
{
|
2008-09-12 17:25:11 +00:00
|
|
|
bool const multicol = cell_info[r][c].multicolumn != CELL_NORMAL;
|
2009-02-09 09:02:50 +00:00
|
|
|
bool const fixed_width = (!column_info[c].p_width.zero() && !multicol)
|
|
|
|
|| (multicol && !cell_info[r][c].p_width.zero());
|
|
|
|
cell_info[r][c].inset->toggleFixedWidth(fixed_width);
|
|
|
|
return fixed_width;
|
2008-07-21 02:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool Tabular::setMColumnPWidth(Cursor & cur, idx_type cell,
|
2007-04-28 12:58:49 +00:00
|
|
|
Length const & width)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (!isMultiColumn(cell))
|
|
|
|
return false;
|
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(cell).p_width = width;
|
|
|
|
toggleFixedWidth(cur, cellInset(cell).get(), !width.zero());
|
2007-04-26 12:54:21 +00:00
|
|
|
// cur paragraph can become invalid after paragraphs were merged
|
|
|
|
if (cur.pit() > cur.lastpit())
|
|
|
|
cur.pit() = cur.lastpit();
|
|
|
|
// cur position can become invalid after newlines were removed
|
|
|
|
if (cur.pos() > cur.lastpos())
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-07 18:45:26 +00:00
|
|
|
bool Tabular::setMROffset(Cursor &, idx_type cell, Length const & mroffset)
|
2010-11-07 05:32:28 +00:00
|
|
|
{
|
|
|
|
cellInfo(cell).mroffset = mroffset;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
void Tabular::setAlignSpecial(idx_type cell, docstring const & special,
|
|
|
|
Tabular::Feature what)
|
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
if (what == SET_SPECIAL_MULTICOLUMN)
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(cell).align_special = special;
|
2007-04-26 12:54:21 +00:00
|
|
|
else
|
2007-09-04 10:52:08 +00:00
|
|
|
column_info[cellColumn(cell)].align_special = special;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
void Tabular::setTopLine(idx_type i, bool line)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(i).top_line = line;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
void Tabular::setBottomLine(idx_type i, bool line)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(i).bottom_line = line;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
void Tabular::setLeftLine(idx_type cell, bool line)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(cell).left_line = line;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
void Tabular::setRightLine(idx_type cell, bool line)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(cell).right_line = line;
|
2008-03-18 18:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Tabular::rowTopLine(row_type r) const
|
|
|
|
{
|
|
|
|
bool all_rows_set = true;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; all_rows_set && c < ncols(); ++c)
|
|
|
|
all_rows_set = cellInfo(cellIndex(r, c)).top_line;
|
2008-03-18 18:08:32 +00:00
|
|
|
return all_rows_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::rowBottomLine(row_type r) const
|
|
|
|
{
|
|
|
|
bool all_rows_set = true;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; all_rows_set && c < ncols(); ++c)
|
|
|
|
all_rows_set = cellInfo(cellIndex(r, c)).bottom_line;
|
2008-03-18 18:08:32 +00:00
|
|
|
return all_rows_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::columnLeftLine(col_type c) const
|
|
|
|
{
|
2008-05-07 09:37:22 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
return false;
|
|
|
|
|
2008-04-24 17:26:17 +00:00
|
|
|
int nrows_left = 0;
|
|
|
|
int total = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
idx_type const i = cellIndex(r, c);
|
2008-04-24 17:26:17 +00:00
|
|
|
if (c == cellColumn(i)) {
|
|
|
|
++total;
|
2008-04-25 11:56:21 +00:00
|
|
|
bool right = c > 0 && cellInfo(cellIndex(r, c - 1)).right_line;
|
2008-04-24 17:26:17 +00:00
|
|
|
if (cellInfo(i).left_line || right)
|
|
|
|
++nrows_left;
|
|
|
|
}
|
2008-03-18 18:08:32 +00:00
|
|
|
}
|
2008-06-09 08:11:46 +00:00
|
|
|
return 2 * nrows_left >= total;
|
2008-03-18 18:08:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::columnRightLine(col_type c) const
|
|
|
|
{
|
2008-05-07 09:37:22 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
return false;
|
|
|
|
|
2008-04-24 17:26:17 +00:00
|
|
|
int nrows_right = 0;
|
|
|
|
int total = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2008-03-18 18:08:32 +00:00
|
|
|
idx_type i = cellIndex(r, c);
|
2008-04-24 17:26:17 +00:00
|
|
|
if (c == cellColumn(i) + columnSpan(i) - 1) {
|
|
|
|
++total;
|
2014-07-26 14:29:23 +00:00
|
|
|
bool left = (c + 1 < ncols()
|
2008-12-22 18:18:47 +00:00
|
|
|
&& cellInfo(cellIndex(r, c + 1)).left_line)
|
2010-03-05 18:10:34 +00:00
|
|
|
|| c + 1 == ncols();
|
2008-04-24 17:26:17 +00:00
|
|
|
if (cellInfo(i).right_line && left)
|
|
|
|
++nrows_right;
|
|
|
|
}
|
2008-03-18 18:08:32 +00:00
|
|
|
}
|
2008-06-09 08:11:46 +00:00
|
|
|
return 2 * nrows_right >= total;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LyXAlignment Tabular::getAlignment(idx_type cell, bool onlycolumn) const
|
|
|
|
{
|
2010-06-05 07:44:44 +00:00
|
|
|
if (!onlycolumn && (isMultiColumn(cell) || isMultiRow(cell)))
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).alignment;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
return column_info[cellColumn(cell)].alignment;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Tabular::VAlignment
|
|
|
|
Tabular::getVAlignment(idx_type cell, bool onlycolumn) const
|
|
|
|
{
|
2010-03-13 10:49:26 +00:00
|
|
|
if (!onlycolumn && (isMultiColumn(cell) || isMultiRow(cell)))
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).valignment;
|
2007-09-04 10:52:08 +00:00
|
|
|
return column_info[cellColumn(cell)].valignment;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-28 12:58:49 +00:00
|
|
|
Length const Tabular::getPWidth(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (isMultiColumn(cell))
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).p_width;
|
2007-09-04 10:52:08 +00:00
|
|
|
return column_info[cellColumn(cell)].p_width;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-07 05:32:28 +00:00
|
|
|
Length const Tabular::getMROffset(idx_type cell) const
|
|
|
|
{
|
|
|
|
return cellInfo(cell).mroffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
int Tabular::textHOffset(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
// the LaTeX Way :-(
|
|
|
|
int x = WIDTH_OF_LINE;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2010-06-14 10:42:42 +00:00
|
|
|
int const w = cellWidth(cell) - cellInfo(cell).width;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
switch (getAlignment(cell)) {
|
|
|
|
case LYX_ALIGN_CENTER:
|
2010-06-14 10:42:42 +00:00
|
|
|
x += w / 2;
|
2007-04-26 12:54:21 +00:00
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
2010-06-14 10:42:42 +00:00
|
|
|
x += w;
|
2007-04-26 12:54:21 +00:00
|
|
|
break;
|
2010-06-05 07:44:44 +00:00
|
|
|
case LYX_ALIGN_DECIMAL: {
|
|
|
|
// we center when no decimal point
|
|
|
|
if (cellInfo(cell).decimal_width == 0) {
|
2010-06-14 10:42:42 +00:00
|
|
|
x += w / 2;
|
2010-06-05 07:44:44 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
col_type const c = cellColumn(cell);
|
|
|
|
int max_dhoffset = 0;
|
|
|
|
for(row_type r = 0; r < row_info.size() ; ++r) {
|
|
|
|
idx_type const i = cellIndex(r, c);
|
2010-06-12 16:44:50 +00:00
|
|
|
if (getAlignment(i) == LYX_ALIGN_DECIMAL
|
|
|
|
&& cellInfo(i).decimal_width != 0)
|
2010-06-05 07:44:44 +00:00
|
|
|
max_dhoffset = max(max_dhoffset, cellInfo(i).decimal_hoffset);
|
|
|
|
}
|
|
|
|
x += max_dhoffset - cellInfo(cell).decimal_hoffset;
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
default:
|
|
|
|
// LYX_ALIGN_LEFT: nothing :-)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
int Tabular::textVOffset(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-04-13 18:56:28 +00:00
|
|
|
int voffset = cellInfo(cell).voffset;
|
|
|
|
if (isMultiRow(cell)) {
|
|
|
|
row_type const row = cellRow(cell);
|
2014-07-26 14:29:23 +00:00
|
|
|
voffset += (cellHeight(cell) - rowAscent(row) - rowDescent(row))/2;
|
2010-04-13 18:56:28 +00:00
|
|
|
}
|
|
|
|
return voffset;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Tabular::idx_type Tabular::getFirstCellInRow(row_type row) const
|
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
col_type c = 0;
|
2011-08-05 16:06:41 +00:00
|
|
|
idx_type const numcells = numberOfCellsInRow(row);
|
|
|
|
// we check against numcells to make sure we do not crash if all the
|
|
|
|
// cells are multirow (bug #7535), but in that case our return value
|
|
|
|
// is really invalid, i.e., it is NOT the first cell in the row. but
|
|
|
|
// i do not know what to do here. (rgh)
|
|
|
|
while (c < numcells - 1
|
|
|
|
&& cell_info[row][c].multirow == CELL_PART_OF_MULTIROW)
|
2010-02-11 01:07:54 +00:00
|
|
|
++c;
|
2010-02-12 18:36:20 +00:00
|
|
|
return cell_info[row][c].cellno;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Tabular::idx_type Tabular::getLastCellInRow(row_type row) const
|
|
|
|
{
|
2010-03-05 18:10:34 +00:00
|
|
|
col_type c = ncols() - 1;
|
2011-08-05 16:06:41 +00:00
|
|
|
// of course we check against 0 so we don't crash. but we have the same
|
|
|
|
// problem as in the previous routine: if all the cells are part of a
|
|
|
|
// multirow or part of a multi column, then our return value is invalid.
|
2011-02-17 10:42:13 +00:00
|
|
|
while (c > 0
|
|
|
|
&& (cell_info[row][c].multirow == CELL_PART_OF_MULTIROW
|
|
|
|
|| cell_info[row][c].multicolumn == CELL_PART_OF_MULTICOLUMN))
|
2010-02-12 18:36:20 +00:00
|
|
|
--c;
|
|
|
|
return cell_info[row][c].cellno;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
Tabular::row_type Tabular::cellRow(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-04-21 13:33:39 +00:00
|
|
|
if (cell >= numberofcells)
|
2010-03-05 18:10:34 +00:00
|
|
|
return nrows() - 1;
|
2007-04-26 12:54:21 +00:00
|
|
|
if (cell == npos)
|
|
|
|
return 0;
|
|
|
|
return rowofcell[cell];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
Tabular::col_type Tabular::cellColumn(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-04-21 13:33:39 +00:00
|
|
|
if (cell >= numberofcells)
|
2010-03-05 18:10:34 +00:00
|
|
|
return ncols() - 1;
|
2007-04-26 12:54:21 +00:00
|
|
|
if (cell == npos)
|
2010-11-01 15:15:38 +00:00
|
|
|
return 0;
|
2007-04-26 12:54:21 +00:00
|
|
|
return columnofcell[cell];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void Tabular::write(ostream & os) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
// header line
|
|
|
|
os << "<lyxtabular"
|
|
|
|
<< write_attribute("version", 3)
|
2010-03-05 18:10:34 +00:00
|
|
|
<< write_attribute("rows", nrows())
|
|
|
|
<< write_attribute("columns", ncols())
|
2007-04-26 12:54:21 +00:00
|
|
|
<< ">\n";
|
|
|
|
// global longtable options
|
|
|
|
os << "<features"
|
2014-05-31 08:46:49 +00:00
|
|
|
<< write_attribute("rotate", rotate)
|
2007-04-26 12:54:21 +00:00
|
|
|
<< write_attribute("booktabs", use_booktabs)
|
2009-07-11 14:33:05 +00:00
|
|
|
<< write_attribute("islongtable", is_long_tabular)
|
|
|
|
<< write_attribute("firstHeadTopDL", endfirsthead.topDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
<< write_attribute("firstHeadBottomDL", endfirsthead.bottomDL)
|
|
|
|
<< write_attribute("firstHeadEmpty", endfirsthead.empty)
|
|
|
|
<< write_attribute("headTopDL", endhead.topDL)
|
|
|
|
<< write_attribute("headBottomDL", endhead.bottomDL)
|
|
|
|
<< write_attribute("footTopDL", endfoot.topDL)
|
|
|
|
<< write_attribute("footBottomDL", endfoot.bottomDL)
|
|
|
|
<< write_attribute("lastFootTopDL", endlastfoot.topDL)
|
|
|
|
<< write_attribute("lastFootBottomDL", endlastfoot.bottomDL)
|
2009-07-11 14:33:05 +00:00
|
|
|
<< write_attribute("lastFootEmpty", endlastfoot.empty);
|
|
|
|
// longtables cannot be aligned vertically
|
2011-02-03 23:11:26 +00:00
|
|
|
if (!is_long_tabular) {
|
2014-05-31 08:33:46 +00:00
|
|
|
os << write_attribute("tabularvalignment", tabular_valignment);
|
|
|
|
os << write_attribute("tabularwidth", tabular_width);
|
2011-02-03 23:11:26 +00:00
|
|
|
}
|
2009-07-11 14:33:05 +00:00
|
|
|
if (is_long_tabular)
|
2014-05-31 08:33:46 +00:00
|
|
|
os << write_attribute("longtabularalignment", longtabular_alignment);
|
2009-07-11 14:33:05 +00:00
|
|
|
os << ">\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "<column"
|
2010-06-05 07:44:44 +00:00
|
|
|
<< write_attribute("alignment", column_info[c].alignment);
|
|
|
|
if (column_info[c].alignment == LYX_ALIGN_DECIMAL)
|
|
|
|
os << write_attribute("decimal_point", column_info[c].decimal_point);
|
|
|
|
os << write_attribute("valignment", column_info[c].valignment)
|
2010-03-05 18:10:34 +00:00
|
|
|
<< write_attribute("width", column_info[c].p_width.asString())
|
|
|
|
<< write_attribute("special", column_info[c].align_special)
|
2007-04-26 12:54:21 +00:00
|
|
|
<< ">\n";
|
|
|
|
}
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2007-04-26 12:54:21 +00:00
|
|
|
static const string def("default");
|
2008-03-18 18:08:32 +00:00
|
|
|
os << "<row";
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row_info[r].top_space_default)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << write_attribute("topspace", def);
|
|
|
|
else
|
2010-03-05 18:10:34 +00:00
|
|
|
os << write_attribute("topspace", row_info[r].top_space);
|
|
|
|
if (row_info[r].bottom_space_default)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << write_attribute("bottomspace", def);
|
|
|
|
else
|
2010-03-05 18:10:34 +00:00
|
|
|
os << write_attribute("bottomspace", row_info[r].bottom_space);
|
|
|
|
if (row_info[r].interline_space_default)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << write_attribute("interlinespace", def);
|
|
|
|
else
|
2010-03-05 18:10:34 +00:00
|
|
|
os << write_attribute("interlinespace", row_info[r].interline_space);
|
|
|
|
os << write_attribute("endhead", row_info[r].endhead)
|
|
|
|
<< write_attribute("endfirsthead", row_info[r].endfirsthead)
|
|
|
|
<< write_attribute("endfoot", row_info[r].endfoot)
|
|
|
|
<< write_attribute("endlastfoot", row_info[r].endlastfoot)
|
|
|
|
<< write_attribute("newpage", row_info[r].newpage)
|
|
|
|
<< write_attribute("caption", row_info[r].caption)
|
2007-04-26 12:54:21 +00:00
|
|
|
<< ">\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "<cell"
|
2010-03-05 18:10:34 +00:00
|
|
|
<< write_attribute("multicolumn", cell_info[r][c].multicolumn)
|
|
|
|
<< write_attribute("multirow", cell_info[r][c].multirow)
|
2010-11-07 05:32:28 +00:00
|
|
|
<< write_attribute("mroffset", cell_info[r][c].mroffset)
|
2010-03-05 18:10:34 +00:00
|
|
|
<< write_attribute("alignment", cell_info[r][c].alignment)
|
|
|
|
<< write_attribute("valignment", cell_info[r][c].valignment)
|
|
|
|
<< write_attribute("topline", cell_info[r][c].top_line)
|
|
|
|
<< write_attribute("bottomline", cell_info[r][c].bottom_line)
|
|
|
|
<< write_attribute("leftline", cell_info[r][c].left_line)
|
|
|
|
<< write_attribute("rightline", cell_info[r][c].right_line)
|
|
|
|
<< write_attribute("rotate", cell_info[r][c].rotate)
|
|
|
|
<< write_attribute("usebox", cell_info[r][c].usebox)
|
|
|
|
<< write_attribute("width", cell_info[r][c].p_width)
|
|
|
|
<< write_attribute("special", cell_info[r][c].align_special)
|
2007-04-26 12:54:21 +00:00
|
|
|
<< ">\n";
|
|
|
|
os << "\\begin_inset ";
|
2010-03-05 18:10:34 +00:00
|
|
|
cell_info[r][c].inset->write(os);
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\n\\end_inset\n"
|
|
|
|
<< "</cell>\n";
|
2014-06-03 17:35:18 +00:00
|
|
|
// FIXME This can be removed again once the mystery
|
|
|
|
// crash has been resolved.
|
|
|
|
os << flush;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
os << "</row>\n";
|
|
|
|
}
|
|
|
|
os << "</lyxtabular>\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void Tabular::read(Lexer & lex)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
string line;
|
|
|
|
istream & is = lex.getStream();
|
|
|
|
|
|
|
|
l_getline(is, line);
|
2008-02-27 20:43:16 +00:00
|
|
|
if (!prefixIs(line, "<lyxtabular ") && !prefixIs(line, "<Tabular ")) {
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(false, return);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int version;
|
|
|
|
if (!getTokenValue(line, "version", version))
|
|
|
|
return;
|
2013-04-25 21:27:10 +00:00
|
|
|
LATTEST(version >= 2);
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
int rows_arg;
|
|
|
|
if (!getTokenValue(line, "rows", rows_arg))
|
|
|
|
return;
|
|
|
|
int columns_arg;
|
|
|
|
if (!getTokenValue(line, "columns", columns_arg))
|
|
|
|
return;
|
2009-11-08 15:53:21 +00:00
|
|
|
init(buffer_, rows_arg, columns_arg);
|
2007-04-26 12:54:21 +00:00
|
|
|
l_getline(is, line);
|
|
|
|
if (!prefixIs(line, "<features")) {
|
|
|
|
lyxerr << "Wrong tabular format (expected <features ...> got"
|
|
|
|
<< line << ')' << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
getTokenValue(line, "rotate", rotate);
|
|
|
|
getTokenValue(line, "booktabs", use_booktabs);
|
|
|
|
getTokenValue(line, "islongtable", is_long_tabular);
|
2009-01-03 18:33:09 +00:00
|
|
|
getTokenValue(line, "tabularvalignment", tabular_valignment);
|
2011-02-03 23:11:26 +00:00
|
|
|
getTokenValue(line, "tabularwidth", tabular_width);
|
2009-07-11 13:09:45 +00:00
|
|
|
getTokenValue(line, "longtabularalignment", longtabular_alignment);
|
2007-04-26 12:54:21 +00:00
|
|
|
getTokenValue(line, "firstHeadTopDL", endfirsthead.topDL);
|
|
|
|
getTokenValue(line, "firstHeadBottomDL", endfirsthead.bottomDL);
|
|
|
|
getTokenValue(line, "firstHeadEmpty", endfirsthead.empty);
|
|
|
|
getTokenValue(line, "headTopDL", endhead.topDL);
|
|
|
|
getTokenValue(line, "headBottomDL", endhead.bottomDL);
|
|
|
|
getTokenValue(line, "footTopDL", endfoot.topDL);
|
|
|
|
getTokenValue(line, "footBottomDL", endfoot.bottomDL);
|
|
|
|
getTokenValue(line, "lastFootTopDL", endlastfoot.topDL);
|
|
|
|
getTokenValue(line, "lastFootBottomDL", endlastfoot.bottomDL);
|
|
|
|
getTokenValue(line, "lastFootEmpty", endlastfoot.empty);
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2007-04-26 12:54:21 +00:00
|
|
|
l_getline(is,line);
|
|
|
|
if (!prefixIs(line,"<column")) {
|
|
|
|
lyxerr << "Wrong tabular format (expected <column ...> got"
|
|
|
|
<< line << ')' << endl;
|
|
|
|
return;
|
|
|
|
}
|
2010-03-05 18:10:34 +00:00
|
|
|
getTokenValue(line, "alignment", column_info[c].alignment);
|
2010-06-05 07:44:44 +00:00
|
|
|
getTokenValue(line, "decimal_point", column_info[c].decimal_point);
|
2010-03-05 18:10:34 +00:00
|
|
|
getTokenValue(line, "valignment", column_info[c].valignment);
|
|
|
|
getTokenValue(line, "width", column_info[c].p_width);
|
|
|
|
getTokenValue(line, "special", column_info[c].align_special);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type i = 0; i < nrows(); ++i) {
|
2007-04-26 12:54:21 +00:00
|
|
|
l_getline(is, line);
|
|
|
|
if (!prefixIs(line, "<row")) {
|
|
|
|
lyxerr << "Wrong tabular format (expected <row ...> got"
|
|
|
|
<< line << ')' << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
getTokenValue(line, "topspace", row_info[i].top_space,
|
2007-05-28 22:27:45 +00:00
|
|
|
row_info[i].top_space_default);
|
2007-04-26 12:54:21 +00:00
|
|
|
getTokenValue(line, "bottomspace", row_info[i].bottom_space,
|
2007-05-28 22:27:45 +00:00
|
|
|
row_info[i].bottom_space_default);
|
2007-04-26 12:54:21 +00:00
|
|
|
getTokenValue(line, "interlinespace", row_info[i].interline_space,
|
2007-05-28 22:27:45 +00:00
|
|
|
row_info[i].interline_space_default);
|
2007-04-26 12:54:21 +00:00
|
|
|
getTokenValue(line, "endfirsthead", row_info[i].endfirsthead);
|
|
|
|
getTokenValue(line, "endhead", row_info[i].endhead);
|
|
|
|
getTokenValue(line, "endfoot", row_info[i].endfoot);
|
|
|
|
getTokenValue(line, "endlastfoot", row_info[i].endlastfoot);
|
|
|
|
getTokenValue(line, "newpage", row_info[i].newpage);
|
2008-05-04 07:51:50 +00:00
|
|
|
getTokenValue(line, "caption", row_info[i].caption);
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type j = 0; j < ncols(); ++j) {
|
2007-04-26 12:54:21 +00:00
|
|
|
l_getline(is, line);
|
|
|
|
if (!prefixIs(line, "<cell")) {
|
|
|
|
lyxerr << "Wrong tabular format (expected <cell ...> got"
|
|
|
|
<< line << ')' << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
getTokenValue(line, "multicolumn", cell_info[i][j].multicolumn);
|
2010-02-11 01:07:54 +00:00
|
|
|
getTokenValue(line, "multirow", cell_info[i][j].multirow);
|
2010-11-07 05:32:28 +00:00
|
|
|
getTokenValue(line, "mroffset", cell_info[i][j].mroffset);
|
2007-04-26 12:54:21 +00:00
|
|
|
getTokenValue(line, "alignment", cell_info[i][j].alignment);
|
|
|
|
getTokenValue(line, "valignment", cell_info[i][j].valignment);
|
|
|
|
getTokenValue(line, "topline", cell_info[i][j].top_line);
|
|
|
|
getTokenValue(line, "bottomline", cell_info[i][j].bottom_line);
|
|
|
|
getTokenValue(line, "leftline", cell_info[i][j].left_line);
|
|
|
|
getTokenValue(line, "rightline", cell_info[i][j].right_line);
|
|
|
|
getTokenValue(line, "rotate", cell_info[i][j].rotate);
|
|
|
|
getTokenValue(line, "usebox", cell_info[i][j].usebox);
|
|
|
|
getTokenValue(line, "width", cell_info[i][j].p_width);
|
2008-07-21 02:07:54 +00:00
|
|
|
setFixedWidth(i,j);
|
2007-04-26 12:54:21 +00:00
|
|
|
getTokenValue(line, "special", cell_info[i][j].align_special);
|
|
|
|
l_getline(is, line);
|
|
|
|
if (prefixIs(line, "\\begin_inset")) {
|
2008-07-23 12:13:41 +00:00
|
|
|
cell_info[i][j].inset->setBuffer(*buffer_);
|
2008-02-27 20:43:16 +00:00
|
|
|
cell_info[i][j].inset->read(lex);
|
2007-04-26 12:54:21 +00:00
|
|
|
l_getline(is, line);
|
|
|
|
}
|
|
|
|
if (!prefixIs(line, "</cell>")) {
|
|
|
|
lyxerr << "Wrong tabular format (expected </cell> got"
|
|
|
|
<< line << ')' << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
l_getline(is, line);
|
|
|
|
if (!prefixIs(line, "</row>")) {
|
|
|
|
lyxerr << "Wrong tabular format (expected </row> got"
|
|
|
|
<< line << ')' << endl;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (!prefixIs(line, "</lyxtabular>")) {
|
|
|
|
l_getline(is, line);
|
|
|
|
}
|
2007-09-04 18:13:19 +00:00
|
|
|
updateIndexes();
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::isMultiColumn(idx_type cell) const
|
|
|
|
{
|
2014-07-26 14:29:23 +00:00
|
|
|
return (cellInfo(cell).multicolumn == CELL_BEGIN_OF_MULTICOLUMN
|
2010-03-04 20:20:45 +00:00
|
|
|
|| cellInfo(cell).multicolumn == CELL_PART_OF_MULTICOLUMN);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-24 10:51:28 +00:00
|
|
|
bool Tabular::hasMultiColumn(col_type c) const
|
|
|
|
{
|
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
if (isMultiColumn(cellIndex(r, c)))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
Tabular::CellData & Tabular::cellInfo(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2007-09-04 10:52:08 +00:00
|
|
|
return cell_info[cellRow(cell)][cellColumn(cell)];
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-09-25 06:50:03 +00:00
|
|
|
Tabular::idx_type Tabular::setMultiColumn(idx_type cell, idx_type number,
|
|
|
|
bool const right_border)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-03-04 20:20:45 +00:00
|
|
|
idx_type const col = cellColumn(cell);
|
|
|
|
idx_type const row = cellRow(cell);
|
|
|
|
for (idx_type i = 0; i < number; ++i)
|
|
|
|
unsetMultiRow(cellIndex(row, col + i));
|
|
|
|
|
2010-03-15 18:08:38 +00:00
|
|
|
// unsetting of multirow may have invalidated cell index
|
|
|
|
cell = cellIndex(row, col);
|
2008-03-25 13:32:38 +00:00
|
|
|
CellData & cs = cellInfo(cell);
|
2007-04-26 12:54:21 +00:00
|
|
|
cs.multicolumn = CELL_BEGIN_OF_MULTICOLUMN;
|
2010-06-05 07:44:44 +00:00
|
|
|
if (column_info[col].alignment != LYX_ALIGN_DECIMAL)
|
|
|
|
cs.alignment = column_info[col].alignment;
|
2014-02-06 00:09:18 +00:00
|
|
|
setRightLine(cell, right_border);
|
2010-03-04 20:20:45 +00:00
|
|
|
|
2015-03-24 09:50:51 +00:00
|
|
|
idx_type lastcell = cellIndex(row, col + number - 1);
|
|
|
|
for (idx_type i = 1; i < lastcell - cell + 1; ++i) {
|
2008-03-25 13:32:38 +00:00
|
|
|
CellData & cs1 = cellInfo(cell + i);
|
2007-04-26 12:54:21 +00:00
|
|
|
cs1.multicolumn = CELL_PART_OF_MULTICOLUMN;
|
2008-02-27 20:43:16 +00:00
|
|
|
cs.inset->appendParagraphs(cs1.inset->paragraphs());
|
2007-04-26 12:54:21 +00:00
|
|
|
cs1.inset->clear();
|
|
|
|
}
|
2007-09-04 18:13:19 +00:00
|
|
|
updateIndexes();
|
2010-03-15 18:08:38 +00:00
|
|
|
return cell;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
bool Tabular::isMultiRow(idx_type cell) const
|
|
|
|
{
|
|
|
|
return (cellInfo(cell).multirow == CELL_BEGIN_OF_MULTIROW
|
|
|
|
|| cellInfo(cell).multirow == CELL_PART_OF_MULTIROW);
|
|
|
|
}
|
|
|
|
|
2012-12-24 10:51:28 +00:00
|
|
|
bool Tabular::hasMultiRow(row_type r) const
|
|
|
|
{
|
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
if (isMultiRow(cellIndex(r, c)))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2010-02-11 01:07:54 +00:00
|
|
|
|
2011-09-23 17:12:20 +00:00
|
|
|
Tabular::idx_type Tabular::setMultiRow(idx_type cell, idx_type number,
|
2014-02-14 02:17:20 +00:00
|
|
|
bool const bottom_border,
|
|
|
|
LyXAlignment const halign)
|
2010-02-11 01:07:54 +00:00
|
|
|
{
|
2010-03-04 20:20:45 +00:00
|
|
|
idx_type const col = cellColumn(cell);
|
|
|
|
idx_type const row = cellRow(cell);
|
|
|
|
for (idx_type i = 0; i < number; ++i)
|
|
|
|
unsetMultiColumn(cellIndex(row + i, col));
|
|
|
|
|
2010-11-01 03:26:25 +00:00
|
|
|
// unsetting of multirow may have invalidated cell index
|
2010-03-15 18:08:38 +00:00
|
|
|
cell = cellIndex(row, col);
|
2010-02-11 01:07:54 +00:00
|
|
|
CellData & cs = cellInfo(cell);
|
|
|
|
cs.multirow = CELL_BEGIN_OF_MULTIROW;
|
2010-03-13 10:49:26 +00:00
|
|
|
cs.valignment = LYX_VALIGN_MIDDLE;
|
2010-11-01 03:26:25 +00:00
|
|
|
// the horizontal alignment of multirow cells can only
|
|
|
|
// be changed for the whole table row,
|
|
|
|
// support changing this only for the multirow cell can be done via
|
|
|
|
// \multirowsetup
|
2014-02-14 02:17:20 +00:00
|
|
|
if (getPWidth(cell).zero())
|
|
|
|
cs.alignment = halign;
|
|
|
|
else
|
|
|
|
cs.alignment = LYX_ALIGN_LEFT;
|
2010-03-05 03:37:21 +00:00
|
|
|
|
2011-09-23 17:12:20 +00:00
|
|
|
// set the bottom line of the last selected cell
|
|
|
|
setBottomLine(cell, bottom_border);
|
2010-03-04 20:20:45 +00:00
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
for (idx_type i = 1; i < number; ++i) {
|
2010-03-04 20:20:45 +00:00
|
|
|
CellData & cs1 = cell_info[row + i][col];
|
2010-02-11 01:07:54 +00:00
|
|
|
cs1.multirow = CELL_PART_OF_MULTIROW;
|
|
|
|
cs.inset->appendParagraphs(cs1.inset->paragraphs());
|
|
|
|
cs1.inset->clear();
|
|
|
|
}
|
|
|
|
updateIndexes();
|
2010-03-15 18:08:38 +00:00
|
|
|
return cell;
|
2010-02-11 01:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
Tabular::idx_type Tabular::columnSpan(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2007-09-04 10:52:08 +00:00
|
|
|
row_type const row = cellRow(cell);
|
2010-06-05 07:44:44 +00:00
|
|
|
col_type const col = cellColumn(cell);
|
|
|
|
int span = 1;
|
|
|
|
while (col + span < ncols() && isPartOfMultiColumn(row, col + span))
|
|
|
|
++span;
|
2010-02-11 01:07:54 +00:00
|
|
|
|
2010-06-05 07:44:44 +00:00
|
|
|
return span;
|
2010-02-11 01:07:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Tabular::idx_type Tabular::rowSpan(idx_type cell) const
|
|
|
|
{
|
|
|
|
col_type const column = cellColumn(cell);
|
|
|
|
col_type row = cellRow(cell) + 1;
|
2010-03-05 18:10:34 +00:00
|
|
|
while (row < nrows() && isPartOfMultiRow(row, column))
|
2010-02-11 01:07:54 +00:00
|
|
|
++row;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
return row - cellRow(cell);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
void Tabular::unsetMultiColumn(idx_type cell)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-03-04 20:20:45 +00:00
|
|
|
if (!isMultiColumn(cell))
|
|
|
|
return;
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
row_type const row = cellRow(cell);
|
2010-03-04 20:20:45 +00:00
|
|
|
col_type const col = cellColumn(cell);
|
2010-02-11 01:07:54 +00:00
|
|
|
row_type const span = columnSpan(cell);
|
2010-11-01 04:30:06 +00:00
|
|
|
for (col_type c = 0; c < span; ++c) {
|
|
|
|
// in the table dialog the lines are set in every case
|
|
|
|
// when unsetting a multicolumn this leads to an additional right
|
|
|
|
// line for every cell that was part of the former multicolumn cell,
|
|
|
|
// except if the cell is in the last column
|
|
|
|
// therefore remove this line
|
2010-11-01 11:54:18 +00:00
|
|
|
if (cell_info[row][col + c].multicolumn == CELL_BEGIN_OF_MULTICOLUMN
|
2010-11-01 04:30:06 +00:00
|
|
|
&& (col + c) < (col + span - 1))
|
|
|
|
cell_info[row][col + c].right_line = false;
|
2010-03-04 20:20:45 +00:00
|
|
|
cell_info[row][col + c].multicolumn = CELL_NORMAL;
|
2010-11-01 04:30:06 +00:00
|
|
|
}
|
2010-02-11 01:07:54 +00:00
|
|
|
updateIndexes();
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
void Tabular::unsetMultiRow(idx_type cell)
|
|
|
|
{
|
2010-03-04 20:20:45 +00:00
|
|
|
if (!isMultiRow(cell))
|
|
|
|
return;
|
|
|
|
|
2010-03-13 10:49:26 +00:00
|
|
|
cellInfo(cell).valignment = LYX_VALIGN_TOP;
|
2010-03-16 22:48:07 +00:00
|
|
|
cellInfo(cell).alignment = LYX_ALIGN_CENTER;
|
2010-02-11 01:07:54 +00:00
|
|
|
row_type const row = cellRow(cell);
|
2010-03-04 20:20:45 +00:00
|
|
|
col_type const col = cellColumn(cell);
|
2010-02-11 01:07:54 +00:00
|
|
|
row_type const span = rowSpan(cell);
|
|
|
|
for (row_type r = 0; r < span; ++r)
|
2010-03-04 20:20:45 +00:00
|
|
|
cell_info[row + r][col].multirow = CELL_NORMAL;
|
2007-09-04 18:13:19 +00:00
|
|
|
updateIndexes();
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-16 01:29:37 +00:00
|
|
|
void Tabular::setRotateCell(idx_type cell, int value)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2012-03-16 01:29:37 +00:00
|
|
|
cellInfo(cell).rotate = value;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-16 01:29:37 +00:00
|
|
|
int Tabular::getRotateCell(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
return cellInfo(cell).rotate;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::needRotating() const
|
|
|
|
{
|
|
|
|
if (rotate)
|
|
|
|
return true;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r)
|
|
|
|
for (col_type c = 0; c < ncols(); ++c)
|
2012-03-16 01:29:37 +00:00
|
|
|
if (cell_info[r][c].rotate != 0)
|
2007-04-26 12:54:21 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::isLastCell(idx_type cell) const
|
|
|
|
{
|
2008-04-21 13:33:39 +00:00
|
|
|
if (cell + 1 < numberofcells)
|
2007-04-26 12:54:21 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
Tabular::idx_type Tabular::cellAbove(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
if (cellRow(cell) == 0)
|
|
|
|
return cell;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
col_type const col = cellColumn(cell);
|
|
|
|
row_type r = cellRow(cell) - 1;
|
|
|
|
while (r > 0 && cell_info[r][col].multirow == CELL_PART_OF_MULTIROW)
|
|
|
|
--r;
|
|
|
|
|
|
|
|
return cell_info[r][col].cellno;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
Tabular::idx_type Tabular::cellBelow(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
row_type const nextrow = cellRow(cell) + rowSpan(cell);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (nextrow < nrows())
|
2010-02-11 01:07:54 +00:00
|
|
|
return cell_info[nextrow][cellColumn(cell)].cellno;
|
2007-04-26 12:54:21 +00:00
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
Tabular::idx_type Tabular::cellIndex(row_type row, col_type column) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(column != npos && column < ncols(), column = 0);
|
|
|
|
LASSERT(row != npos && row < nrows(), row = 0);
|
2007-04-26 12:54:21 +00:00
|
|
|
return cell_info[row][column].cellno;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::setUsebox(idx_type cell, BoxType type)
|
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInfo(cell).usebox = type;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-25 21:14:36 +00:00
|
|
|
// FIXME: Remove this routine because we cannot insert \parboxes when the user
|
|
|
|
// adds line breaks, see bug 4886.
|
2007-04-26 12:54:21 +00:00
|
|
|
Tabular::BoxType Tabular::getUsebox(idx_type cell) const
|
|
|
|
{
|
2008-05-25 21:14:36 +00:00
|
|
|
if ((!column_info[cellColumn(cell)].p_width.zero() && !isMultiColumn(cell)) ||
|
|
|
|
(isMultiColumn(cell) && !cellInfo(cell).p_width.zero()))
|
2007-04-26 12:54:21 +00:00
|
|
|
return BOX_NONE;
|
2008-03-25 13:32:38 +00:00
|
|
|
if (cellInfo(cell).usebox > 1)
|
|
|
|
return cellInfo(cell).usebox;
|
2007-04-26 12:54:21 +00:00
|
|
|
return useParbox(cell);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
// This are functions used for the longtable support
|
|
|
|
///
|
|
|
|
void Tabular::setLTHead(row_type row, bool flag, ltType const & hd,
|
|
|
|
bool first)
|
|
|
|
{
|
|
|
|
if (first) {
|
|
|
|
endfirsthead = hd;
|
|
|
|
if (hd.set)
|
|
|
|
row_info[row].endfirsthead = flag;
|
|
|
|
} else {
|
|
|
|
endhead = hd;
|
|
|
|
if (hd.set)
|
|
|
|
row_info[row].endhead = flag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::getRowOfLTHead(row_type row, ltType & hd) const
|
|
|
|
{
|
|
|
|
hd = endhead;
|
|
|
|
hd.set = haveLTHead();
|
|
|
|
return row_info[row].endhead;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::getRowOfLTFirstHead(row_type row, ltType & hd) const
|
|
|
|
{
|
|
|
|
hd = endfirsthead;
|
|
|
|
hd.set = haveLTFirstHead();
|
|
|
|
return row_info[row].endfirsthead;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::setLTFoot(row_type row, bool flag, ltType const & fd,
|
|
|
|
bool last)
|
|
|
|
{
|
|
|
|
if (last) {
|
|
|
|
endlastfoot = fd;
|
|
|
|
if (fd.set)
|
|
|
|
row_info[row].endlastfoot = flag;
|
|
|
|
} else {
|
|
|
|
endfoot = fd;
|
|
|
|
if (fd.set)
|
|
|
|
row_info[row].endfoot = flag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::getRowOfLTFoot(row_type row, ltType & fd) const
|
|
|
|
{
|
|
|
|
fd = endfoot;
|
|
|
|
fd.set = haveLTFoot();
|
|
|
|
return row_info[row].endfoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::getRowOfLTLastFoot(row_type row, ltType & fd) const
|
|
|
|
{
|
|
|
|
fd = endlastfoot;
|
|
|
|
fd.set = haveLTLastFoot();
|
|
|
|
return row_info[row].endlastfoot;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::setLTNewPage(row_type row, bool what)
|
|
|
|
{
|
|
|
|
row_info[row].newpage = what;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::getLTNewPage(row_type row) const
|
|
|
|
{
|
|
|
|
return row_info[row].newpage;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-18 21:27:17 +00:00
|
|
|
bool Tabular::haveLTHead(bool withcaptions) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2011-01-13 20:19:15 +00:00
|
|
|
if (!is_long_tabular)
|
|
|
|
return false;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type i = 0; i < nrows(); ++i)
|
2011-12-18 21:27:17 +00:00
|
|
|
if (row_info[i].endhead &&
|
|
|
|
(withcaptions || !row_info[i].caption))
|
2007-04-26 12:54:21 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-18 21:27:17 +00:00
|
|
|
bool Tabular::haveLTFirstHead(bool withcaptions) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2011-01-13 20:19:15 +00:00
|
|
|
if (!is_long_tabular || endfirsthead.empty)
|
2007-04-26 12:54:21 +00:00
|
|
|
return false;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r)
|
2011-12-18 21:27:17 +00:00
|
|
|
if (row_info[r].endfirsthead &&
|
|
|
|
(withcaptions || !row_info[r].caption))
|
2007-04-26 12:54:21 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-18 21:27:17 +00:00
|
|
|
bool Tabular::haveLTFoot(bool withcaptions) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2011-01-13 20:19:15 +00:00
|
|
|
if (!is_long_tabular)
|
|
|
|
return false;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r)
|
2011-12-18 21:27:17 +00:00
|
|
|
if (row_info[r].endfoot &&
|
|
|
|
(withcaptions || !row_info[r].caption))
|
2007-04-26 12:54:21 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-18 21:27:17 +00:00
|
|
|
bool Tabular::haveLTLastFoot(bool withcaptions) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2011-01-13 20:19:15 +00:00
|
|
|
if (!is_long_tabular || endlastfoot.empty)
|
2007-04-26 12:54:21 +00:00
|
|
|
return false;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r)
|
2011-12-18 21:27:17 +00:00
|
|
|
if (row_info[r].endlastfoot &&
|
|
|
|
(withcaptions || !row_info[r].caption))
|
2007-04-26 12:54:21 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-05-04 07:51:50 +00:00
|
|
|
Tabular::idx_type Tabular::setLTCaption(row_type row, bool what)
|
|
|
|
{
|
|
|
|
idx_type i = getFirstCellInRow(row);
|
|
|
|
if (what) {
|
2011-09-25 06:50:03 +00:00
|
|
|
setMultiColumn(i, numberOfCellsInRow(row), false);
|
2008-05-04 07:51:50 +00:00
|
|
|
setTopLine(i, false);
|
|
|
|
setBottomLine(i, false);
|
|
|
|
setLeftLine(i, false);
|
|
|
|
setRightLine(i, false);
|
2011-12-18 21:27:17 +00:00
|
|
|
if (!row_info[row].endfirsthead && !row_info[row].endhead &&
|
|
|
|
!row_info[row].endfoot && !row_info[row].endlastfoot) {
|
|
|
|
setLTHead(row, true, endfirsthead, true);
|
|
|
|
row_info[row].endfirsthead = true;
|
|
|
|
}
|
2009-02-10 18:08:09 +00:00
|
|
|
} else {
|
2008-05-04 07:51:50 +00:00
|
|
|
unsetMultiColumn(i);
|
2009-11-02 04:31:06 +00:00
|
|
|
// When unsetting a caption row, also all existing
|
|
|
|
// captions in this row must be dissolved.
|
2009-02-10 18:08:09 +00:00
|
|
|
}
|
2008-05-04 07:51:50 +00:00
|
|
|
row_info[row].caption = what;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::ltCaption(row_type row) const
|
|
|
|
{
|
|
|
|
return row_info[row].caption;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-18 21:27:17 +00:00
|
|
|
bool Tabular::haveLTCaption(CaptionType captiontype) const
|
2009-02-10 18:08:09 +00:00
|
|
|
{
|
2011-01-13 20:19:15 +00:00
|
|
|
if (!is_long_tabular)
|
|
|
|
return false;
|
2011-12-18 21:27:17 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
if (row_info[r].caption) {
|
|
|
|
switch (captiontype) {
|
|
|
|
case CAPTION_FIRSTHEAD:
|
|
|
|
if (row_info[r].endfirsthead)
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case CAPTION_HEAD:
|
|
|
|
if (row_info[r].endhead)
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case CAPTION_FOOT:
|
|
|
|
if (row_info[r].endfoot)
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case CAPTION_LASTFOOT:
|
|
|
|
if (row_info[r].endlastfoot)
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case CAPTION_ANY:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-10 18:08:09 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
// end longtable support functions
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
void Tabular::setRowAscent(row_type row, int height)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row >= nrows() || row_info[row].ascent == height)
|
2007-04-26 12:54:21 +00:00
|
|
|
return;
|
2007-09-04 10:52:08 +00:00
|
|
|
row_info[row].ascent = height;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
void Tabular::setRowDescent(row_type row, int height)
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row >= nrows() || row_info[row].descent == height)
|
2007-04-26 12:54:21 +00:00
|
|
|
return;
|
2007-09-04 10:52:08 +00:00
|
|
|
row_info[row].descent = height;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
int Tabular::rowAscent(row_type row) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(row < nrows(), row = 0);
|
2007-09-04 10:52:08 +00:00
|
|
|
return row_info[row].ascent;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
int Tabular::rowDescent(row_type row) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(row < nrows(), row = 0);
|
2007-09-04 10:52:08 +00:00
|
|
|
return row_info[row].descent;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
int Tabular::height() const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
int height = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type row = 0; row < nrows(); ++row)
|
2007-09-04 10:52:08 +00:00
|
|
|
height += rowAscent(row) + rowDescent(row) +
|
2010-02-11 01:07:54 +00:00
|
|
|
interRowSpace(row);
|
2007-04-26 12:54:21 +00:00
|
|
|
return height;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::isPartOfMultiColumn(row_type row, col_type column) const
|
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(row < nrows(), return false);
|
|
|
|
LASSERT(column < ncols(), return false);
|
2007-04-26 12:54:21 +00:00
|
|
|
return cell_info[row][column].multicolumn == CELL_PART_OF_MULTICOLUMN;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
bool Tabular::isPartOfMultiRow(row_type row, col_type column) const
|
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
LASSERT(row < nrows(), return false);
|
|
|
|
LASSERT(column < ncols(), return false);
|
2010-02-11 01:07:54 +00:00
|
|
|
return cell_info[row][column].multirow == CELL_PART_OF_MULTIROW;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-05 17:13:10 +00:00
|
|
|
void Tabular::TeXTopHLine(otexstream & os, row_type row, string const & lang) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-09-14 17:43:04 +00:00
|
|
|
// we only output complete row lines and the 1st row here, the rest
|
|
|
|
// is done in Tabular::TeXBottomHLine(...)
|
|
|
|
|
|
|
|
// get for each column the topline (if any)
|
2008-09-14 12:31:58 +00:00
|
|
|
vector<bool> topline;
|
2008-09-18 16:29:27 +00:00
|
|
|
col_type nset = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2008-09-14 12:31:58 +00:00
|
|
|
topline.push_back(topLine(cellIndex(row, c)));
|
2010-02-11 01:07:54 +00:00
|
|
|
// If cell is part of a multirow and not the first cell of the
|
|
|
|
// multirow, no line must be drawn.
|
|
|
|
if (row != 0)
|
|
|
|
if (isMultiRow(cellIndex(row, c))
|
2011-09-23 12:36:37 +00:00
|
|
|
&& cell_info[row][c].multirow != CELL_BEGIN_OF_MULTIROW)
|
|
|
|
topline[c] = false;
|
2008-09-14 12:31:58 +00:00
|
|
|
if (topline[c])
|
|
|
|
++nset;
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-09-14 17:43:04 +00:00
|
|
|
// do nothing if empty first row, or incomplete row line after
|
2010-03-05 18:10:34 +00:00
|
|
|
if ((row == 0 && nset == 0) || (row > 0 && nset != ncols()))
|
2011-02-10 20:02:48 +00:00
|
|
|
return;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-09-14 17:43:04 +00:00
|
|
|
// only output complete row lines and the 1st row's clines
|
2010-03-05 18:10:34 +00:00
|
|
|
if (nset == ncols()) {
|
2008-09-14 12:31:58 +00:00
|
|
|
if (use_booktabs) {
|
|
|
|
os << (row == 0 ? "\\toprule " : "\\midrule ");
|
|
|
|
} else {
|
|
|
|
os << "\\hline ";
|
|
|
|
}
|
|
|
|
} else if (row == 0) {
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2010-10-05 01:14:34 +00:00
|
|
|
if (topline[c]) {
|
|
|
|
col_type offset = 0;
|
|
|
|
for (col_type j = 0 ; j < c; ++j)
|
|
|
|
if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
|
|
|
|
++offset;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
//babel makes the "-" character an active one, so we have to suppress this here
|
|
|
|
//see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
|
|
|
|
if (lang == "slovak" || lang == "czech")
|
2014-07-26 14:29:23 +00:00
|
|
|
os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline")
|
2010-10-05 01:14:34 +00:00
|
|
|
<< "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
|
|
|
|
else
|
|
|
|
os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
col_type cstart = c;
|
|
|
|
for ( ; c < ncols() && topline[c]; ++c) {}
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
for (col_type j = cstart ; j < c ; ++j)
|
|
|
|
if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
|
|
|
|
++offset;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
os << c + offset << "} ";
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
os << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-05 17:13:10 +00:00
|
|
|
void Tabular::TeXBottomHLine(otexstream & os, row_type row, string const & lang) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-09-14 17:43:04 +00:00
|
|
|
// we output bottomlines of row r and the toplines of row r+1
|
|
|
|
// if the latter do not span the whole tabular
|
|
|
|
|
|
|
|
// get the bottomlines of row r, and toplines in next row
|
2010-03-05 18:10:34 +00:00
|
|
|
bool lastrow = row == nrows() - 1;
|
2008-09-14 12:31:58 +00:00
|
|
|
vector<bool> bottomline, topline;
|
|
|
|
bool nextrowset = true;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2008-09-14 12:31:58 +00:00
|
|
|
bottomline.push_back(bottomLine(cellIndex(row, c)));
|
|
|
|
topline.push_back(!lastrow && topLine(cellIndex(row + 1, c)));
|
2011-09-23 12:36:37 +00:00
|
|
|
// If cell is part of a multirow and not the last cell of the
|
2010-02-11 01:07:54 +00:00
|
|
|
// multirow, no line must be drawn.
|
|
|
|
if (!lastrow)
|
|
|
|
if (isMultiRow(cellIndex(row, c))
|
2011-09-23 12:36:37 +00:00
|
|
|
&& isMultiRow(cellIndex(row + 1, c))
|
|
|
|
&& cell_info[row + 1][c].multirow != CELL_BEGIN_OF_MULTIROW) {
|
|
|
|
bottomline[c] = false;
|
|
|
|
topline[c] = false;
|
2010-02-11 01:07:54 +00:00
|
|
|
}
|
2008-09-14 12:31:58 +00:00
|
|
|
nextrowset &= topline[c];
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-09-14 17:43:04 +00:00
|
|
|
// combine this row's bottom lines and next row's toplines if necessary
|
2008-09-18 16:29:27 +00:00
|
|
|
col_type nset = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2008-09-14 12:31:58 +00:00
|
|
|
if (!nextrowset)
|
|
|
|
bottomline[c] = bottomline[c] || topline[c];
|
|
|
|
if (bottomline[c])
|
|
|
|
++nset;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
2008-09-14 12:31:58 +00:00
|
|
|
|
2008-09-14 17:43:04 +00:00
|
|
|
// do nothing if empty, OR incomplete row line with a topline in next row
|
2010-03-05 18:10:34 +00:00
|
|
|
if (nset == 0 || (nextrowset && nset != ncols()))
|
2011-02-10 20:02:48 +00:00
|
|
|
return;
|
2008-09-14 12:31:58 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
if (nset == ncols()) {
|
2008-09-14 12:31:58 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
os << (lastrow ? "\\bottomrule" : "\\midrule");
|
|
|
|
else
|
2010-02-11 01:07:54 +00:00
|
|
|
os << "\\hline ";
|
2008-09-14 12:31:58 +00:00
|
|
|
} else {
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2010-10-05 01:14:34 +00:00
|
|
|
if (bottomline[c]) {
|
|
|
|
col_type offset = 0;
|
|
|
|
for (col_type j = 0 ; j < c; ++j)
|
|
|
|
if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
|
|
|
|
++offset;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
//babel makes the "-" character an active one, so we have to suppress this here
|
|
|
|
//see http://groups.google.com/group/comp.text.tex/browse_thread/thread/af769424a4a0f289#
|
|
|
|
if (lang == "slovak" || lang == "czech")
|
|
|
|
os << "\\expandafter" << (use_booktabs ? "\\cmidrule" : "\\cline")
|
|
|
|
<< "\\expandafter{\\expandafter" << c + 1 + offset << "\\string-";
|
|
|
|
else
|
|
|
|
os << (use_booktabs ? "\\cmidrule{" : "\\cline{") << c + 1 + offset << '-';
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
col_type cstart = c;
|
|
|
|
for ( ; c < ncols() && bottomline[c]; ++c) {}
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
for (col_type j = cstart ; j < c ; ++j)
|
|
|
|
if (column_info[j].alignment == LYX_ALIGN_DECIMAL)
|
|
|
|
++offset;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-05 01:14:34 +00:00
|
|
|
os << c + offset << "} ";
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
os << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void Tabular::TeXCellPreamble(otexstream & os, idx_type cell,
|
|
|
|
bool & ismulticol, bool & ismultirow) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-05-04 07:51:50 +00:00
|
|
|
row_type const r = cellRow(cell);
|
|
|
|
if (is_long_tabular && row_info[r].caption)
|
2011-02-10 20:02:48 +00:00
|
|
|
return;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
Tabular::VAlignment valign = getVAlignment(cell, !isMultiColumn(cell));
|
|
|
|
LyXAlignment align = getAlignment(cell, !isMultiColumn(cell));
|
2008-03-25 20:48:48 +00:00
|
|
|
// figure out how to set the lines
|
|
|
|
// we always set double lines to the right of the cell
|
|
|
|
col_type const c = cellColumn(cell);
|
|
|
|
col_type const nextcol = c + columnSpan(cell);
|
2008-04-24 17:26:17 +00:00
|
|
|
bool colright = columnRightLine(c);
|
|
|
|
bool colleft = columnLeftLine(c);
|
2010-03-05 18:10:34 +00:00
|
|
|
bool nextcolleft = nextcol < ncols() && columnLeftLine(nextcol);
|
2014-07-26 14:29:23 +00:00
|
|
|
bool nextcellleft = nextcol < ncols()
|
2008-03-28 12:00:53 +00:00
|
|
|
&& leftLine(cellIndex(r, nextcol));
|
2008-04-27 09:12:53 +00:00
|
|
|
bool coldouble = colright && nextcolleft;
|
|
|
|
bool celldouble = rightLine(cell) && nextcellleft;
|
2010-02-11 01:07:54 +00:00
|
|
|
|
|
|
|
ismulticol = isMultiColumn(cell)
|
2008-04-27 09:12:53 +00:00
|
|
|
|| (c == 0 && colleft != leftLine(cell))
|
|
|
|
|| ((colright || nextcolleft) && !rightLine(cell) && !nextcellleft)
|
|
|
|
|| (!colright && !nextcolleft && (rightLine(cell) || nextcellleft))
|
|
|
|
|| (coldouble != celldouble);
|
2010-06-05 07:44:44 +00:00
|
|
|
|
|
|
|
// we center in multicol when no decimal point
|
2011-05-09 12:33:32 +00:00
|
|
|
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);
|
|
|
|
ismulticol |= !dit;
|
|
|
|
}
|
2010-06-05 07:44:44 +00:00
|
|
|
|
|
|
|
// up counter by 1 for each decimally aligned col since they use 2 latex cols
|
|
|
|
int latexcolspan = columnSpan(cell);
|
|
|
|
for(col_type col = c; col < c + columnSpan(cell); ++col)
|
|
|
|
if (column_info[col].alignment == LYX_ALIGN_DECIMAL)
|
|
|
|
++latexcolspan;
|
|
|
|
|
2008-03-25 20:48:48 +00:00
|
|
|
if (ismulticol) {
|
2010-06-05 07:44:44 +00:00
|
|
|
os << "\\multicolumn{" << latexcolspan << "}{";
|
2008-07-04 13:18:28 +00:00
|
|
|
if (c ==0 && leftLine(cell))
|
2007-04-26 21:40:51 +00:00
|
|
|
os << '|';
|
2008-03-25 13:32:38 +00:00
|
|
|
if (!cellInfo(cell).align_special.empty()) {
|
|
|
|
os << cellInfo(cell).align_special;
|
2007-04-26 12:54:21 +00:00
|
|
|
} else {
|
|
|
|
if (!getPWidth(cell).zero()) {
|
2008-09-10 12:49:08 +00:00
|
|
|
switch (align) {
|
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
os << ">{\\raggedright}";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
os << ">{\\raggedleft}";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_CENTER:
|
|
|
|
os << ">{\\centering}";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2008-03-18 18:08:32 +00:00
|
|
|
switch (valign) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_VALIGN_TOP:
|
|
|
|
os << 'p';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_MIDDLE:
|
|
|
|
os << 'm';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_BOTTOM:
|
|
|
|
os << 'b';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
os << '{'
|
|
|
|
<< from_ascii(getPWidth(cell).asLatexString())
|
|
|
|
<< '}';
|
|
|
|
} else {
|
2008-03-18 18:08:32 +00:00
|
|
|
switch (align) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
os << 'l';
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
os << 'r';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
os << 'c';
|
|
|
|
break;
|
|
|
|
}
|
2007-04-26 21:40:51 +00:00
|
|
|
} // end if else !getPWidth
|
|
|
|
} // end if else !cellinfo_of_cell
|
2008-04-27 09:12:53 +00:00
|
|
|
if (rightLine(cell) || nextcellleft)
|
2008-03-25 20:48:48 +00:00
|
|
|
os << '|';
|
2008-04-24 17:26:17 +00:00
|
|
|
if (celldouble)
|
2008-03-25 20:48:48 +00:00
|
|
|
// add extra vertical line if we want a double one
|
2007-04-26 21:40:51 +00:00
|
|
|
os << '|';
|
|
|
|
os << "}{";
|
2010-06-05 07:44:44 +00:00
|
|
|
} // end if ismulticol
|
2010-02-11 01:07:54 +00:00
|
|
|
|
|
|
|
// we only need code for the first multirow cell
|
|
|
|
ismultirow = isMultiRow(cell);
|
|
|
|
if (ismultirow) {
|
|
|
|
os << "\\multirow{" << rowSpan(cell) << "}{";
|
|
|
|
if (!getPWidth(cell).zero())
|
|
|
|
os << from_ascii(getPWidth(cell).asLatexString());
|
|
|
|
else
|
|
|
|
// we need to set a default value
|
2010-03-14 10:33:02 +00:00
|
|
|
os << "*";
|
2010-11-07 05:32:28 +00:00
|
|
|
os << "}";
|
|
|
|
if (!getMROffset(cell).zero())
|
|
|
|
os << "[" << from_ascii(getMROffset(cell).asLatexString()) << "]";
|
|
|
|
os << "{";
|
2010-06-05 07:44:44 +00:00
|
|
|
} // end if ismultirow
|
2010-02-11 01:07:54 +00:00
|
|
|
|
2012-03-16 01:29:37 +00:00
|
|
|
if (getRotateCell(cell) != 0)
|
|
|
|
os << "\\begin{turn}{" << convert<string>(getRotateCell(cell)) << "}\n";
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
if (getUsebox(cell) == BOX_PARBOX) {
|
|
|
|
os << "\\parbox[";
|
2008-03-18 18:08:32 +00:00
|
|
|
switch (valign) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_VALIGN_TOP:
|
|
|
|
os << 't';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_MIDDLE:
|
|
|
|
os << 'c';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_BOTTOM:
|
|
|
|
os << 'b';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
os << "]{" << from_ascii(getPWidth(cell).asLatexString())
|
|
|
|
<< "}{";
|
|
|
|
} else if (getUsebox(cell) == BOX_MINIPAGE) {
|
|
|
|
os << "\\begin{minipage}[";
|
2008-03-18 18:08:32 +00:00
|
|
|
switch (valign) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_VALIGN_TOP:
|
|
|
|
os << 't';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_MIDDLE:
|
|
|
|
os << 'm';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_BOTTOM:
|
|
|
|
os << 'b';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
os << "]{" << from_ascii(getPWidth(cell).asLatexString())
|
|
|
|
<< "}\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void Tabular::TeXCellPostamble(otexstream & os, idx_type cell,
|
|
|
|
bool ismulticol, bool ismultirow) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-05-04 07:51:50 +00:00
|
|
|
row_type const r = cellRow(cell);
|
|
|
|
if (is_long_tabular && row_info[r].caption)
|
2011-02-10 20:02:48 +00:00
|
|
|
return;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
// usual cells
|
|
|
|
if (getUsebox(cell) == BOX_PARBOX)
|
|
|
|
os << '}';
|
2011-02-10 20:02:48 +00:00
|
|
|
else if (getUsebox(cell) == BOX_MINIPAGE)
|
|
|
|
os << breakln << "\\end{minipage}";
|
2012-03-16 01:29:37 +00:00
|
|
|
if (getRotateCell(cell) != 0)
|
|
|
|
os << breakln << "\\end{turn}";
|
2010-06-05 07:44:44 +00:00
|
|
|
if (ismultirow)
|
2008-03-31 12:09:24 +00:00
|
|
|
os << '}';
|
2010-06-05 07:44:44 +00:00
|
|
|
if (ismulticol)
|
|
|
|
os << '}';
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void Tabular::TeXLongtableHeaderFooter(otexstream & os,
|
|
|
|
OutputParams const & runparams) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
if (!is_long_tabular)
|
2011-02-10 20:02:48 +00:00
|
|
|
return;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2014-01-25 08:32:57 +00:00
|
|
|
// caption handling
|
2014-02-23 09:55:23 +00:00
|
|
|
// output caption which is in no header or footer
|
2014-01-25 08:32:57 +00:00
|
|
|
if (haveLTCaption()) {
|
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2014-02-23 09:55:23 +00:00
|
|
|
if (row_info[r].caption &&
|
|
|
|
!row_info[r].endfirsthead && !row_info[r].endhead &&
|
|
|
|
!row_info[r].endfoot && !row_info[r].endlastfoot)
|
2014-01-25 08:32:57 +00:00
|
|
|
TeXRow(os, r, runparams);
|
|
|
|
}
|
|
|
|
}
|
2009-02-12 02:23:48 +00:00
|
|
|
// output first header info
|
|
|
|
if (haveLTFirstHead()) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endfirsthead.topDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (row_info[r].endfirsthead)
|
|
|
|
TeXRow(os, r, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endfirsthead.bottomDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
2009-02-12 02:23:48 +00:00
|
|
|
os << "\\endfirsthead\n";
|
|
|
|
}
|
|
|
|
// output header info
|
|
|
|
if (haveLTHead()) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endfirsthead.empty && !haveLTFirstHead())
|
2009-02-13 23:48:19 +00:00
|
|
|
os << "\\endfirsthead\n";
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endhead.topDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (row_info[r].endhead)
|
|
|
|
TeXRow(os, r, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endhead.bottomDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
2009-02-12 02:23:48 +00:00
|
|
|
os << "\\endhead\n";
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
// output footer info
|
|
|
|
if (haveLTFoot()) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endfoot.topDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (row_info[r].endfoot)
|
|
|
|
TeXRow(os, r, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endfoot.bottomDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
|
|
|
os << "\\endfoot\n";
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endlastfoot.empty && !haveLTLastFoot())
|
2009-02-13 23:48:19 +00:00
|
|
|
os << "\\endlastfoot\n";
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
// output lastfooter info
|
|
|
|
if (haveLTLastFoot()) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endlastfoot.topDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-02-10 20:02:48 +00:00
|
|
|
if (row_info[r].endlastfoot)
|
|
|
|
TeXRow(os, r, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
2011-02-10 20:02:48 +00:00
|
|
|
if (endlastfoot.bottomDL)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\hline\n";
|
|
|
|
os << "\\endlastfoot\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool Tabular::isValidRow(row_type row) const
|
|
|
|
{
|
|
|
|
if (!is_long_tabular)
|
|
|
|
return true;
|
2009-02-12 02:23:48 +00:00
|
|
|
return !row_info[row].endhead && !row_info[row].endfirsthead
|
|
|
|
&& !row_info[row].endfoot && !row_info[row].endlastfoot
|
|
|
|
&& !row_info[row].caption;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void Tabular::TeXRow(otexstream & os, row_type row,
|
|
|
|
OutputParams const & runparams) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2010-03-05 18:10:34 +00:00
|
|
|
idx_type cell = cellIndex(row, 0);
|
2008-09-26 21:24:59 +00:00
|
|
|
shared_ptr<InsetTableCell> inset = cellInset(cell);
|
|
|
|
Paragraph const & par = inset->paragraphs().front();
|
2008-09-27 15:32:43 +00:00
|
|
|
string const lang = par.getParLanguage(buffer().params())->lang();
|
2008-09-26 21:24:59 +00:00
|
|
|
|
|
|
|
//output the top line
|
2011-02-10 20:02:48 +00:00
|
|
|
TeXTopHLine(os, row, lang);
|
2008-09-26 21:24:59 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row_info[row].top_space_default) {
|
2007-04-26 12:54:21 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
os << "\\addlinespace\n";
|
|
|
|
else
|
|
|
|
os << "\\noalign{\\vskip\\doublerulesep}\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
} else if(!row_info[row].top_space.zero()) {
|
2007-04-26 12:54:21 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
os << "\\addlinespace["
|
2010-03-05 18:10:34 +00:00
|
|
|
<< from_ascii(row_info[row].top_space.asLatexString())
|
2007-04-26 12:54:21 +00:00
|
|
|
<< "]\n";
|
|
|
|
else {
|
|
|
|
os << "\\noalign{\\vskip"
|
2010-03-05 18:10:34 +00:00
|
|
|
<< from_ascii(row_info[row].top_space.asLatexString())
|
2007-04-26 12:54:21 +00:00
|
|
|
<< "}\n";
|
|
|
|
}
|
|
|
|
}
|
2008-03-25 20:48:48 +00:00
|
|
|
bool ismulticol = false;
|
2010-02-11 01:07:54 +00:00
|
|
|
bool ismultirow = false;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2010-06-05 07:44:44 +00:00
|
|
|
if (isPartOfMultiColumn(row, c))
|
|
|
|
continue;
|
2011-02-17 10:42:13 +00:00
|
|
|
|
|
|
|
cell = cellIndex(row, c);
|
|
|
|
|
|
|
|
if (isPartOfMultiRow(row, c)
|
|
|
|
&& column_info[c].alignment != LYX_ALIGN_DECIMAL) {
|
|
|
|
if (cell != getLastCellInRow(row))
|
2014-07-26 14:29:23 +00:00
|
|
|
os << " & ";
|
2007-04-26 12:54:21 +00:00
|
|
|
continue;
|
2010-06-05 07:44:44 +00:00
|
|
|
}
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
TeXCellPreamble(os, cell, ismulticol, ismultirow);
|
2008-03-25 13:32:38 +00:00
|
|
|
shared_ptr<InsetTableCell> inset = cellInset(cell);
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
Paragraph const & par = inset->paragraphs().front();
|
2008-02-27 20:43:16 +00:00
|
|
|
bool rtl = par.isRTL(buffer().params())
|
2007-04-26 12:54:21 +00:00
|
|
|
&& !par.empty()
|
2012-07-23 06:40:37 +00:00
|
|
|
&& getPWidth(cell).zero()
|
|
|
|
&& !runparams.use_polyglossia;
|
2007-04-26 12:54:21 +00:00
|
|
|
|
2007-05-31 18:53:01 +00:00
|
|
|
if (rtl) {
|
2008-09-10 16:02:32 +00:00
|
|
|
string const lang =
|
|
|
|
par.getParLanguage(buffer().params())->lang();
|
|
|
|
if (lang == "farsi")
|
2007-05-31 18:53:01 +00:00
|
|
|
os << "\\textFR{";
|
2008-09-10 16:02:32 +00:00
|
|
|
else if (lang == "arabic_arabi")
|
2007-06-26 00:11:03 +00:00
|
|
|
os << "\\textAR{";
|
2011-12-18 21:27:17 +00:00
|
|
|
// currently, remaining RTL languages are
|
2008-09-10 16:02:32 +00:00
|
|
|
// arabic_arabtex and hebrew
|
2007-05-31 18:53:01 +00:00
|
|
|
else
|
|
|
|
os << "\\R{";
|
|
|
|
}
|
2008-09-10 16:02:32 +00:00
|
|
|
// pass to the OutputParams that we are in a cell and
|
|
|
|
// which alignment we have set.
|
|
|
|
// InsetNewline needs this context information.
|
2008-09-27 15:32:43 +00:00
|
|
|
OutputParams newrp(runparams);
|
2008-09-10 16:02:32 +00:00
|
|
|
newrp.inTableCell = (getAlignment(cell) == LYX_ALIGN_BLOCK)
|
|
|
|
? OutputParams::PLAIN
|
|
|
|
: OutputParams::ALIGNED;
|
2010-06-05 07:44:44 +00:00
|
|
|
|
2011-05-09 12:33:32 +00:00
|
|
|
if (getAlignment(cell) == LYX_ALIGN_DECIMAL) {
|
2010-06-05 07:44:44 +00:00
|
|
|
// copy cell and split in 2
|
|
|
|
InsetTableCell head = InsetTableCell(*cellInset(cell).get());
|
|
|
|
head.setBuffer(buffer());
|
2011-04-25 12:56:09 +00:00
|
|
|
DocIterator dit = cellInset(cell)->getText(0)->macrocontextPosition();
|
|
|
|
dit.pop_back();
|
|
|
|
dit.push_back(CursorSlice(head));
|
|
|
|
head.setMacrocontextPositionRecursive(dit);
|
2010-06-05 07:44:44 +00:00
|
|
|
bool hassep = false;
|
|
|
|
InsetTableCell tail = splitCell(head, column_info[c].decimal_point, hassep);
|
|
|
|
head.latex(os, newrp);
|
2011-05-09 12:33:32 +00:00
|
|
|
if (hassep) {
|
|
|
|
os << '&';
|
|
|
|
tail.setBuffer(head.buffer());
|
|
|
|
dit.pop_back();
|
|
|
|
dit.push_back(CursorSlice(tail));
|
|
|
|
tail.setMacrocontextPositionRecursive(dit);
|
|
|
|
tail.latex(os, newrp);
|
|
|
|
}
|
2011-02-14 01:02:12 +00:00
|
|
|
} else if (!isPartOfMultiRow(row, c)) {
|
|
|
|
if (!runparams.nice)
|
|
|
|
os.texrow().start(par.id(), 0);
|
2011-02-10 20:02:48 +00:00
|
|
|
inset->latex(os, newrp);
|
2011-02-14 01:02:12 +00:00
|
|
|
}
|
2010-06-05 07:44:44 +00:00
|
|
|
|
2008-09-27 15:32:43 +00:00
|
|
|
runparams.encoding = newrp.encoding;
|
2007-04-26 12:54:21 +00:00
|
|
|
if (rtl)
|
|
|
|
os << '}';
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
TeXCellPostamble(os, cell, ismulticol, ismultirow);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (cell != getLastCellInRow(row)) { // not last cell in row
|
2011-02-14 01:02:12 +00:00
|
|
|
if (runparams.nice)
|
|
|
|
os << " & ";
|
|
|
|
else
|
|
|
|
os << " &\n";
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-12-18 21:27:17 +00:00
|
|
|
os << "\\tabularnewline";
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row_info[row].bottom_space_default) {
|
2007-04-26 12:54:21 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
os << "\\addlinespace";
|
|
|
|
else
|
|
|
|
os << "[\\doublerulesep]";
|
2010-03-05 18:10:34 +00:00
|
|
|
} else if (!row_info[row].bottom_space.zero()) {
|
2007-04-26 12:54:21 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
os << "\\addlinespace";
|
|
|
|
os << '['
|
2010-03-05 18:10:34 +00:00
|
|
|
<< from_ascii(row_info[row].bottom_space.asLatexString())
|
2007-04-26 12:54:21 +00:00
|
|
|
<< ']';
|
|
|
|
}
|
|
|
|
os << '\n';
|
2008-09-26 21:24:59 +00:00
|
|
|
|
|
|
|
//output the bottom line
|
2011-02-10 20:02:48 +00:00
|
|
|
TeXBottomHLine(os, row, lang);
|
2008-09-26 21:24:59 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row_info[row].interline_space_default) {
|
2007-04-26 12:54:21 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
os << "\\addlinespace\n";
|
|
|
|
else
|
|
|
|
os << "\\noalign{\\vskip\\doublerulesep}\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
} else if (!row_info[row].interline_space.zero()) {
|
2007-04-26 12:54:21 +00:00
|
|
|
if (use_booktabs)
|
|
|
|
os << "\\addlinespace["
|
2010-03-05 18:10:34 +00:00
|
|
|
<< from_ascii(row_info[row].interline_space.asLatexString())
|
2007-04-26 12:54:21 +00:00
|
|
|
<< "]\n";
|
|
|
|
else
|
|
|
|
os << "\\noalign{\\vskip"
|
2010-03-05 18:10:34 +00:00
|
|
|
<< from_ascii(row_info[row].interline_space.asLatexString())
|
2007-04-26 12:54:21 +00:00
|
|
|
<< "}\n";
|
|
|
|
}
|
|
|
|
}
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2001-12-18 03:21:10 +00:00
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void Tabular::latex(otexstream & os, OutputParams const & runparams) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2011-02-03 23:11:26 +00:00
|
|
|
bool const is_tabular_star = !tabular_width.zero();
|
2005-01-27 21:05:44 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
//+ first the opening preamble +
|
|
|
|
//+---------------------------------------------------------------------
|
2001-12-18 03:21:10 +00:00
|
|
|
|
2011-03-12 01:40:01 +00:00
|
|
|
os << safebreakln;
|
|
|
|
if (runparams.lastid != -1)
|
|
|
|
os.texrow().start(runparams.lastid, runparams.lastpos);
|
|
|
|
|
2012-03-19 00:21:26 +00:00
|
|
|
if (rotate != 0)
|
2012-03-21 22:04:45 +00:00
|
|
|
os << "\\begin{turn}{" << convert<string>(rotate) << "}\n";
|
2011-02-10 20:02:48 +00:00
|
|
|
|
2009-07-11 13:09:45 +00:00
|
|
|
if (is_long_tabular) {
|
2009-01-03 18:33:09 +00:00
|
|
|
os << "\\begin{longtable}";
|
2009-07-11 13:09:45 +00:00
|
|
|
switch (longtabular_alignment) {
|
|
|
|
case LYX_LONGTABULAR_ALIGN_LEFT:
|
|
|
|
os << "[l]";
|
|
|
|
break;
|
|
|
|
case LYX_LONGTABULAR_ALIGN_CENTER:
|
|
|
|
break;
|
|
|
|
case LYX_LONGTABULAR_ALIGN_RIGHT:
|
|
|
|
os << "[r]";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
2011-02-03 23:11:26 +00:00
|
|
|
if (is_tabular_star)
|
|
|
|
os << "\\begin{tabular*}{" << from_ascii(tabular_width.asLatexString()) << "}";
|
|
|
|
else
|
|
|
|
os << "\\begin{tabular}";
|
2009-07-11 13:09:45 +00:00
|
|
|
switch (tabular_valignment) {
|
2009-01-03 18:33:09 +00:00
|
|
|
case LYX_VALIGN_TOP:
|
|
|
|
os << "[t]";
|
|
|
|
break;
|
2009-07-11 13:09:45 +00:00
|
|
|
case LYX_VALIGN_MIDDLE:
|
|
|
|
break;
|
2009-01-03 18:33:09 +00:00
|
|
|
case LYX_VALIGN_BOTTOM:
|
|
|
|
os << "[b]";
|
|
|
|
break;
|
2009-07-11 13:09:45 +00:00
|
|
|
}
|
2009-01-03 18:33:09 +00:00
|
|
|
}
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2009-01-03 18:33:09 +00:00
|
|
|
os << "{";
|
2008-03-18 18:08:32 +00:00
|
|
|
|
2011-02-03 23:11:26 +00:00
|
|
|
if (is_tabular_star)
|
|
|
|
os << "@{\\extracolsep{\\fill}}";
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
if (columnLeftLine(c))
|
2007-04-26 21:40:51 +00:00
|
|
|
os << '|';
|
2010-03-05 18:10:34 +00:00
|
|
|
if (!column_info[c].align_special.empty()) {
|
|
|
|
os << column_info[c].align_special;
|
2007-04-26 12:54:21 +00:00
|
|
|
} else {
|
2010-03-05 18:10:34 +00:00
|
|
|
if (!column_info[c].p_width.zero()) {
|
|
|
|
switch (column_info[c].alignment) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
os << ">{\\raggedright}";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
os << ">{\\raggedleft}";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_CENTER:
|
|
|
|
os << ">{\\centering}";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_NONE:
|
|
|
|
case LYX_ALIGN_BLOCK:
|
|
|
|
case LYX_ALIGN_LAYOUT:
|
|
|
|
case LYX_ALIGN_SPECIAL:
|
2010-06-05 07:44:44 +00:00
|
|
|
case LYX_ALIGN_DECIMAL:
|
2007-04-26 12:54:21 +00:00
|
|
|
break;
|
|
|
|
}
|
2002-02-16 15:59:55 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
switch (column_info[c].valignment) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_VALIGN_TOP:
|
|
|
|
os << 'p';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_MIDDLE:
|
|
|
|
os << 'm';
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_BOTTOM:
|
|
|
|
os << 'b';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
os << '{'
|
2010-03-05 18:10:34 +00:00
|
|
|
<< from_ascii(column_info[c].p_width.asLatexString())
|
2007-04-26 12:54:21 +00:00
|
|
|
<< '}';
|
|
|
|
} else {
|
2010-03-05 18:10:34 +00:00
|
|
|
switch (column_info[c].alignment) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
os << 'l';
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
os << 'r';
|
|
|
|
break;
|
2010-06-05 07:44:44 +00:00
|
|
|
case LYX_ALIGN_DECIMAL:
|
|
|
|
os << "r@{\\extracolsep{0pt}" << column_info[c].decimal_point << "}l";
|
|
|
|
break;
|
2007-04-26 12:54:21 +00:00
|
|
|
default:
|
|
|
|
os << 'c';
|
|
|
|
break;
|
|
|
|
}
|
2007-04-26 21:40:51 +00:00
|
|
|
} // end if else !column_info[i].p_width
|
|
|
|
} // end if else !column_info[i].align_special
|
2010-03-05 18:10:34 +00:00
|
|
|
if (columnRightLine(c))
|
2007-04-26 21:40:51 +00:00
|
|
|
os << '|';
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
os << "}\n";
|
2006-09-03 07:02:38 +00:00
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
TeXLongtableHeaderFooter(os, runparams);
|
2005-09-06 17:39:39 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
//+ the single row and columns (cells) +
|
|
|
|
//+---------------------------------------------------------------------
|
2003-09-09 22:13:45 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
if (isValidRow(r)) {
|
2011-02-10 20:02:48 +00:00
|
|
|
TeXRow(os, r, runparams);
|
|
|
|
if (is_long_tabular && row_info[r].newpage)
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\\newpage\n";
|
|
|
|
}
|
|
|
|
}
|
2003-06-30 23:56:22 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
//+ the closing of the tabular +
|
|
|
|
//+---------------------------------------------------------------------
|
2006-10-21 00:16:43 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
if (is_long_tabular)
|
|
|
|
os << "\\end{longtable}";
|
2011-02-10 20:02:48 +00:00
|
|
|
else {
|
2011-02-03 23:11:26 +00:00
|
|
|
if (is_tabular_star)
|
|
|
|
os << "\\end{tabular*}";
|
|
|
|
else
|
|
|
|
os << "\\end{tabular}";
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
2006-06-20 08:39:16 +00:00
|
|
|
|
2012-03-19 00:21:26 +00:00
|
|
|
if (rotate != 0)
|
|
|
|
os << breakln << "\\end{turn}";
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
2004-11-23 23:04:52 +00:00
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
int Tabular::docbookRow(odocstream & os, row_type row,
|
2007-04-26 12:54:21 +00:00
|
|
|
OutputParams const & runparams) const
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
idx_type cell = getFirstCellInRow(row);
|
2006-10-07 16:47:54 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "<row>\n";
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
if (isPartOfMultiColumn(row, c))
|
2007-04-26 12:54:21 +00:00
|
|
|
continue;
|
2003-07-04 08:23:23 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "<entry align=\"";
|
|
|
|
switch (getAlignment(cell)) {
|
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
os << "left";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
os << "right";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
os << "center";
|
|
|
|
break;
|
|
|
|
}
|
2001-03-20 01:22:46 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "\" valign=\"";
|
|
|
|
switch (getVAlignment(cell)) {
|
|
|
|
case LYX_VALIGN_TOP:
|
|
|
|
os << "top";
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_BOTTOM:
|
|
|
|
os << "bottom";
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_MIDDLE:
|
|
|
|
os << "middle";
|
|
|
|
}
|
|
|
|
os << '"';
|
2001-12-18 03:21:10 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
if (isMultiColumn(cell)) {
|
2010-03-05 18:10:34 +00:00
|
|
|
os << " namest=\"col" << c << "\" ";
|
|
|
|
os << "nameend=\"col" << c + columnSpan(cell) - 1 << '"';
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
os << '>';
|
2008-03-25 13:32:38 +00:00
|
|
|
ret += cellInset(cell)->docbook(os, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "</entry>\n";
|
|
|
|
++cell;
|
|
|
|
}
|
|
|
|
os << "</row>\n";
|
|
|
|
return ret;
|
|
|
|
}
|
2001-03-20 01:22:46 +00:00
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
int Tabular::docbook(odocstream & os, OutputParams const & runparams) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
int ret = 0;
|
2000-07-28 14:28:54 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
//+ first the opening preamble +
|
|
|
|
//+---------------------------------------------------------------------
|
2000-07-28 14:28:54 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
os << "<tgroup cols=\"" << ncols()
|
2007-04-26 12:54:21 +00:00
|
|
|
<< "\" colsep=\"1\" rowsep=\"1\">\n";
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
os << "<colspec colname=\"col" << c << "\" align=\"";
|
|
|
|
switch (column_info[c].alignment) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
os << "left";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
os << "right";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
os << "center";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
os << '"';
|
|
|
|
if (runparams.flavor == OutputParams::XML)
|
|
|
|
os << '/';
|
|
|
|
os << ">\n";
|
|
|
|
++ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
//+ Long Tabular case +
|
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
|
2009-02-12 02:37:14 +00:00
|
|
|
// output caption info
|
2011-12-18 21:27:17 +00:00
|
|
|
// The caption flag wins over head/foot
|
2009-02-12 02:37:14 +00:00
|
|
|
if (haveLTCaption()) {
|
|
|
|
os << "<caption>\n";
|
|
|
|
++ret;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
if (row_info[r].caption) {
|
|
|
|
ret += docbookRow(os, r, runparams);
|
2009-02-12 02:37:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
os << "</caption>\n";
|
|
|
|
++ret;
|
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
// output header info
|
2011-12-18 21:27:17 +00:00
|
|
|
if (haveLTHead(false) || haveLTFirstHead(false)) {
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "<thead>\n";
|
|
|
|
++ret;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-12-18 21:27:17 +00:00
|
|
|
if ((row_info[r].endhead || row_info[r].endfirsthead) &&
|
|
|
|
!row_info[r].caption) {
|
2010-03-05 18:10:34 +00:00
|
|
|
ret += docbookRow(os, r, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
os << "</thead>\n";
|
|
|
|
++ret;
|
|
|
|
}
|
|
|
|
// output footer info
|
2011-12-18 21:27:17 +00:00
|
|
|
if (haveLTFoot(false) || haveLTLastFoot(false)) {
|
2007-04-26 12:54:21 +00:00
|
|
|
os << "<tfoot>\n";
|
|
|
|
++ret;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-12-18 21:27:17 +00:00
|
|
|
if ((row_info[r].endfoot || row_info[r].endlastfoot) &&
|
|
|
|
!row_info[r].caption) {
|
2010-03-05 18:10:34 +00:00
|
|
|
ret += docbookRow(os, r, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
os << "</tfoot>\n";
|
|
|
|
++ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
//+ the single row and columns (cells) +
|
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
|
|
|
|
os << "<tbody>\n";
|
|
|
|
++ret;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
if (isValidRow(r)) {
|
|
|
|
ret += docbookRow(os, r, runparams);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
os << "</tbody>\n";
|
|
|
|
++ret;
|
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
//+ the closing of the tabular +
|
|
|
|
//+---------------------------------------------------------------------
|
|
|
|
|
|
|
|
os << "</tgroup>";
|
|
|
|
++ret;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-14 15:39:13 +00:00
|
|
|
docstring Tabular::xhtmlRow(XHTMLStream & xs, row_type row,
|
2011-01-13 21:04:52 +00:00
|
|
|
OutputParams const & runparams, bool header) const
|
2009-12-14 15:39:13 +00:00
|
|
|
{
|
|
|
|
docstring ret;
|
2011-01-13 21:04:52 +00:00
|
|
|
string const celltag = header ? "th" : "td";
|
2009-12-14 15:39:13 +00:00
|
|
|
idx_type cell = getFirstCellInRow(row);
|
|
|
|
|
2010-01-19 22:08:04 +00:00
|
|
|
xs << html::StartTag("tr");
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2011-05-11 14:20:24 +00:00
|
|
|
if (isPartOfMultiColumn(row, c) || isPartOfMultiRow(row, c))
|
2009-12-14 15:39:13 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
stringstream attr;
|
|
|
|
attr << "align='";
|
|
|
|
switch (getAlignment(cell)) {
|
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
attr << "left";
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
attr << "right";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
attr << "center";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
attr << "'";
|
|
|
|
attr << " valign='";
|
|
|
|
switch (getVAlignment(cell)) {
|
|
|
|
case LYX_VALIGN_TOP:
|
|
|
|
attr << "top";
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_BOTTOM:
|
|
|
|
attr << "bottom";
|
|
|
|
break;
|
|
|
|
case LYX_VALIGN_MIDDLE:
|
|
|
|
attr << "middle";
|
|
|
|
}
|
|
|
|
attr << "'";
|
|
|
|
|
|
|
|
if (isMultiColumn(cell))
|
2009-12-14 15:44:49 +00:00
|
|
|
attr << " colspan='" << columnSpan(cell) << "'";
|
2011-05-11 14:20:24 +00:00
|
|
|
else if (isMultiRow(cell))
|
|
|
|
attr << " rowspan='" << rowSpan(cell) << "'";
|
2009-12-14 15:39:13 +00:00
|
|
|
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::StartTag(celltag, attr.str()) << html::CR();
|
2009-12-14 15:39:13 +00:00
|
|
|
ret += cellInset(cell)->xhtml(xs, runparams);
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::EndTag(celltag) << html::CR();
|
2009-12-14 15:39:13 +00:00
|
|
|
++cell;
|
|
|
|
}
|
2010-01-19 22:08:04 +00:00
|
|
|
xs << html::EndTag("tr");
|
2009-12-14 15:39:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
docstring Tabular::xhtml(XHTMLStream & xs, OutputParams const & runparams) const
|
|
|
|
{
|
|
|
|
docstring ret;
|
2011-01-13 21:04:52 +00:00
|
|
|
|
|
|
|
if (is_long_tabular) {
|
|
|
|
// we'll wrap it in a div, so as to deal with alignment
|
|
|
|
string align;
|
|
|
|
switch (longtabular_alignment) {
|
|
|
|
case LYX_LONGTABULAR_ALIGN_LEFT:
|
|
|
|
align = "left";
|
|
|
|
break;
|
|
|
|
case LYX_LONGTABULAR_ALIGN_CENTER:
|
|
|
|
align = "center";
|
|
|
|
break;
|
|
|
|
case LYX_LONGTABULAR_ALIGN_RIGHT:
|
|
|
|
align = "right";
|
|
|
|
break;
|
|
|
|
}
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::StartTag("div", "class='longtable' style='text-align: " + align + ";'")
|
|
|
|
<< html::CR();
|
2011-12-18 21:27:17 +00:00
|
|
|
// The caption flag wins over head/foot
|
2011-01-13 21:04:52 +00:00
|
|
|
if (haveLTCaption()) {
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::StartTag("div", "class='longtable-caption' style='text-align: " + align + ";'")
|
|
|
|
<< html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r)
|
|
|
|
if (row_info[r].caption)
|
|
|
|
ret += xhtmlRow(xs, r, runparams);
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::EndTag("div") << html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::StartTag("table") << html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
|
|
|
|
// output header info
|
2011-12-18 21:27:17 +00:00
|
|
|
bool const havefirsthead = haveLTFirstHead(false);
|
2011-01-13 21:04:52 +00:00
|
|
|
// if we have a first head, then we are going to ignore the
|
|
|
|
// headers for the additional pages, since there aren't any
|
|
|
|
// in XHTML. this test accomplishes that.
|
2011-12-18 21:27:17 +00:00
|
|
|
bool const havehead = !havefirsthead && haveLTHead(false);
|
2011-01-13 21:04:52 +00:00
|
|
|
if (havehead || havefirsthead) {
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::StartTag("thead") << html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-12-18 21:27:17 +00:00
|
|
|
if (((havefirsthead && row_info[r].endfirsthead) ||
|
|
|
|
(havehead && row_info[r].endhead)) &&
|
|
|
|
!row_info[r].caption) {
|
2011-01-13 21:04:52 +00:00
|
|
|
ret += xhtmlRow(xs, r, runparams, true);
|
|
|
|
}
|
|
|
|
}
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::EndTag("thead") << html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
}
|
|
|
|
// output footer info
|
2011-12-18 21:27:17 +00:00
|
|
|
bool const havelastfoot = haveLTLastFoot(false);
|
2011-01-13 21:04:52 +00:00
|
|
|
// as before.
|
2011-12-18 21:27:17 +00:00
|
|
|
bool const havefoot = !havelastfoot && haveLTFoot(false);
|
2011-01-13 21:04:52 +00:00
|
|
|
if (havefoot || havelastfoot) {
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::StartTag("tfoot") << html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
2011-12-18 21:27:17 +00:00
|
|
|
if (((havelastfoot && row_info[r].endlastfoot) ||
|
|
|
|
(havefoot && row_info[r].endfoot)) &&
|
|
|
|
!row_info[r].caption) {
|
2011-01-13 21:04:52 +00:00
|
|
|
ret += xhtmlRow(xs, r, runparams);
|
|
|
|
}
|
|
|
|
}
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::EndTag("tfoot") << html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
}
|
2009-12-14 15:39:13 +00:00
|
|
|
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::StartTag("tbody") << html::CR();
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
if (isValidRow(r)) {
|
|
|
|
ret += xhtmlRow(xs, r, runparams);
|
2009-12-14 15:39:13 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-13 21:04:52 +00:00
|
|
|
xs << html::EndTag("tbody")
|
2011-04-01 19:18:25 +00:00
|
|
|
<< html::CR()
|
|
|
|
<< html::EndTag("table")
|
|
|
|
<< html::CR();
|
2011-01-13 21:04:52 +00:00
|
|
|
if (is_long_tabular)
|
2011-04-01 19:18:25 +00:00
|
|
|
xs << html::EndTag("div") << html::CR();
|
2009-12-14 15:39:13 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
bool Tabular::plaintextTopHLine(odocstringstream & os, row_type row,
|
2007-05-28 22:27:45 +00:00
|
|
|
vector<unsigned int> const & clen) const
|
2000-07-28 14:28:54 +00:00
|
|
|
{
|
2007-04-26 12:54:21 +00:00
|
|
|
idx_type const fcell = getFirstCellInRow(row);
|
2010-02-12 18:36:20 +00:00
|
|
|
idx_type const n = numberOfCellsInRow(row) + fcell;
|
2007-04-26 12:54:21 +00:00
|
|
|
idx_type tmp = 0;
|
2000-07-28 14:28:54 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
for (idx_type i = fcell; i < n; ++i) {
|
|
|
|
if (topLine(i)) {
|
|
|
|
++tmp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!tmp)
|
|
|
|
return false;
|
2004-01-05 17:33:57 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
char_type ch;
|
|
|
|
for (idx_type i = fcell; i < n; ++i) {
|
|
|
|
if (topLine(i)) {
|
|
|
|
if (leftLine(i))
|
|
|
|
os << "+-";
|
|
|
|
else
|
|
|
|
os << "--";
|
|
|
|
ch = '-';
|
|
|
|
} else {
|
|
|
|
os << " ";
|
|
|
|
ch = ' ';
|
|
|
|
}
|
2007-09-04 10:52:08 +00:00
|
|
|
col_type column = cellColumn(i);
|
2007-04-26 12:54:21 +00:00
|
|
|
int len = clen[column];
|
2010-03-05 18:10:34 +00:00
|
|
|
while (column < ncols() - 1
|
2007-04-26 12:54:21 +00:00
|
|
|
&& isPartOfMultiColumn(row, ++column))
|
|
|
|
len += clen[column] + 4;
|
|
|
|
os << docstring(len, ch);
|
|
|
|
if (topLine(i)) {
|
|
|
|
if (rightLine(i))
|
|
|
|
os << "-+";
|
|
|
|
else
|
|
|
|
os << "--";
|
|
|
|
} else {
|
|
|
|
os << " ";
|
|
|
|
}
|
2003-03-09 18:11:57 +00:00
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
os << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
bool Tabular::plaintextBottomHLine(odocstringstream & os, row_type row,
|
2007-05-28 22:27:45 +00:00
|
|
|
vector<unsigned int> const & clen) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
idx_type const fcell = getFirstCellInRow(row);
|
2010-02-12 18:36:20 +00:00
|
|
|
idx_type const n = numberOfCellsInRow(row) + fcell;
|
2007-04-26 12:54:21 +00:00
|
|
|
idx_type tmp = 0;
|
2003-03-09 18:11:57 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
for (idx_type i = fcell; i < n; ++i) {
|
|
|
|
if (bottomLine(i)) {
|
|
|
|
++tmp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!tmp)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
char_type ch;
|
|
|
|
for (idx_type i = fcell; i < n; ++i) {
|
|
|
|
if (bottomLine(i)) {
|
|
|
|
if (leftLine(i))
|
|
|
|
os << "+-";
|
|
|
|
else
|
|
|
|
os << "--";
|
|
|
|
ch = '-';
|
|
|
|
} else {
|
|
|
|
os << " ";
|
|
|
|
ch = ' ';
|
|
|
|
}
|
2007-09-04 10:52:08 +00:00
|
|
|
col_type column = cellColumn(i);
|
2007-04-26 12:54:21 +00:00
|
|
|
int len = clen[column];
|
2010-03-05 18:10:34 +00:00
|
|
|
while (column < ncols() - 1 && isPartOfMultiColumn(row, ++column))
|
2007-04-26 12:54:21 +00:00
|
|
|
len += clen[column] + 4;
|
|
|
|
os << docstring(len, ch);
|
|
|
|
if (bottomLine(i)) {
|
|
|
|
if (rightLine(i))
|
|
|
|
os << "-+";
|
|
|
|
else
|
|
|
|
os << "--";
|
|
|
|
} else {
|
|
|
|
os << " ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
os << endl;
|
|
|
|
return true;
|
|
|
|
}
|
2001-03-20 01:22:46 +00:00
|
|
|
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
void Tabular::plaintextPrintCell(odocstringstream & os,
|
2007-04-26 12:54:21 +00:00
|
|
|
OutputParams const & runparams,
|
|
|
|
idx_type cell, row_type row, col_type column,
|
|
|
|
vector<unsigned int> const & clen,
|
2013-03-08 19:52:18 +00:00
|
|
|
bool onlydata, size_t max_length) const
|
2003-03-09 18:11:57 +00:00
|
|
|
{
|
2007-04-26 12:54:21 +00:00
|
|
|
odocstringstream sstr;
|
2013-03-08 19:52:18 +00:00
|
|
|
cellInset(cell)->plaintext(sstr, runparams, max_length);
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
if (onlydata) {
|
|
|
|
os << sstr.str();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (leftLine(cell))
|
|
|
|
os << "| ";
|
|
|
|
else
|
|
|
|
os << " ";
|
|
|
|
|
|
|
|
unsigned int len1 = sstr.str().length();
|
|
|
|
unsigned int len2 = clen[column];
|
2010-03-05 18:10:34 +00:00
|
|
|
while (column < ncols() - 1 && isPartOfMultiColumn(row, ++column))
|
2007-04-26 12:54:21 +00:00
|
|
|
len2 += clen[column] + 4;
|
|
|
|
len2 -= len1;
|
|
|
|
|
|
|
|
switch (getAlignment(cell)) {
|
|
|
|
default:
|
|
|
|
case LYX_ALIGN_LEFT:
|
|
|
|
len1 = 0;
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_RIGHT:
|
|
|
|
len1 = len2;
|
|
|
|
len2 = 0;
|
|
|
|
break;
|
|
|
|
case LYX_ALIGN_CENTER:
|
|
|
|
len1 = len2 / 2;
|
|
|
|
len2 -= len1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
os << docstring(len1, ' ') << sstr.str()
|
|
|
|
<< docstring(len2, ' ');
|
|
|
|
|
|
|
|
if (rightLine(cell))
|
|
|
|
os << " |";
|
|
|
|
else
|
|
|
|
os << " ";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
void Tabular::plaintext(odocstringstream & os,
|
2007-05-28 22:27:45 +00:00
|
|
|
OutputParams const & runparams, int const depth,
|
2013-03-08 19:52:18 +00:00
|
|
|
bool onlydata, char_type delim, size_t max_length) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
|
|
|
// first calculate the width of the single columns
|
2010-03-05 18:10:34 +00:00
|
|
|
vector<unsigned int> clen(ncols());
|
2007-04-26 12:54:21 +00:00
|
|
|
|
|
|
|
if (!onlydata) {
|
2010-03-04 21:31:06 +00:00
|
|
|
// first all non multicolumn cells!
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
clen[c] = 0;
|
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
idx_type cell = cellIndex(r, c);
|
2010-03-04 21:31:06 +00:00
|
|
|
if (isMultiColumn(cell))
|
2007-04-26 12:54:21 +00:00
|
|
|
continue;
|
|
|
|
odocstringstream sstr;
|
2013-03-08 19:52:18 +00:00
|
|
|
cellInset(cell)->plaintext(sstr, runparams, max_length);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (clen[c] < sstr.str().length())
|
|
|
|
clen[c] = sstr.str().length();
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
2010-03-04 21:31:06 +00:00
|
|
|
// then all multicolumn cells!
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
idx_type cell = cellIndex(r, c);
|
|
|
|
if (cell_info[r][c].multicolumn != CELL_BEGIN_OF_MULTICOLUMN)
|
2007-04-26 12:54:21 +00:00
|
|
|
continue;
|
|
|
|
odocstringstream sstr;
|
2013-03-08 19:52:18 +00:00
|
|
|
cellInset(cell)->plaintext(sstr, runparams, max_length);
|
2007-04-26 12:54:21 +00:00
|
|
|
int len = int(sstr.str().length());
|
2008-03-18 18:08:32 +00:00
|
|
|
idx_type const n = columnSpan(cell);
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type k = c; len > 0 && k < c + n - 1; ++k)
|
2007-04-26 12:54:21 +00:00
|
|
|
len -= clen[k];
|
2010-03-05 18:10:34 +00:00
|
|
|
if (len > int(clen[c + n - 1]))
|
|
|
|
clen[c + n - 1] = len;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
idx_type cell = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < nrows(); ++r) {
|
|
|
|
if (!onlydata && plaintextTopHLine(os, r, clen))
|
2007-04-26 12:54:21 +00:00
|
|
|
os << docstring(depth * 2, ' ');
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < ncols(); ++c) {
|
2011-05-11 14:12:00 +00:00
|
|
|
if (isPartOfMultiColumn(r, c) || isPartOfMultiRow(r,c))
|
2007-04-26 12:54:21 +00:00
|
|
|
continue;
|
2010-03-05 18:10:34 +00:00
|
|
|
if (onlydata && c > 0)
|
2007-11-01 16:59:40 +00:00
|
|
|
// we don't use operator<< for single UCS4 character.
|
|
|
|
// see explanation in docstream.h
|
|
|
|
os.put(delim);
|
2013-03-08 19:52:18 +00:00
|
|
|
plaintextPrintCell(os, runparams, cell, r, c, clen, onlydata, max_length);
|
2007-04-26 12:54:21 +00:00
|
|
|
++cell;
|
2013-03-08 19:52:18 +00:00
|
|
|
if (os.str().size() > max_length)
|
|
|
|
break;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
os << endl;
|
|
|
|
if (!onlydata) {
|
|
|
|
os << docstring(depth * 2, ' ');
|
2010-03-05 18:10:34 +00:00
|
|
|
if (plaintextBottomHLine(os, r, clen))
|
2007-04-26 12:54:21 +00:00
|
|
|
os << docstring(depth * 2, ' ');
|
|
|
|
}
|
2013-03-08 19:52:18 +00:00
|
|
|
if (os.str().size() > max_length)
|
|
|
|
break;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
shared_ptr<InsetTableCell> Tabular::cellInset(idx_type cell) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2007-09-04 10:52:08 +00:00
|
|
|
return cell_info[cellRow(cell)][cellColumn(cell)].inset;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
shared_ptr<InsetTableCell> Tabular::cellInset(row_type row,
|
2007-04-26 12:54:21 +00:00
|
|
|
col_type column) const
|
|
|
|
{
|
|
|
|
return cell_info[row][column].inset;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::setCellInset(row_type row, col_type column,
|
2008-03-21 06:16:05 +00:00
|
|
|
shared_ptr<InsetTableCell> ins) const
|
2007-04-26 12:54:21 +00:00
|
|
|
{
|
2008-03-21 17:45:14 +00:00
|
|
|
CellData & cd = cell_info[row][column];
|
|
|
|
cd.inset = ins;
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Tabular::validate(LaTeXFeatures & features) const
|
|
|
|
{
|
|
|
|
features.require("NeedTabularnewline");
|
2008-04-21 13:33:39 +00:00
|
|
|
if (use_booktabs)
|
2007-04-26 12:54:21 +00:00
|
|
|
features.require("booktabs");
|
2008-04-21 13:33:39 +00:00
|
|
|
if (is_long_tabular)
|
2007-04-26 12:54:21 +00:00
|
|
|
features.require("longtable");
|
|
|
|
if (needRotating())
|
|
|
|
features.require("rotating");
|
2008-04-21 13:33:39 +00:00
|
|
|
for (idx_type cell = 0; cell < numberofcells; ++cell) {
|
2010-02-11 01:07:54 +00:00
|
|
|
if (isMultiRow(cell))
|
|
|
|
features.require("multirow");
|
2008-09-10 12:49:08 +00:00
|
|
|
if (getVAlignment(cell) != LYX_VALIGN_TOP
|
|
|
|
|| !getPWidth(cell).zero())
|
2007-04-26 12:54:21 +00:00
|
|
|
features.require("array");
|
2008-03-25 13:32:38 +00:00
|
|
|
cellInset(cell)->validate(features);
|
2007-04-26 12:54:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Tabular::BoxType Tabular::useParbox(idx_type cell) const
|
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
ParagraphList const & parlist = cellInset(cell)->paragraphs();
|
2007-04-26 12:54:21 +00:00
|
|
|
ParagraphList::const_iterator cit = parlist.begin();
|
|
|
|
ParagraphList::const_iterator end = parlist.end();
|
|
|
|
|
|
|
|
for (; cit != end; ++cit)
|
|
|
|
for (int i = 0; i < cit->size(); ++i)
|
|
|
|
if (cit->isNewline(i))
|
|
|
|
return BOX_PARBOX;
|
|
|
|
|
|
|
|
return BOX_NONE;
|
2003-03-09 18:11:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-21 17:45:14 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// InsetTableCell
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
2009-11-08 15:53:21 +00:00
|
|
|
InsetTableCell::InsetTableCell(Buffer * buf)
|
2009-04-04 19:34:14 +00:00
|
|
|
: InsetText(buf, InsetText::PlainLayout), isFixedWidth(false),
|
2008-09-13 10:10:01 +00:00
|
|
|
contentAlign(LYX_ALIGN_CENTER)
|
2008-03-21 17:45:14 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
2008-07-10 17:41:52 +00:00
|
|
|
bool InsetTableCell::forcePlainLayout(idx_type) const
|
2008-03-21 17:45:14 +00:00
|
|
|
{
|
2008-07-16 14:23:32 +00:00
|
|
|
return !isFixedWidth;
|
2008-03-21 17:45:14 +00:00
|
|
|
}
|
|
|
|
|
2008-09-10 16:02:32 +00:00
|
|
|
|
2008-03-21 17:45:14 +00:00
|
|
|
bool InsetTableCell::allowParagraphCustomization(idx_type) const
|
|
|
|
{
|
2008-07-16 14:23:32 +00:00
|
|
|
return isFixedWidth;
|
2008-03-21 17:45:14 +00:00
|
|
|
}
|
|
|
|
|
2008-09-09 18:42:17 +00:00
|
|
|
|
2015-04-04 09:59:01 +00:00
|
|
|
bool InsetTableCell::forceLocalFontSwitch() const
|
|
|
|
{
|
|
|
|
return isFixedWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-21 17:45:14 +00:00
|
|
|
bool InsetTableCell::getStatus(Cursor & cur, FuncRequest const & cmd,
|
|
|
|
FuncStatus & status) const
|
|
|
|
{
|
2010-12-03 02:44:16 +00:00
|
|
|
bool enabled = true;
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2008-03-21 17:45:14 +00:00
|
|
|
case LFUN_LAYOUT:
|
2008-07-10 17:41:52 +00:00
|
|
|
enabled = !forcePlainLayout();
|
2008-03-21 17:45:14 +00:00
|
|
|
break;
|
|
|
|
case LFUN_LAYOUT_PARAGRAPH:
|
|
|
|
enabled = allowParagraphCustomization();
|
|
|
|
break;
|
2010-12-03 02:44:16 +00:00
|
|
|
|
|
|
|
case LFUN_MATH_DISPLAY:
|
|
|
|
if (!hasFixedWidth()) {
|
|
|
|
enabled = false;
|
|
|
|
break;
|
|
|
|
} //fall-through
|
2008-03-21 17:45:14 +00:00
|
|
|
default:
|
|
|
|
return InsetText::getStatus(cur, cmd, status);
|
|
|
|
}
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(enabled);
|
2008-03-21 17:45:14 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
docstring InsetTableCell::asString(bool intoInsets)
|
2008-08-08 21:26:18 +00:00
|
|
|
{
|
|
|
|
docstring retval;
|
|
|
|
if (paragraphs().empty())
|
|
|
|
return retval;
|
|
|
|
ParagraphList::const_iterator it = paragraphs().begin();
|
|
|
|
ParagraphList::const_iterator en = paragraphs().end();
|
|
|
|
bool first = true;
|
|
|
|
for (; it != en; ++it) {
|
|
|
|
if (!first)
|
|
|
|
retval += "\n";
|
|
|
|
else
|
|
|
|
first = false;
|
|
|
|
retval += it->asString(intoInsets ? AS_STR_INSETS : AS_STR_NONE);
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-02-24 19:36:13 +00:00
|
|
|
void InsetTableCell::addToToc(DocIterator const & di, bool output_active) const
|
|
|
|
{
|
|
|
|
InsetText::iterateForToc(di, output_active);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-14 15:39:13 +00:00
|
|
|
docstring InsetTableCell::xhtml(XHTMLStream & xs, OutputParams const & rp) const
|
|
|
|
{
|
|
|
|
if (!isFixedWidth)
|
|
|
|
return InsetText::insetAsXHTML(xs, rp, InsetText::JustText);
|
|
|
|
return InsetText::xhtml(xs, rp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-08-08 21:26:18 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// InsetTabular
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
2009-11-08 15:53:21 +00:00
|
|
|
InsetTabular::InsetTabular(Buffer * buf, row_type rows,
|
2006-04-05 23:56:29 +00:00
|
|
|
col_type columns)
|
2014-07-26 20:25:48 +00:00
|
|
|
: Inset(buf), tabular(buf, max(rows, row_type(1)), max(columns, col_type(1))),
|
2015-01-10 17:00:13 +00:00
|
|
|
rowselect_(false), colselect_(false)
|
2008-02-23 22:32:33 +00:00
|
|
|
{
|
|
|
|
}
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2003-06-03 15:10:14 +00:00
|
|
|
InsetTabular::InsetTabular(InsetTabular const & tab)
|
2014-07-26 20:25:48 +00:00
|
|
|
: Inset(tab), tabular(tab.tabular)
|
2008-02-23 22:32:33 +00:00
|
|
|
{
|
|
|
|
}
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2000-04-19 14:42:19 +00:00
|
|
|
InsetTabular::~InsetTabular()
|
|
|
|
{
|
2008-03-27 22:26:24 +00:00
|
|
|
hideDialogs("tabular", this);
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-23 13:25:03 +00:00
|
|
|
void InsetTabular::setBuffer(Buffer & buf)
|
|
|
|
{
|
|
|
|
tabular.setBuffer(buf);
|
|
|
|
Inset::setBuffer(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-21 20:42:46 +00:00
|
|
|
bool InsetTabular::insetAllowed(InsetCode code) const
|
|
|
|
{
|
2010-08-07 03:16:38 +00:00
|
|
|
switch (code) {
|
|
|
|
case FLOAT_CODE:
|
2010-05-05 21:15:15 +00:00
|
|
|
case MARGIN_CODE:
|
|
|
|
case MATHMACRO_CODE:
|
2010-08-07 03:16:38 +00:00
|
|
|
case WRAP_CODE:
|
2007-12-21 20:42:46 +00:00
|
|
|
return false;
|
|
|
|
|
2010-05-05 21:15:15 +00:00
|
|
|
case CAPTION_CODE:
|
|
|
|
return tabular.is_long_tabular;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return true;
|
|
|
|
}
|
2007-12-21 20:42:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-22 21:23:38 +00:00
|
|
|
bool InsetTabular::allowsCaptionVariation(std::string const & newtype) const
|
|
|
|
{
|
|
|
|
return tabular.is_long_tabular &&
|
|
|
|
(newtype == "Standard" || newtype == "LongTableNoNumber");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void InsetTabular::write(ostream & os) const
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2003-07-28 13:04:40 +00:00
|
|
|
os << "Tabular" << endl;
|
2008-02-27 20:43:16 +00:00
|
|
|
tabular.write(os);
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-29 14:48:55 +00:00
|
|
|
string InsetTabular::contextMenu(BufferView const &, int, int) const
|
2008-03-28 18:50:33 +00:00
|
|
|
{
|
2010-11-29 23:21:52 +00:00
|
|
|
// FIXME: depending on the selection state,
|
|
|
|
// we could offer a different menu.
|
|
|
|
return cell(0)->contextMenuName() + ";" + contextMenuName();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-29 14:48:55 +00:00
|
|
|
string InsetTabular::contextMenuName() const
|
2010-11-29 23:21:52 +00:00
|
|
|
{
|
2011-10-29 14:48:55 +00:00
|
|
|
return "context-tabular";
|
2008-03-28 18:50:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
void InsetTabular::read(Lexer & lex)
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2008-04-05 10:34:29 +00:00
|
|
|
//bool const old_format = (lex.getString() == "\\LyXTable");
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
tabular.read(lex);
|
2000-05-04 08:14:34 +00:00
|
|
|
|
2008-04-05 10:34:29 +00:00
|
|
|
//if (old_format)
|
2008-04-05 21:24:57 +00:00
|
|
|
// return;
|
2000-05-17 14:43:09 +00:00
|
|
|
|
2004-10-05 12:56:22 +00:00
|
|
|
lex.next();
|
2001-08-06 19:13:25 +00:00
|
|
|
string token = lex.getString();
|
2007-03-26 13:43:49 +00:00
|
|
|
while (lex && token != "\\end_inset") {
|
2004-10-05 12:56:22 +00:00
|
|
|
lex.next();
|
2001-08-06 19:13:25 +00:00
|
|
|
token = lex.getString();
|
2001-04-04 09:42:56 +00:00
|
|
|
}
|
2008-04-05 21:24:57 +00:00
|
|
|
if (!lex)
|
|
|
|
lex.printError("Missing \\end_inset at this point. ");
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
int InsetTabular::rowFromY(Cursor & cur, int y) const
|
|
|
|
{
|
|
|
|
// top y coordinate of tabular
|
2010-11-25 13:20:56 +00:00
|
|
|
int h = yo(cur.bv()) - tabular.rowAscent(0) + offset_valign_;
|
2008-03-18 18:08:32 +00:00
|
|
|
row_type r = 0;
|
2010-03-08 04:04:56 +00:00
|
|
|
for (; r < tabular.nrows() && y > h; ++r)
|
2010-02-11 01:07:54 +00:00
|
|
|
h += tabular.rowAscent(r) + tabular.rowDescent(r)
|
2010-11-25 16:53:56 +00:00
|
|
|
+ tabular.interRowSpace(r);
|
2010-02-11 01:07:54 +00:00
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
return r - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int InsetTabular::columnFromX(Cursor & cur, int x) const
|
|
|
|
{
|
|
|
|
// left x coordinate of tabular
|
|
|
|
int w = xo(cur.bv()) + ADD_TO_TABULAR_WIDTH;
|
|
|
|
col_type c = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (; c < tabular.ncols() && x > w; ++c)
|
2010-06-14 10:42:42 +00:00
|
|
|
w += tabular.cellWidth(c);
|
2008-03-18 18:08:32 +00:00
|
|
|
return c - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-21 20:39:47 +00:00
|
|
|
void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2003-07-17 15:57:08 +00:00
|
|
|
//lyxerr << "InsetTabular::metrics: " << mi.base.bv << " width: " <<
|
|
|
|
// mi.base.textwidth << "\n";
|
2013-04-27 21:52:55 +00:00
|
|
|
LBUFERR(mi.base.bv);
|
2003-07-25 17:11:25 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < tabular.nrows(); ++r) {
|
2010-03-21 12:15:25 +00:00
|
|
|
int maxasc = 0;
|
|
|
|
int maxdes = 0;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < tabular.ncols(); ++c) {
|
|
|
|
if (tabular.isPartOfMultiColumn(r, c)
|
|
|
|
|| tabular.isPartOfMultiRow(r, c))
|
2010-02-11 01:07:54 +00:00
|
|
|
// multicolumn or multirow cell, but not first one
|
2004-02-16 11:58:51 +00:00
|
|
|
continue;
|
2010-03-05 18:10:34 +00:00
|
|
|
idx_type const cell = tabular.cellIndex(r, c);
|
2004-02-16 11:58:51 +00:00
|
|
|
Dimension dim;
|
|
|
|
MetricsInfo m = mi;
|
2010-03-21 12:15:25 +00:00
|
|
|
Length const p_width = tabular.getPWidth(cell);
|
2005-06-16 15:20:09 +00:00
|
|
|
if (!p_width.zero())
|
2015-03-26 15:55:19 +00:00
|
|
|
m.base.textwidth = p_width.inPixels(mi.base);
|
2008-03-25 13:32:38 +00:00
|
|
|
tabular.cellInset(cell)->metrics(m, dim);
|
2005-06-16 15:20:09 +00:00
|
|
|
if (!p_width.zero())
|
|
|
|
dim.wid = m.base.textwidth;
|
2014-07-26 14:29:23 +00:00
|
|
|
tabular.cellInfo(cell).width = dim.wid + 2 * WIDTH_OF_LINE
|
2010-06-14 10:42:42 +00:00
|
|
|
+ tabular.interColumnSpace(cell);
|
2010-03-19 09:41:31 +00:00
|
|
|
|
2010-03-21 12:15:25 +00:00
|
|
|
// FIXME(?): do we need a second metrics call?
|
2014-07-26 14:29:23 +00:00
|
|
|
TextMetrics const & tm =
|
2010-03-19 09:41:31 +00:00
|
|
|
mi.base.bv->textMetrics(tabular.cellInset(cell)->getText(0));
|
2010-06-05 07:44:44 +00:00
|
|
|
|
2010-11-25 22:06:31 +00:00
|
|
|
// determine horizontal offset because of decimal align (if necessary)
|
2010-06-05 07:44:44 +00:00
|
|
|
int decimal_width = 0;
|
2010-06-07 09:39:04 +00:00
|
|
|
if (tabular.getAlignment(cell) == LYX_ALIGN_DECIMAL) {
|
2011-04-25 12:56:09 +00:00
|
|
|
InsetTableCell tail = InsetTableCell(*tabular.cellInset(cell).get());
|
|
|
|
tail.setBuffer(tabular.buffer());
|
|
|
|
// we need to set macrocontext position everywhere
|
|
|
|
// otherwise we crash with nested insets (e.g. footnotes)
|
|
|
|
// after decimal point
|
|
|
|
DocIterator dit = tabular.cellInset(cell)->getText(0)->macrocontextPosition();
|
|
|
|
dit.pop_back();
|
|
|
|
dit.push_back(CursorSlice(tail));
|
|
|
|
tail.setMacrocontextPositionRecursive(dit);
|
|
|
|
|
|
|
|
// remove text leading decimal point
|
|
|
|
docstring const align_d = tabular.column_info[c].decimal_point;
|
2011-05-09 12:33:32 +00:00
|
|
|
dit = separatorPos(&tail, align_d);
|
2011-04-25 12:56:09 +00:00
|
|
|
|
|
|
|
pit_type const psize = tail.paragraphs().front().size();
|
|
|
|
if (dit) {
|
|
|
|
tail.paragraphs().front().eraseChars(0,
|
|
|
|
dit.pos() < psize ? dit.pos() + 1 : psize, false);
|
|
|
|
Dimension dim1;
|
2010-06-05 07:44:44 +00:00
|
|
|
tail.metrics(m, dim1);
|
|
|
|
decimal_width = dim1.width();
|
|
|
|
}
|
|
|
|
}
|
2011-04-25 12:56:09 +00:00
|
|
|
tabular.cell_info[r][c].decimal_hoffset = tm.width() - decimal_width;
|
2010-06-05 07:44:44 +00:00
|
|
|
tabular.cell_info[r][c].decimal_width = decimal_width;
|
|
|
|
|
2010-03-21 12:15:25 +00:00
|
|
|
// with LYX_VALIGN_BOTTOM the descent is relative to the last par
|
|
|
|
// = descent of text in last par + TEXT_TO_INSET_OFFSET:
|
|
|
|
int const lastpardes = tm.last().second->descent()
|
|
|
|
+ TEXT_TO_INSET_OFFSET;
|
2010-03-22 00:42:01 +00:00
|
|
|
int offset = 0;
|
2014-07-26 14:29:23 +00:00
|
|
|
switch (tabular.getVAlignment(cell)) {
|
2010-03-19 09:41:31 +00:00
|
|
|
case Tabular::LYX_VALIGN_TOP:
|
2014-07-26 14:29:23 +00:00
|
|
|
break;
|
2010-03-19 09:41:31 +00:00
|
|
|
case Tabular::LYX_VALIGN_MIDDLE:
|
2014-07-26 14:29:23 +00:00
|
|
|
offset = -(dim.des - lastpardes)/2;
|
|
|
|
break;
|
2010-03-19 09:41:31 +00:00
|
|
|
case Tabular::LYX_VALIGN_BOTTOM:
|
2014-07-26 14:29:23 +00:00
|
|
|
offset = -(dim.des - lastpardes);
|
2010-03-19 09:41:31 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-03-21 12:15:25 +00:00
|
|
|
tabular.cell_info[r][c].voffset = offset;
|
|
|
|
maxasc = max(maxasc, dim.asc - offset);
|
|
|
|
maxdes = max(maxdes, dim.des + offset);
|
2004-02-16 11:58:51 +00:00
|
|
|
}
|
2010-03-05 18:10:34 +00:00
|
|
|
int const top_space = tabular.row_info[r].top_space_default ?
|
2006-07-03 19:13:56 +00:00
|
|
|
default_line_space :
|
2015-03-26 15:55:19 +00:00
|
|
|
tabular.row_info[r].top_space.inPixels(mi.base);
|
2010-03-21 12:15:25 +00:00
|
|
|
tabular.setRowAscent(r, maxasc + ADD_TO_HEIGHT + top_space);
|
2010-03-05 18:10:34 +00:00
|
|
|
int const bottom_space = tabular.row_info[r].bottom_space_default ?
|
2006-07-03 19:13:56 +00:00
|
|
|
default_line_space :
|
2015-03-26 15:55:19 +00:00
|
|
|
tabular.row_info[r].bottom_space.inPixels(mi.base);
|
2010-03-21 12:15:25 +00:00
|
|
|
tabular.setRowDescent(r, maxdes + ADD_TO_HEIGHT + bottom_space);
|
2004-02-16 11:58:51 +00:00
|
|
|
}
|
2010-11-25 22:49:05 +00:00
|
|
|
|
|
|
|
// for top-alignment the first horizontal table line must be exactly at
|
|
|
|
// the position of the base line of the surrounding text line
|
|
|
|
// for bottom alignment, the same is for the last table line
|
2010-11-25 13:20:56 +00:00
|
|
|
switch (tabular.tabular_valignment) {
|
|
|
|
case Tabular::LYX_VALIGN_BOTTOM:
|
|
|
|
offset_valign_ = tabular.rowAscent(0) - tabular.height();
|
|
|
|
break;
|
|
|
|
case Tabular::LYX_VALIGN_MIDDLE:
|
2010-11-25 22:49:05 +00:00
|
|
|
offset_valign_ = (- tabular.height()) / 2 + tabular.rowAscent(0);
|
2010-11-25 13:20:56 +00:00
|
|
|
break;
|
|
|
|
case Tabular::LYX_VALIGN_TOP:
|
2010-11-25 22:49:05 +00:00
|
|
|
offset_valign_ = tabular.rowAscent(0);
|
2010-11-25 13:20:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-03-24 14:03:00 +00:00
|
|
|
tabular.updateColumnWidths();
|
2014-07-26 14:29:23 +00:00
|
|
|
dim.asc = tabular.rowAscent(0) - offset_valign_;
|
2007-09-04 10:52:08 +00:00
|
|
|
dim.des = tabular.height() - dim.asc;
|
|
|
|
dim.wid = tabular.width() + 2 * ADD_TO_TABULAR_WIDTH;
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
2010-03-21 12:15:25 +00:00
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
bool InsetTabular::isCellSelected(Cursor & cur, row_type row, col_type col)
|
2008-10-25 10:47:38 +00:00
|
|
|
const
|
|
|
|
{
|
|
|
|
if (&cur.inset() == this && cur.selection()) {
|
|
|
|
if (cur.selIsMultiCell()) {
|
|
|
|
row_type rs, re;
|
|
|
|
col_type cs, ce;
|
|
|
|
getSelection(cur, rs, re, cs, ce);
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-03-16 09:46:25 +00:00
|
|
|
idx_type const cell = tabular.cellIndex(row, col);
|
2010-03-16 09:50:58 +00:00
|
|
|
col_type const cspan = tabular.columnSpan(cell);
|
|
|
|
row_type const rspan = tabular.rowSpan(cell);
|
2014-07-26 14:29:23 +00:00
|
|
|
if (col + cspan - 1 >= cs && col <= ce
|
2010-03-16 09:50:58 +00:00
|
|
|
&& row + rspan - 1 >= rs && row <= re)
|
2008-10-25 10:47:38 +00:00
|
|
|
return true;
|
2014-07-26 14:29:23 +00:00
|
|
|
} else
|
|
|
|
if (col == tabular.cellColumn(cur.idx())
|
2008-10-25 10:47:38 +00:00
|
|
|
&& row == tabular.cellRow(cur.idx())) {
|
|
|
|
CursorSlice const & beg = cur.selBegin();
|
|
|
|
CursorSlice const & end = cur.selEnd();
|
|
|
|
|
2008-11-18 21:37:02 +00:00
|
|
|
if ((end.lastpos() > 0 || end.lastpit() > 0)
|
|
|
|
&& end.pos() == end.lastpos() && beg.pos() == 0
|
|
|
|
&& end.pit() == end.lastpit() && beg.pit() == 0)
|
2008-10-25 10:47:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2003-05-30 06:48:24 +00:00
|
|
|
void InsetTabular::draw(PainterInfo & pi, int x, int y) const
|
2001-04-04 09:42:56 +00:00
|
|
|
{
|
2014-07-26 20:25:48 +00:00
|
|
|
x += ADD_TO_TABULAR_WIDTH;
|
2010-02-11 01:07:54 +00:00
|
|
|
|
2003-05-30 06:48:24 +00:00
|
|
|
BufferView * bv = pi.base.bv;
|
2008-10-25 10:47:38 +00:00
|
|
|
Cursor & cur = pi.base.bv->cursor();
|
2004-11-30 01:59:49 +00:00
|
|
|
|
2010-11-25 13:08:26 +00:00
|
|
|
// FIXME: As the full background is painted in drawBackground(),
|
2007-08-31 14:02:12 +00:00
|
|
|
// we have no choice but to do a full repaint for the Text cells.
|
|
|
|
pi.full_repaint = true;
|
|
|
|
|
2008-10-25 10:47:38 +00:00
|
|
|
bool const original_selection_state = pi.selected;
|
2007-11-06 14:07:49 +00:00
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
idx_type idx = 0;
|
2007-04-26 12:54:21 +00:00
|
|
|
first_visible_cell = Tabular::npos;
|
2010-11-25 13:20:56 +00:00
|
|
|
|
|
|
|
int yy = y + offset_valign_;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < tabular.nrows(); ++r) {
|
2003-07-30 15:41:39 +00:00
|
|
|
int nx = x;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < tabular.ncols(); ++c) {
|
|
|
|
if (tabular.isPartOfMultiColumn(r, c))
|
2003-03-17 01:34:36 +00:00
|
|
|
continue;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
idx = tabular.cellIndex(r, c);
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
if (tabular.isPartOfMultiRow(r, c)) {
|
2010-06-14 10:42:42 +00:00
|
|
|
nx += tabular.cellWidth(idx);
|
2010-02-11 01:07:54 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
if (first_visible_cell == Tabular::npos)
|
2004-02-16 11:58:51 +00:00
|
|
|
first_visible_cell = idx;
|
2003-03-17 01:34:36 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
pi.selected |= isCellSelected(cur, r, c);
|
2010-02-11 01:07:54 +00:00
|
|
|
int const cx = nx + tabular.textHOffset(idx);
|
2010-11-25 13:20:56 +00:00
|
|
|
int const cy = yy + tabular.textVOffset(idx);
|
2007-09-20 10:58:38 +00:00
|
|
|
// Cache the Inset position.
|
2010-03-16 21:42:16 +00:00
|
|
|
bv->coordCache().insets().add(cell(idx).get(), cx, cy);
|
2010-02-11 01:07:54 +00:00
|
|
|
cell(idx)->draw(pi, cx, cy);
|
2010-11-25 13:20:56 +00:00
|
|
|
drawCellLines(pi, nx, yy, r, idx);
|
2010-06-14 10:42:42 +00:00
|
|
|
nx += tabular.cellWidth(idx);
|
2008-10-25 10:47:38 +00:00
|
|
|
pi.selected = original_selection_state;
|
2000-11-19 16:07:18 +00:00
|
|
|
}
|
2003-05-26 11:33:37 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
if (r + 1 < tabular.nrows())
|
2014-07-26 14:29:23 +00:00
|
|
|
yy += tabular.rowDescent(r) + tabular.rowAscent(r + 1)
|
2010-03-13 12:00:37 +00:00
|
|
|
+ tabular.interRowSpace(r + 1);
|
2004-11-30 01:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-11-25 13:08:26 +00:00
|
|
|
void InsetTabular::drawBackground(PainterInfo & pi, int x, int y) const
|
|
|
|
{
|
2014-07-26 20:25:48 +00:00
|
|
|
x += ADD_TO_TABULAR_WIDTH;
|
2010-11-25 13:20:56 +00:00
|
|
|
y += offset_valign_ - tabular.rowAscent(0);
|
2010-11-25 13:08:26 +00:00
|
|
|
pi.pain.fillRectangle(x, y, tabular.width(), tabular.height(),
|
|
|
|
pi.backgroundColor(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-11-30 01:59:49 +00:00
|
|
|
void InsetTabular::drawSelection(PainterInfo & pi, int x, int y) const
|
|
|
|
{
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor & cur = pi.base.bv->cursor();
|
2006-06-18 09:27:57 +00:00
|
|
|
|
2014-07-26 20:25:48 +00:00
|
|
|
x += ADD_TO_TABULAR_WIDTH;
|
2006-06-18 09:27:57 +00:00
|
|
|
|
2004-11-30 01:59:49 +00:00
|
|
|
if (!cur.selection())
|
|
|
|
return;
|
2007-11-01 22:17:22 +00:00
|
|
|
if (&cur.inset() != this)
|
2004-11-30 01:59:49 +00:00
|
|
|
return;
|
2003-05-26 11:33:37 +00:00
|
|
|
|
2005-07-15 17:15:32 +00:00
|
|
|
//resetPos(cur);
|
2004-12-06 02:35:12 +00:00
|
|
|
|
2008-11-18 22:35:02 +00:00
|
|
|
bool const full_cell_selected = isCellSelected(cur,
|
|
|
|
tabular.cellRow(cur.idx()), tabular.cellColumn(cur.idx()));
|
2005-01-06 15:40:49 +00:00
|
|
|
|
2008-11-18 22:35:02 +00:00
|
|
|
if (cur.selIsMultiCell() || full_cell_selected) {
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < tabular.nrows(); ++r) {
|
2004-11-30 01:59:49 +00:00
|
|
|
int xx = x;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < tabular.ncols(); ++c) {
|
2010-02-11 01:07:54 +00:00
|
|
|
if (tabular.isPartOfMultiColumn(r, c))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
idx_type const cell = tabular.cellIndex(r, c);
|
|
|
|
|
|
|
|
if (tabular.isPartOfMultiRow(r, c)) {
|
2010-06-14 10:42:42 +00:00
|
|
|
xx += tabular.cellWidth(cell);
|
2004-11-30 01:59:49 +00:00
|
|
|
continue;
|
2010-02-11 01:07:54 +00:00
|
|
|
}
|
2010-06-14 10:42:42 +00:00
|
|
|
int const w = tabular.cellWidth(cell);
|
2010-03-16 21:42:16 +00:00
|
|
|
int const h = tabular.cellHeight(cell);
|
2010-11-25 13:20:56 +00:00
|
|
|
int const yy = y - tabular.rowAscent(r) + offset_valign_;
|
2010-02-11 01:07:54 +00:00
|
|
|
if (isCellSelected(cur, r, c))
|
2010-03-13 12:00:37 +00:00
|
|
|
pi.pain.fillRectangle(xx, yy, w, h, Color_selection);
|
2004-11-30 01:59:49 +00:00
|
|
|
xx += w;
|
|
|
|
}
|
2010-03-05 18:10:34 +00:00
|
|
|
if (r + 1 < tabular.nrows())
|
2010-03-13 12:00:37 +00:00
|
|
|
y += tabular.rowDescent(r) + tabular.rowAscent(r + 1)
|
2010-02-11 01:07:54 +00:00
|
|
|
+ tabular.interRowSpace(r + 1);
|
2004-11-30 01:59:49 +00:00
|
|
|
}
|
2005-01-06 15:40:49 +00:00
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
}
|
2010-11-25 13:02:30 +00:00
|
|
|
// FIXME: This code has no effect because InsetTableCell does not handle
|
|
|
|
// drawSelection other than the trivial implementation in Inset.
|
|
|
|
//else {
|
|
|
|
// x += cellXPos(cur.idx());
|
|
|
|
// x += tabular.textHOffset(cur.idx());
|
|
|
|
// cell(cur.idx())->drawSelection(pi, x, 0 /* ignored */);
|
|
|
|
//}
|
2000-06-16 15:13:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-02 12:13:54 +00:00
|
|
|
void InsetTabular::drawCellLines(PainterInfo & pi, int x, int y,
|
|
|
|
row_type row, idx_type cell) const
|
2001-04-04 09:42:56 +00:00
|
|
|
{
|
2010-03-16 22:42:57 +00:00
|
|
|
y -= tabular.rowAscent(row);
|
2010-06-14 10:42:42 +00:00
|
|
|
int const w = tabular.cellWidth(cell);
|
2010-03-16 21:42:16 +00:00
|
|
|
int const h = tabular.cellHeight(cell);
|
2010-09-02 12:13:54 +00:00
|
|
|
Color const linecolor = pi.textColor(Color_tabularline);
|
|
|
|
Color const gridcolor = pi.textColor(Color_tabularonoffline);
|
2005-09-07 10:37:05 +00:00
|
|
|
|
2010-03-16 22:42:57 +00:00
|
|
|
// Top
|
2010-03-18 14:00:44 +00:00
|
|
|
bool drawline = tabular.topLine(cell)
|
|
|
|
|| (row > 0 && tabular.bottomLine(tabular.cellAbove(cell)));
|
2010-09-02 12:13:54 +00:00
|
|
|
pi.pain.line(x, y, x + w, y,
|
2010-03-16 22:42:57 +00:00
|
|
|
drawline ? linecolor : gridcolor,
|
|
|
|
drawline ? Painter::line_solid : Painter::line_onoffdash);
|
2010-02-19 22:00:54 +00:00
|
|
|
|
2010-03-16 22:42:57 +00:00
|
|
|
// Bottom
|
|
|
|
drawline = tabular.bottomLine(cell);
|
2010-09-02 12:13:54 +00:00
|
|
|
pi.pain.line(x, y + h, x + w, y + h,
|
2010-03-16 22:42:57 +00:00
|
|
|
drawline ? linecolor : gridcolor,
|
|
|
|
drawline ? Painter::line_solid : Painter::line_onoffdash);
|
|
|
|
|
|
|
|
// Left
|
|
|
|
col_type const col = tabular.cellColumn(cell);
|
2010-03-18 14:00:44 +00:00
|
|
|
drawline = tabular.leftLine(cell)
|
|
|
|
|| (col > 0 && tabular.rightLine(tabular.cellIndex(row, col - 1)));
|
2010-09-02 12:13:54 +00:00
|
|
|
pi.pain.line(x, y, x, y + h,
|
2010-03-16 22:42:57 +00:00
|
|
|
drawline ? linecolor : gridcolor,
|
|
|
|
drawline ? Painter::line_solid : Painter::line_onoffdash);
|
|
|
|
|
|
|
|
// Right
|
|
|
|
x -= tabular.interColumnSpace(cell);
|
2014-02-05 20:30:04 +00:00
|
|
|
col_type next_cell_col = col + 1;
|
2014-07-26 14:29:23 +00:00
|
|
|
while (next_cell_col < tabular.ncols()
|
2014-02-05 20:30:04 +00:00
|
|
|
&& tabular.isMultiColumn(tabular.cellIndex(row, next_cell_col)))
|
|
|
|
next_cell_col++;
|
2010-03-18 14:00:44 +00:00
|
|
|
drawline = tabular.rightLine(cell)
|
2014-02-05 20:30:04 +00:00
|
|
|
|| (next_cell_col < tabular.ncols()
|
|
|
|
&& tabular.leftLine(tabular.cellIndex(row, next_cell_col)));
|
2010-09-02 12:13:54 +00:00
|
|
|
pi.pain.line(x + w, y, x + w, y + h,
|
2010-03-16 22:42:57 +00:00
|
|
|
drawline ? linecolor : gridcolor,
|
|
|
|
drawline ? Painter::line_solid : Painter::line_onoffdash);
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-12 20:58:12 +00:00
|
|
|
void InsetTabular::edit(Cursor & cur, bool front, EntryDirection)
|
2003-10-15 08:49:44 +00:00
|
|
|
{
|
2006-01-19 15:49:21 +00:00
|
|
|
//lyxerr << "InsetTabular::edit: " << this << endl;
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2004-08-16 00:32:04 +00:00
|
|
|
cur.push(*this);
|
2008-02-12 20:58:12 +00:00
|
|
|
if (front) {
|
2004-01-20 14:25:24 +00:00
|
|
|
if (isRightToLeft(cur))
|
2004-10-23 09:46:33 +00:00
|
|
|
cur.idx() = tabular.getLastCellInRow(0);
|
2003-11-04 12:36:59 +00:00
|
|
|
else
|
2004-10-23 09:46:33 +00:00
|
|
|
cur.idx() = 0;
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = 0;
|
2004-10-23 09:46:33 +00:00
|
|
|
cur.pos() = 0;
|
2003-11-04 12:36:59 +00:00
|
|
|
} else {
|
2004-01-20 14:25:24 +00:00
|
|
|
if (isRightToLeft(cur))
|
2010-03-05 18:10:34 +00:00
|
|
|
cur.idx() = tabular.getFirstCellInRow(tabular.nrows() - 1);
|
2003-11-04 12:36:59 +00:00
|
|
|
else
|
2008-04-21 13:33:39 +00:00
|
|
|
cur.idx() = tabular.numberofcells - 1;
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = 0;
|
2004-10-23 09:46:33 +00:00
|
|
|
cur.pos() = cur.lastpos(); // FIXME crude guess
|
2003-11-04 12:36:59 +00:00
|
|
|
}
|
2009-12-17 17:47:09 +00:00
|
|
|
cur.setCurrentFont();
|
2006-10-20 16:11:30 +00:00
|
|
|
// FIXME: this accesses the position cache before it is initialized
|
2004-08-14 14:03:42 +00:00
|
|
|
//cur.bv().fitCursor();
|
2003-11-04 12:36:59 +00:00
|
|
|
}
|
2003-10-15 08:49:44 +00:00
|
|
|
|
2003-11-04 12:36:59 +00:00
|
|
|
|
2010-03-03 22:13:45 +00:00
|
|
|
void InsetTabular::updateBuffer(ParIterator const & it, UpdateType utype)
|
2007-08-12 21:43:58 +00:00
|
|
|
{
|
|
|
|
// In a longtable, tell captions what the current float is
|
2008-11-15 19:30:58 +00:00
|
|
|
Counters & cnts = buffer().masterBuffer()->params().documentClass().counters();
|
2007-08-12 21:43:58 +00:00
|
|
|
string const saveflt = cnts.current_float();
|
2014-02-25 07:00:43 +00:00
|
|
|
if (tabular.is_long_tabular) {
|
2007-08-12 21:43:58 +00:00
|
|
|
cnts.current_float("table");
|
2014-02-25 07:00:43 +00:00
|
|
|
// in longtables, we only step the counter once
|
|
|
|
cnts.step(from_ascii("table"), utype);
|
|
|
|
cnts.isLongtable(true);
|
|
|
|
}
|
2007-08-12 21:43:58 +00:00
|
|
|
|
|
|
|
ParIterator it2 = it;
|
|
|
|
it2.forwardPos();
|
2007-08-14 14:41:06 +00:00
|
|
|
size_t const end = it2.nargs();
|
2007-08-23 21:35:40 +00:00
|
|
|
for ( ; it2.idx() < end; it2.top().forwardIdx())
|
2010-03-03 22:13:45 +00:00
|
|
|
buffer().updateBuffer(it2, utype);
|
2007-08-12 21:43:58 +00:00
|
|
|
|
|
|
|
//reset afterwards
|
2014-02-25 07:00:43 +00:00
|
|
|
if (tabular.is_long_tabular) {
|
2007-08-12 21:43:58 +00:00
|
|
|
cnts.current_float(saveflt);
|
2014-02-25 07:00:43 +00:00
|
|
|
cnts.isLongtable(false);
|
|
|
|
}
|
2007-08-12 21:43:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-08 21:18:26 +00:00
|
|
|
void InsetTabular::addToToc(DocIterator const & cpit, bool output_active) const
|
2010-01-28 08:33:14 +00:00
|
|
|
{
|
|
|
|
DocIterator dit = cpit;
|
|
|
|
dit.forwardPos();
|
|
|
|
size_t const end = dit.nargs();
|
|
|
|
for ( ; dit.idx() < end; dit.top().forwardIdx())
|
2013-03-08 21:18:26 +00:00
|
|
|
cell(dit.idx())->addToToc(dit, output_active);
|
2010-01-28 08:33:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetTabular::doDispatch(Cursor & cur, FuncRequest & cmd)
|
2004-02-13 16:22:53 +00:00
|
|
|
{
|
2007-11-15 20:04:51 +00:00
|
|
|
LYXERR(Debug::DEBUG, "# InsetTabular::doDispatch: cmd: " << cmd
|
|
|
|
<< "\n cur:" << cur);
|
2004-03-01 17:12:09 +00:00
|
|
|
CursorSlice sl = cur.top();
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor & bvcur = cur.bv().cursor();
|
2003-10-15 08:49:44 +00:00
|
|
|
|
2010-04-09 19:00:42 +00:00
|
|
|
FuncCode const act = cmd.action();
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (act) {
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2008-03-18 18:08:32 +00:00
|
|
|
case LFUN_MOUSE_PRESS: {
|
2005-07-15 11:43:07 +00:00
|
|
|
//lyxerr << "# InsetTabular::MousePress\n" << cur.bv().cursor() << endl;
|
2008-03-18 18:08:32 +00:00
|
|
|
// select row
|
2010-04-09 19:00:42 +00:00
|
|
|
if (cmd.x() < xo(cur.bv()) + ADD_TO_TABULAR_WIDTH
|
|
|
|
|| cmd.x() > xo(cur.bv()) + tabular.width()) {
|
|
|
|
row_type r = rowFromY(cur, cmd.y());
|
2008-03-18 18:08:32 +00:00
|
|
|
cur.idx() = tabular.getFirstCellInRow(r);
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.resetAnchor();
|
|
|
|
cur.idx() = tabular.getLastCellInRow(r);
|
|
|
|
cur.pos() = cur.lastpos();
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(true);
|
2014-07-26 14:29:23 +00:00
|
|
|
bvcur = cur;
|
2008-03-25 21:26:03 +00:00
|
|
|
rowselect_ = true;
|
2008-03-18 18:08:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
// select column
|
2010-11-25 13:20:56 +00:00
|
|
|
int const y0 = yo(cur.bv()) - tabular.rowAscent(0) + offset_valign_;
|
2014-07-26 14:29:23 +00:00
|
|
|
if (cmd.y() < y0 + ADD_TO_TABULAR_WIDTH
|
2010-04-09 19:00:42 +00:00
|
|
|
|| cmd.y() > y0 + tabular.height()) {
|
|
|
|
col_type c = columnFromX(cur, cmd.x());
|
2008-03-18 18:08:32 +00:00
|
|
|
cur.idx() = tabular.cellIndex(0, c);
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.resetAnchor();
|
2010-03-05 18:10:34 +00:00
|
|
|
cur.idx() = tabular.cellIndex(tabular.nrows() - 1, c);
|
2008-03-18 18:08:32 +00:00
|
|
|
cur.pos() = cur.lastpos();
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(true);
|
2014-07-26 14:29:23 +00:00
|
|
|
bvcur = cur;
|
2008-03-25 21:26:03 +00:00
|
|
|
colselect_ = true;
|
2008-03-18 18:08:32 +00:00
|
|
|
break;
|
|
|
|
}
|
2007-08-13 15:38:32 +00:00
|
|
|
// do not reset cursor/selection if we have selected
|
|
|
|
// some cells (bug 2715).
|
|
|
|
if (cmd.button() == mouse_button::button3
|
2014-07-26 14:29:23 +00:00
|
|
|
&& &bvcur.selBegin().inset() == this
|
|
|
|
&& bvcur.selIsMultiCell())
|
2007-08-13 15:38:32 +00:00
|
|
|
;
|
|
|
|
else
|
2008-03-21 06:16:05 +00:00
|
|
|
// Let InsetTableCell do it
|
2007-08-13 15:38:32 +00:00
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2003-12-12 15:18:29 +00:00
|
|
|
break;
|
2008-03-18 18:08:32 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
case LFUN_MOUSE_MOTION:
|
2005-07-15 11:43:07 +00:00
|
|
|
//lyxerr << "# InsetTabular::MouseMotion\n" << bvcur << endl;
|
2004-08-14 22:38:45 +00:00
|
|
|
if (cmd.button() == mouse_button::button1) {
|
2004-08-14 21:23:16 +00:00
|
|
|
// only accept motions to places not deeper nested than the real anchor
|
2010-04-15 18:16:07 +00:00
|
|
|
if (!bvcur.realAnchor().hasPart(cur)) {
|
2008-03-18 18:08:32 +00:00
|
|
|
cur.undispatched();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// select (additional) row
|
2008-03-25 21:26:03 +00:00
|
|
|
if (rowselect_) {
|
2010-04-09 19:00:42 +00:00
|
|
|
row_type r = rowFromY(cur, cmd.y());
|
2008-03-18 18:08:32 +00:00
|
|
|
cur.idx() = tabular.getLastCellInRow(r);
|
2008-08-08 19:21:06 +00:00
|
|
|
// we need to reset the cursor's pit and pos now, as the old ones
|
|
|
|
// may no longer be valid.
|
|
|
|
cur.pit() = 0;
|
|
|
|
cur.pos() = 0;
|
2004-08-14 21:23:16 +00:00
|
|
|
bvcur.setCursor(cur);
|
2008-09-24 21:27:41 +00:00
|
|
|
bvcur.setSelection(true);
|
2008-03-18 18:08:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
// select (additional) column
|
2008-03-25 21:26:03 +00:00
|
|
|
if (colselect_) {
|
2010-04-09 19:00:42 +00:00
|
|
|
col_type c = columnFromX(cur, cmd.x());
|
2010-03-05 18:10:34 +00:00
|
|
|
cur.idx() = tabular.cellIndex(tabular.nrows() - 1, c);
|
2008-08-08 19:21:06 +00:00
|
|
|
// we need to reset the cursor's pit and pos now, as the old ones
|
|
|
|
// may no longer be valid.
|
|
|
|
cur.pit() = 0;
|
|
|
|
cur.pos() = 0;
|
2008-03-18 18:08:32 +00:00
|
|
|
bvcur.setCursor(cur);
|
2008-09-24 21:27:41 +00:00
|
|
|
bvcur.setSelection(true);
|
2008-03-18 18:08:32 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
// only update if selection changes
|
|
|
|
if (bvcur.idx() == cur.idx() &&
|
2010-04-15 18:16:07 +00:00
|
|
|
!(bvcur.realAnchor().idx() == cur.idx() && bvcur.pos() != cur.pos()))
|
2010-07-08 20:04:35 +00:00
|
|
|
cur.noScreenUpdate();
|
2010-04-09 19:00:42 +00:00
|
|
|
setCursorFromCoordinates(cur, cmd.x(), cmd.y());
|
2008-03-18 18:08:32 +00:00
|
|
|
bvcur.setCursor(cur);
|
2008-09-24 21:27:41 +00:00
|
|
|
bvcur.setSelection(true);
|
2008-08-08 19:34:47 +00:00
|
|
|
// if this is a multicell selection, we just set the cursor to
|
|
|
|
// the beginning of the cell's text.
|
2008-08-09 16:29:25 +00:00
|
|
|
if (bvcur.selIsMultiCell()) {
|
2008-10-01 08:18:57 +00:00
|
|
|
bvcur.pit() = bvcur.lastpit();
|
|
|
|
bvcur.pos() = bvcur.lastpos();
|
2008-08-08 19:34:47 +00:00
|
|
|
}
|
2004-08-14 21:23:16 +00:00
|
|
|
}
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-12-12 15:18:29 +00:00
|
|
|
|
2008-03-25 21:26:03 +00:00
|
|
|
case LFUN_MOUSE_RELEASE:
|
|
|
|
rowselect_ = false;
|
|
|
|
colselect_ = false;
|
|
|
|
break;
|
|
|
|
|
2004-02-16 11:58:51 +00:00
|
|
|
case LFUN_CELL_BACKWARD:
|
|
|
|
movePrevCell(cur);
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(false);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-12-12 15:18:29 +00:00
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
case LFUN_CELL_FORWARD:
|
2004-02-16 11:58:51 +00:00
|
|
|
moveNextCell(cur);
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(false);
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2008-08-09 00:43:15 +00:00
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHAR_FORWARD_SELECT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_CHAR_FORWARD:
|
2008-04-11 12:02:10 +00:00
|
|
|
case LFUN_CHAR_BACKWARD_SELECT:
|
|
|
|
case LFUN_CHAR_BACKWARD:
|
|
|
|
case LFUN_CHAR_RIGHT_SELECT:
|
|
|
|
case LFUN_CHAR_RIGHT:
|
|
|
|
case LFUN_CHAR_LEFT_SELECT:
|
2014-07-26 14:29:23 +00:00
|
|
|
case LFUN_CHAR_LEFT:
|
2010-10-25 01:18:48 +00:00
|
|
|
case LFUN_WORD_FORWARD:
|
|
|
|
case LFUN_WORD_FORWARD_SELECT:
|
|
|
|
case LFUN_WORD_BACKWARD:
|
|
|
|
case LFUN_WORD_BACKWARD_SELECT:
|
|
|
|
case LFUN_WORD_RIGHT:
|
|
|
|
case LFUN_WORD_RIGHT_SELECT:
|
|
|
|
case LFUN_WORD_LEFT:
|
|
|
|
case LFUN_WORD_LEFT_SELECT: {
|
2014-07-26 14:29:23 +00:00
|
|
|
// determine whether we move to next or previous cell, where to enter
|
2008-04-11 12:02:10 +00:00
|
|
|
// the new cell from, and which command to "finish" (i.e., exit the
|
|
|
|
// inset) with:
|
|
|
|
bool next_cell;
|
|
|
|
EntryDirection entry_from = ENTRY_DIRECTION_IGNORE;
|
|
|
|
FuncCode finish_lfun;
|
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
if (act == LFUN_CHAR_FORWARD
|
2010-10-25 01:18:48 +00:00
|
|
|
|| act == LFUN_CHAR_FORWARD_SELECT
|
|
|
|
|| act == LFUN_WORD_FORWARD
|
|
|
|
|| act == LFUN_WORD_FORWARD_SELECT) {
|
2008-04-11 12:02:10 +00:00
|
|
|
next_cell = true;
|
|
|
|
finish_lfun = LFUN_FINISHED_FORWARD;
|
|
|
|
}
|
2010-04-09 19:00:42 +00:00
|
|
|
else if (act == LFUN_CHAR_BACKWARD
|
2010-10-25 01:18:48 +00:00
|
|
|
|| act == LFUN_CHAR_BACKWARD_SELECT
|
|
|
|
|| act == LFUN_WORD_BACKWARD
|
|
|
|
|| act == LFUN_WORD_BACKWARD_SELECT) {
|
2008-04-11 12:02:10 +00:00
|
|
|
next_cell = false;
|
|
|
|
finish_lfun = LFUN_FINISHED_BACKWARD;
|
|
|
|
}
|
2014-07-26 14:29:23 +00:00
|
|
|
// LEFT or RIGHT commands --- the interpretation will depend on the
|
2008-04-11 12:02:10 +00:00
|
|
|
// table's direction.
|
|
|
|
else {
|
2010-04-09 19:00:42 +00:00
|
|
|
bool const right = act == LFUN_CHAR_RIGHT
|
2010-10-25 01:18:48 +00:00
|
|
|
|| act == LFUN_CHAR_RIGHT_SELECT
|
|
|
|
|| act == LFUN_WORD_RIGHT
|
|
|
|
|| act == LFUN_WORD_RIGHT_SELECT;
|
2009-02-05 22:14:57 +00:00
|
|
|
next_cell = isRightToLeft(cur) != right;
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2009-02-05 22:14:57 +00:00
|
|
|
if (lyxrc.visual_cursor)
|
2008-04-11 12:02:10 +00:00
|
|
|
entry_from = right ? ENTRY_DIRECTION_LEFT:ENTRY_DIRECTION_RIGHT;
|
|
|
|
|
2009-02-05 22:14:57 +00:00
|
|
|
finish_lfun = right ? LFUN_FINISHED_RIGHT : LFUN_FINISHED_LEFT;
|
2004-03-18 12:53:43 +00:00
|
|
|
}
|
2002-08-19 10:11:13 +00:00
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
bool const select = act == LFUN_CHAR_FORWARD_SELECT
|
2010-10-25 01:18:48 +00:00
|
|
|
|| act == LFUN_CHAR_BACKWARD_SELECT
|
|
|
|
|| act == LFUN_CHAR_RIGHT_SELECT
|
|
|
|
|| act == LFUN_CHAR_LEFT_SELECT
|
|
|
|
|| act == LFUN_WORD_FORWARD_SELECT
|
|
|
|
|| act == LFUN_WORD_RIGHT_SELECT
|
|
|
|
|| act == LFUN_WORD_BACKWARD_SELECT
|
|
|
|
|| act == LFUN_WORD_LEFT_SELECT;
|
2009-02-07 15:24:47 +00:00
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
// If we have a multicell selection or we're
|
2009-02-07 15:24:47 +00:00
|
|
|
// not doing some LFUN_*_SELECT thing anyway...
|
|
|
|
if (!cur.selIsMultiCell() || !select) {
|
|
|
|
col_type const c = tabular.cellColumn(cur.idx());
|
|
|
|
row_type const r = tabular.cellRow(cur.idx());
|
2014-07-26 14:29:23 +00:00
|
|
|
// Are we trying to select the whole cell and is the whole cell
|
2009-02-07 15:24:47 +00:00
|
|
|
// not yet selected?
|
|
|
|
bool const select_whole = select && !isCellSelected(cur, r, c) &&
|
2014-07-26 14:29:23 +00:00
|
|
|
((next_cell && cur.pit() == cur.lastpit()
|
2009-02-07 15:24:47 +00:00
|
|
|
&& cur.pos() == cur.lastpos())
|
|
|
|
|| (!next_cell && cur.pit() == 0 && cur.pos() == 0));
|
|
|
|
|
2009-08-18 18:34:22 +00:00
|
|
|
bool const empty_cell = cur.lastpos() == 0 && cur.lastpit() == 0;
|
|
|
|
|
2008-08-09 00:43:15 +00:00
|
|
|
// ...try to dispatch to the cell's inset.
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2009-02-07 15:24:47 +00:00
|
|
|
|
|
|
|
// When we already have a selection we want to select the whole cell
|
|
|
|
// before going to the next cell.
|
|
|
|
if (select_whole && !empty_cell){
|
|
|
|
getText(cur.idx())->selectAll(cur);
|
|
|
|
cur.dispatched();
|
2012-12-12 08:44:38 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
|
2009-02-07 15:24:47 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
// FIXME: When we support the selection of an empty cell, remove
|
2009-02-07 15:24:47 +00:00
|
|
|
// the !empty_cell from this condition. For now we jump to the next
|
|
|
|
// cell if the current cell is empty.
|
|
|
|
if (cur.result().dispatched() && !empty_cell)
|
2008-08-09 00:43:15 +00:00
|
|
|
break;
|
2004-03-18 12:53:43 +00:00
|
|
|
}
|
2009-02-07 15:24:47 +00:00
|
|
|
|
2008-08-09 00:43:15 +00:00
|
|
|
// move to next/prev cell, as appropriate
|
|
|
|
// note that we will always do this if we're selecting and we have
|
|
|
|
// a multicell selection
|
|
|
|
LYXERR(Debug::RTL, "entering " << (next_cell ? "next" : "previous")
|
|
|
|
<< " cell from: " << int(entry_from));
|
|
|
|
if (next_cell)
|
|
|
|
moveNextCell(cur, entry_from);
|
|
|
|
else
|
|
|
|
movePrevCell(cur, entry_from);
|
|
|
|
// if we're exiting the table, call the appropriate FINISHED lfun
|
2014-10-13 08:59:50 +00:00
|
|
|
if (sl == cur.top()) {
|
2008-08-09 00:43:15 +00:00
|
|
|
cmd = FuncRequest(finish_lfun);
|
2014-10-13 08:59:50 +00:00
|
|
|
cur.undispatched();
|
|
|
|
} else
|
2008-08-09 00:43:15 +00:00
|
|
|
cur.dispatched();
|
2011-03-15 08:54:46 +00:00
|
|
|
|
2011-03-15 18:43:09 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2008-04-11 12:02:10 +00:00
|
|
|
}
|
2007-10-22 22:18:52 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_DOWN_SELECT:
|
2004-02-13 16:22:53 +00:00
|
|
|
case LFUN_DOWN:
|
2008-11-19 01:02:48 +00:00
|
|
|
if (!(cur.selection() && cur.selIsMultiCell()))
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2004-03-27 12:40:39 +00:00
|
|
|
cur.dispatched(); // override the cell's decision
|
2008-11-19 01:02:48 +00:00
|
|
|
if (sl == cur.top()) {
|
2007-04-29 23:33:02 +00:00
|
|
|
// if our Text didn't do anything to the cursor
|
2005-07-18 10:24:35 +00:00
|
|
|
// then we try to put the cursor into the cell below
|
|
|
|
// setting also the right targetX.
|
2010-04-09 19:00:42 +00:00
|
|
|
cur.selHandle(act == LFUN_DOWN_SELECT);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (tabular.cellRow(cur.idx()) != tabular.nrows() - 1) {
|
Fix bug #7490.
As the bug report notes, you do NOT get this crash if you move up or
down in the table a bit before you do the rest. The reason is that
moving up and down sets the cursor's x_target_, and it is because that
is not set that we enter the other code at all and eventually crash.
That is, in InsetTabular's dispatch, we have:
(*) cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());
You can see the potential for trouble here already. cur.pit() is in the
NEW cell, i.e., the one to which we are moving; it was changed a few
lines previously, and cur.idx() points to the new cell, too. But we are
trying to calculate cur.pos(), which means that cur.pos() is currently
the one from the OLD cell. So the cursor is in an inconsistent state.
Calling cur.targetX() leads us to call Cursor::getPos(), and that is
what causes the crash.
We fix the problem by making sure we call targetX() on the original
cursor. The same problem clearly exists in the DOWN stuff, so we fix
that, too.
By the way, should we be setting x_target_ here once we have calculated
it?
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@38530 a592a061-630c-0410-9148-cb99ea01b6c8
2011-04-26 22:41:48 +00:00
|
|
|
int const xtarget = cur.targetX();
|
|
|
|
// WARNING: Once cur.idx() has been reset, the cursor is in
|
|
|
|
// an inconsistent state until pos() has been set. Be careful
|
|
|
|
// what you do with it!
|
2008-03-25 13:32:38 +00:00
|
|
|
cur.idx() = tabular.cellBelow(cur.idx());
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = 0;
|
2007-01-01 11:36:30 +00:00
|
|
|
TextMetrics const & tm =
|
|
|
|
cur.bv().textMetrics(cell(cur.idx())->getText(0));
|
Fix bug #7490.
As the bug report notes, you do NOT get this crash if you move up or
down in the table a bit before you do the rest. The reason is that
moving up and down sets the cursor's x_target_, and it is because that
is not set that we enter the other code at all and eventually crash.
That is, in InsetTabular's dispatch, we have:
(*) cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());
You can see the potential for trouble here already. cur.pit() is in the
NEW cell, i.e., the one to which we are moving; it was changed a few
lines previously, and cur.idx() points to the new cell, too. But we are
trying to calculate cur.pos(), which means that cur.pos() is currently
the one from the OLD cell. So the cursor is in an inconsistent state.
Calling cur.targetX() leads us to call Cursor::getPos(), and that is
what causes the crash.
We fix the problem by making sure we call targetX() on the original
cursor. The same problem clearly exists in the DOWN stuff, so we fix
that, too.
By the way, should we be setting x_target_ here once we have calculated
it?
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@38530 a592a061-630c-0410-9148-cb99ea01b6c8
2011-04-26 22:41:48 +00:00
|
|
|
cur.pos() = tm.x2pos(cur.pit(), 0, xtarget);
|
2009-12-17 17:47:09 +00:00
|
|
|
cur.setCurrentFont();
|
2004-02-16 11:58:51 +00:00
|
|
|
}
|
2008-11-19 01:02:48 +00:00
|
|
|
}
|
2004-03-18 12:53:43 +00:00
|
|
|
if (sl == cur.top()) {
|
2007-10-22 22:18:52 +00:00
|
|
|
// we trick it to go to forward after leaving the
|
2005-07-18 10:24:35 +00:00
|
|
|
// tabular.
|
2007-10-22 22:18:52 +00:00
|
|
|
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
|
2004-03-18 12:53:43 +00:00
|
|
|
cur.undispatched();
|
|
|
|
}
|
2008-10-01 08:18:57 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
|
|
|
cur.pit() = cur.lastpit();
|
|
|
|
cur.pos() = cur.lastpos();
|
2009-12-17 17:47:09 +00:00
|
|
|
cur.setCurrentFont();
|
2012-12-12 08:44:17 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
|
2008-10-01 08:18:57 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-12-12 08:43:53 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_UP_SELECT:
|
2004-02-13 16:22:53 +00:00
|
|
|
case LFUN_UP:
|
2008-11-19 01:02:48 +00:00
|
|
|
if (!(cur.selection() && cur.selIsMultiCell()))
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2004-03-27 12:40:39 +00:00
|
|
|
cur.dispatched(); // override the cell's decision
|
2008-11-19 01:02:48 +00:00
|
|
|
if (sl == cur.top()) {
|
2007-04-29 23:33:02 +00:00
|
|
|
// if our Text didn't do anything to the cursor
|
2005-07-18 10:24:35 +00:00
|
|
|
// then we try to put the cursor into the cell above
|
|
|
|
// setting also the right targetX.
|
2010-04-09 19:00:42 +00:00
|
|
|
cur.selHandle(act == LFUN_UP_SELECT);
|
2007-09-04 10:52:08 +00:00
|
|
|
if (tabular.cellRow(cur.idx()) != 0) {
|
Fix bug #7490.
As the bug report notes, you do NOT get this crash if you move up or
down in the table a bit before you do the rest. The reason is that
moving up and down sets the cursor's x_target_, and it is because that
is not set that we enter the other code at all and eventually crash.
That is, in InsetTabular's dispatch, we have:
(*) cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());
You can see the potential for trouble here already. cur.pit() is in the
NEW cell, i.e., the one to which we are moving; it was changed a few
lines previously, and cur.idx() points to the new cell, too. But we are
trying to calculate cur.pos(), which means that cur.pos() is currently
the one from the OLD cell. So the cursor is in an inconsistent state.
Calling cur.targetX() leads us to call Cursor::getPos(), and that is
what causes the crash.
We fix the problem by making sure we call targetX() on the original
cursor. The same problem clearly exists in the DOWN stuff, so we fix
that, too.
By the way, should we be setting x_target_ here once we have calculated
it?
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@38530 a592a061-630c-0410-9148-cb99ea01b6c8
2011-04-26 22:41:48 +00:00
|
|
|
int const xtarget = cur.targetX();
|
|
|
|
// WARNING: Once cur.idx() has been reset, the cursor is in
|
|
|
|
// an inconsistent state until pos() has been set. Be careful
|
|
|
|
// what you do with it!
|
2008-03-25 13:32:38 +00:00
|
|
|
cur.idx() = tabular.cellAbove(cur.idx());
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = cur.lastpit();
|
2007-04-29 23:33:02 +00:00
|
|
|
Text const * text = cell(cur.idx())->getText(0);
|
2007-01-01 11:36:30 +00:00
|
|
|
TextMetrics const & tm = cur.bv().textMetrics(text);
|
2006-12-29 23:54:48 +00:00
|
|
|
ParagraphMetrics const & pm =
|
2007-01-01 11:36:30 +00:00
|
|
|
tm.parMetrics(cur.lastpit());
|
Fix bug #7490.
As the bug report notes, you do NOT get this crash if you move up or
down in the table a bit before you do the rest. The reason is that
moving up and down sets the cursor's x_target_, and it is because that
is not set that we enter the other code at all and eventually crash.
That is, in InsetTabular's dispatch, we have:
(*) cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());
You can see the potential for trouble here already. cur.pit() is in the
NEW cell, i.e., the one to which we are moving; it was changed a few
lines previously, and cur.idx() points to the new cell, too. But we are
trying to calculate cur.pos(), which means that cur.pos() is currently
the one from the OLD cell. So the cursor is in an inconsistent state.
Calling cur.targetX() leads us to call Cursor::getPos(), and that is
what causes the crash.
We fix the problem by making sure we call targetX() on the original
cursor. The same problem clearly exists in the DOWN stuff, so we fix
that, too.
By the way, should we be setting x_target_ here once we have calculated
it?
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@38530 a592a061-630c-0410-9148-cb99ea01b6c8
2011-04-26 22:41:48 +00:00
|
|
|
cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, xtarget);
|
2009-12-17 17:47:09 +00:00
|
|
|
cur.setCurrentFont();
|
2004-02-16 11:58:51 +00:00
|
|
|
}
|
2008-11-19 01:02:48 +00:00
|
|
|
}
|
2004-03-18 12:53:43 +00:00
|
|
|
if (sl == cur.top()) {
|
2007-05-29 20:53:32 +00:00
|
|
|
cmd = FuncRequest(LFUN_UP);
|
2004-03-18 12:53:43 +00:00
|
|
|
cur.undispatched();
|
|
|
|
}
|
2008-10-01 08:18:57 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
2008-11-19 01:02:48 +00:00
|
|
|
cur.pit() = 0;
|
2008-10-01 08:18:57 +00:00
|
|
|
cur.pos() = cur.lastpos();
|
2009-12-17 17:47:09 +00:00
|
|
|
cur.setCurrentFont();
|
2012-12-12 08:44:17 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
|
2008-10-01 08:18:57 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-12-12 08:43:53 +00:00
|
|
|
cur.screenUpdateFlags(Update::Force | Update::FitCursor);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
// case LFUN_SCREEN_DOWN: {
|
2004-11-30 01:59:49 +00:00
|
|
|
// //if (hasSelection())
|
|
|
|
// // cur.selection() = false;
|
2007-09-04 10:52:08 +00:00
|
|
|
// col_type const col = tabular.cellColumn(cur.idx());
|
2006-07-13 16:37:55 +00:00
|
|
|
// int const t = cur.bv().top_y() + cur.bv().height();
|
2004-11-30 01:59:49 +00:00
|
|
|
// if (t < yo() + tabular.getHeightOfTabular()) {
|
2010-06-14 21:48:23 +00:00
|
|
|
// cur.bv().scrollDocView(t, true);
|
2008-03-25 13:32:38 +00:00
|
|
|
// cur.idx() = tabular.cellBelow(first_visible_cell) + col;
|
2004-11-30 01:59:49 +00:00
|
|
|
// } else {
|
|
|
|
// cur.idx() = tabular.getFirstCellInRow(tabular.rows() - 1) + col;
|
|
|
|
// }
|
|
|
|
// cur.par() = 0;
|
|
|
|
// cur.pos() = 0;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//
|
2006-05-05 20:23:12 +00:00
|
|
|
// case LFUN_SCREEN_UP: {
|
2004-11-30 01:59:49 +00:00
|
|
|
// //if (hasSelection())
|
|
|
|
// // cur.selection() = false;
|
2007-09-04 10:52:08 +00:00
|
|
|
// col_type const col = tabular.cellColumn(cur.idx());
|
2006-07-13 16:37:55 +00:00
|
|
|
// int const t = cur.bv().top_y() + cur.bv().height();
|
2004-11-30 01:59:49 +00:00
|
|
|
// if (yo() < 0) {
|
2010-06-14 21:48:23 +00:00
|
|
|
// cur.bv().scrollDocView(t, true);
|
2004-11-30 01:59:49 +00:00
|
|
|
// if (yo() > 0)
|
|
|
|
// cur.idx() = col;
|
|
|
|
// else
|
2008-03-25 13:32:38 +00:00
|
|
|
// cur.idx() = tabular.cellBelow(first_visible_cell) + col;
|
2004-11-30 01:59:49 +00:00
|
|
|
// } else {
|
|
|
|
// cur.idx() = col;
|
|
|
|
// }
|
|
|
|
// cur.par() = cur.lastpar();
|
|
|
|
// cur.pos() = cur.lastpos();
|
|
|
|
// break;
|
|
|
|
// }
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
case LFUN_LAYOUT_TABULAR:
|
2010-02-18 08:28:46 +00:00
|
|
|
cur.bv().showDialog("tabular");
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2011-12-05 12:40:22 +00:00
|
|
|
case LFUN_INSET_MODIFY: {
|
|
|
|
string arg;
|
|
|
|
if (cmd.getArg(1) == "from-dialog")
|
|
|
|
arg = cmd.getArg(0) + to_utf8(cmd.argument().substr(19));
|
|
|
|
else
|
|
|
|
arg = to_utf8(cmd.argument());
|
|
|
|
if (!tabularFeatures(cur, arg))
|
2004-03-01 17:12:09 +00:00
|
|
|
cur.undispatched();
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2011-12-05 12:40:22 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
// insert file functions
|
2007-01-15 22:49:14 +00:00
|
|
|
case LFUN_FILE_INSERT_PLAINTEXT_PARA:
|
2009-05-12 00:15:16 +00:00
|
|
|
case LFUN_FILE_INSERT_PLAINTEXT:
|
2006-12-04 14:45:17 +00:00
|
|
|
// FIXME UNICODE
|
2009-05-12 00:15:16 +00:00
|
|
|
if (FileName::isAbsolute(to_utf8(cmd.argument()))) {
|
|
|
|
docstring const tmpstr = cur.bv().contentsOfPlaintextFile(
|
|
|
|
FileName(to_utf8(cmd.argument())));
|
|
|
|
if (tmpstr.empty())
|
|
|
|
break;
|
2014-07-19 22:50:24 +00:00
|
|
|
cur.recordUndoInset();
|
2009-05-12 00:15:16 +00:00
|
|
|
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();
|
|
|
|
}
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
case LFUN_CUT:
|
2008-08-09 16:29:25 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
2005-03-17 15:57:41 +00:00
|
|
|
if (copySelection(cur)) {
|
2014-07-19 22:50:24 +00:00
|
|
|
cur.recordUndoInset();
|
2005-03-17 15:57:41 +00:00
|
|
|
cutSelection(cur);
|
|
|
|
}
|
2009-05-17 21:22:02 +00:00
|
|
|
} else
|
2005-03-17 15:57:41 +00:00
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2008-10-01 08:18:57 +00:00
|
|
|
case LFUN_SELF_INSERT:
|
|
|
|
if (cur.selIsMultiCell()) {
|
2014-07-19 22:50:24 +00:00
|
|
|
cur.recordUndoInset();
|
2008-10-01 08:18:57 +00:00
|
|
|
cutSelection(cur);
|
2014-03-02 12:21:59 +00:00
|
|
|
BufferView * bv = &cur.bv();
|
|
|
|
docstring::const_iterator cit = cmd.argument().begin();
|
|
|
|
docstring::const_iterator const end = cmd.argument().end();
|
|
|
|
for (; cit != end; ++cit)
|
|
|
|
bv->translateAndInsert(*cit, getText(cur.idx()), cur);
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2014-03-02 12:21:59 +00:00
|
|
|
cur.resetAnchor();
|
|
|
|
bv->bookmarkEditPosition();
|
|
|
|
} else
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2008-10-01 08:18:57 +00:00
|
|
|
break;
|
|
|
|
|
2006-05-08 18:09:19 +00:00
|
|
|
case LFUN_CHAR_DELETE_BACKWARD:
|
|
|
|
case LFUN_CHAR_DELETE_FORWARD:
|
2008-08-09 16:29:25 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
2014-07-19 22:50:24 +00:00
|
|
|
cur.recordUndoInset();
|
2004-02-13 16:22:53 +00:00
|
|
|
cutSelection(cur);
|
2009-07-12 14:36:42 +00:00
|
|
|
} else
|
2004-11-23 23:04:52 +00:00
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2004-01-08 18:30:14 +00:00
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
case LFUN_COPY:
|
|
|
|
if (!cur.selection())
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2008-08-09 16:29:25 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
2007-10-18 11:51:17 +00:00
|
|
|
cur.finishUndo();
|
2005-03-17 15:57:41 +00:00
|
|
|
copySelection(cur);
|
|
|
|
} else
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2003-11-10 09:06:48 +00:00
|
|
|
|
Split clipboard and X selection
* src/LyXAction.C
(LyXAction::init): handle new LFUN_CLIPBOARD_PASTE
* src/insets/insettabular.C
(InsetTabular::doDispatch): ditto
* src/insets/insetbox.C
(InsetBox::doDispatch): ditto
* src/insets/insetert.C
(InsetERT::doDispatch): ditto
(InsetERT::getStatus): ditto
* src/insets/insetcharstyle.C
(InsetCharStyle::doDispatch): ditto
* src/BufferView_pimpl.C
(BufferView::Pimpl::selectionRequest): stuff selection, not clipboard
* src/mathed/math_nestinset.C
(MathNestInset::lfunMousePress): get stuff selection, not clipboard
(MathNestInset::lfunMouseRelease): clipboard -> selection in
commented code
* src/CutAndPaste.C
(cutSelection): ditto
* src/frontends/{qt3,gtk}/GuiImplementation.C
(GuiImplementation::newWorkArea): create new selection, not clipboard,
since the clipboard is now an object
(GuiImplementation::destroyWorkArea): destroy selection, not clipboard
* src/frontends/{qt4,qt3,gtk}/GuiSelection.h: new, copied from
GuiClipboard.h
* src/frontends/{qt4,qt3,gtk}/GuiSelection.C: new, copied from
GuiClipboard.C
* src/frontends/{qt3,gtk}/GuiImplementation.h
(selection): new accessor for selection_
(selection_): new, the global selection object
* src/frontends/{qt4,qt3,gtk}/Makefile.am: add GuiSelection.C and
GuiSelection.h
* src/frontends/{qt4,qt3,gtk}/GuiClipboard.C
(GuiClipboard::get): return clipboard, not selection
(GuiClipboard::put): stuff clipboard, not selection
* src/frontends/{qt4,qt3,gtk}/GuiClipboard.h
(haveSelection): remove (this is now in GuiSelection)
* src/frontends/{qt3,gtk}/GuiClipboard.h
(old_work_area_): remove, since it is not needed anymore
* src/frontends/gtk/ghelpers.C
(getGTKStockIcon): handle LFUN_CLIPBOARD_PASTE
* src/frontends/Clipboard.h
(haveSelection): remove (this is now in Selection)
* src/frontends/qt4/GuiImplementation.[Ch]
(GuiImplementation::selection): new accessor for selection_
* src/frontends/Gui.h
(selection): New accessor for the global selection object
* src/frontends/Selection.h; new, copied from Clipboard.h
* src/frontends/Makefile.am: add Selection.h
* src/text3.C
(various): s/clipboard().haveSelection/selection().haveSelection/
(LyXText::dispatch): handle LFUN_CLIPBOARD_PASTE
(LyXText::getStatus): ditto
* src/lfuns.h: new lfun LFUN_CLIPBOARD_PASTE
* lib/ui/stdmenus.ui: add new lfun LFUN_CLIPBOARD_PASTE
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@14408 a592a061-630c-0410-9148-cb99ea01b6c8
2006-07-10 11:32:25 +00:00
|
|
|
case LFUN_CLIPBOARD_PASTE:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_PRIMARY_SELECTION_PASTE: {
|
2010-04-09 19:00:42 +00:00
|
|
|
docstring const clip = (act == LFUN_CLIPBOARD_PASTE) ?
|
2013-04-14 17:45:36 +00:00
|
|
|
theClipboard().getAsText(Clipboard::PlainTextType) :
|
2006-10-11 17:24:46 +00:00
|
|
|
theSelection().get();
|
2004-02-13 16:22:53 +00:00
|
|
|
if (clip.empty())
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2007-01-15 22:49:14 +00:00
|
|
|
// pass to InsertPlaintextString, but
|
2006-05-22 10:19:27 +00:00
|
|
|
// only if we have multi-cell content
|
2006-10-21 00:16:43 +00:00
|
|
|
if (clip.find_first_of(from_ascii("\t\n")) != docstring::npos) {
|
2014-07-19 22:50:24 +00:00
|
|
|
cur.recordUndoInset();
|
2007-01-15 22:49:14 +00:00
|
|
|
if (insertPlaintextString(cur.bv(), clip, false)) {
|
2006-05-22 10:19:27 +00:00
|
|
|
// content has been replaced,
|
|
|
|
// so cursor might be invalid
|
|
|
|
cur.pos() = cur.lastpos();
|
2007-12-02 15:19:39 +00:00
|
|
|
cur.pit() = cur.lastpit();
|
2006-05-22 10:19:27 +00:00
|
|
|
bvcur.setCursor(cur);
|
|
|
|
break;
|
|
|
|
}
|
2001-01-03 16:04:05 +00:00
|
|
|
}
|
2007-01-04 09:48:54 +00:00
|
|
|
// Let the cell handle normal text
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2007-01-04 09:50:25 +00:00
|
|
|
break;
|
2004-02-13 16:22:53 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
case LFUN_PASTE:
|
2008-05-22 10:44:28 +00:00
|
|
|
if (!tabularStackDirty()) {
|
2009-05-17 21:22:02 +00:00
|
|
|
if (!cur.selIsMultiCell())
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2008-05-22 10:44:28 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-12-11 23:04:24 +00:00
|
|
|
if (theClipboard().isInternal()) {
|
2014-07-19 22:50:24 +00:00
|
|
|
cur.recordUndoInset();
|
2007-02-02 03:10:15 +00:00
|
|
|
pasteClipboard(cur);
|
2001-04-04 09:42:56 +00:00
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
break;
|
2003-11-10 09:06:48 +00:00
|
|
|
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_EMPH:
|
|
|
|
case LFUN_FONT_BOLD:
|
2008-09-15 16:49:11 +00:00
|
|
|
case LFUN_FONT_BOLDSYMBOL:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_ROMAN:
|
|
|
|
case LFUN_FONT_NOUN:
|
|
|
|
case LFUN_FONT_ITAL:
|
|
|
|
case LFUN_FONT_FRAK:
|
2007-09-20 18:02:39 +00:00
|
|
|
case LFUN_FONT_TYPEWRITER:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_SANS:
|
2008-06-11 08:35:15 +00:00
|
|
|
case LFUN_TEXTSTYLE_APPLY:
|
|
|
|
case LFUN_TEXTSTYLE_UPDATE:
|
2005-03-17 13:23:14 +00:00
|
|
|
case LFUN_FONT_SIZE:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FONT_UNDERLINE:
|
2009-05-03 22:45:14 +00:00
|
|
|
case LFUN_FONT_STRIKEOUT:
|
2014-02-11 10:00:20 +00:00
|
|
|
case LFUN_FONT_UNDERUNDERLINE:
|
|
|
|
case LFUN_FONT_UNDERWAVE:
|
2005-03-17 13:23:14 +00:00
|
|
|
case LFUN_LANGUAGE:
|
2013-10-04 10:52:00 +00:00
|
|
|
case LFUN_PARAGRAPH_PARAMS_APPLY:
|
|
|
|
case LFUN_PARAGRAPH_PARAMS:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WORD_CAPITALIZE:
|
|
|
|
case LFUN_WORD_UPCASE:
|
|
|
|
case LFUN_WORD_LOWCASE:
|
|
|
|
case LFUN_CHARS_TRANSPOSE:
|
2008-08-09 16:29:25 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
2005-03-13 10:36:42 +00:00
|
|
|
row_type rs, re;
|
|
|
|
col_type cs, ce;
|
|
|
|
getSelection(cur, rs, re, cs, ce);
|
2007-04-26 14:56:30 +00:00
|
|
|
Cursor tmpcur = cur;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = rs; r <= re; ++r) {
|
|
|
|
for (col_type c = cs; c <= ce; ++c) {
|
2005-03-13 10:36:42 +00:00
|
|
|
// cursor follows cell:
|
2010-03-05 18:10:34 +00:00
|
|
|
tmpcur.idx() = tabular.cellIndex(r, c);
|
2005-03-13 10:36:42 +00:00
|
|
|
// select this cell only:
|
2006-09-21 10:43:49 +00:00
|
|
|
tmpcur.pit() = 0;
|
|
|
|
tmpcur.pos() = 0;
|
|
|
|
tmpcur.resetAnchor();
|
|
|
|
tmpcur.pit() = tmpcur.lastpit();
|
|
|
|
tmpcur.pos() = tmpcur.top().lastpos();
|
|
|
|
tmpcur.setCursor(tmpcur);
|
|
|
|
tmpcur.setSelection();
|
|
|
|
cell(tmpcur.idx())->dispatch(tmpcur, cmd);
|
2005-03-13 10:36:42 +00:00
|
|
|
}
|
2005-07-16 18:25:58 +00:00
|
|
|
}
|
2005-03-13 10:36:42 +00:00
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
|
|
|
break;
|
|
|
|
}
|
2009-04-10 00:17:34 +00:00
|
|
|
|
|
|
|
case LFUN_INSET_SETTINGS:
|
|
|
|
// relay this lfun to Inset, not to the cell.
|
|
|
|
Inset::doDispatch(cur, cmd);
|
|
|
|
break;
|
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
default:
|
2004-02-16 11:58:51 +00:00
|
|
|
// we try to handle this event in the insets dispatch function.
|
2004-11-23 23:04:52 +00:00
|
|
|
cell(cur.idx())->dispatch(cur, cmd);
|
2004-02-13 16:22:53 +00:00
|
|
|
break;
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-27 12:40:39 +00:00
|
|
|
// function sets an object as defined in func_status.h:
|
|
|
|
// states OK, Unknown, Disabled, On, Off.
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd,
|
2004-03-27 12:40:39 +00:00
|
|
|
FuncStatus & status) const
|
2004-03-18 13:57:20 +00:00
|
|
|
{
|
2010-04-09 19:00:42 +00:00
|
|
|
switch (cmd.action()) {
|
2010-02-18 08:28:46 +00:00
|
|
|
case LFUN_INSET_MODIFY: {
|
2014-07-26 14:29:23 +00:00
|
|
|
if (&cur.inset() != this || cmd.getArg(0) != "tabular")
|
2010-02-18 08:28:46 +00:00
|
|
|
break;
|
2010-03-09 23:04:59 +00:00
|
|
|
|
2010-02-18 08:28:46 +00:00
|
|
|
// FIXME: We only check for the very first argument...
|
2011-02-16 23:09:29 +00:00
|
|
|
string const s = cmd.getArg(1);
|
|
|
|
// We always enable the lfun if it is coming from the dialog
|
|
|
|
// because the dialog makes sure all the settings are valid,
|
|
|
|
// even though the first argument might not be valid now.
|
|
|
|
if (s == "from-dialog") {
|
|
|
|
status.setEnabled(true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
int action = Tabular::LAST_ACTION;
|
2004-03-27 12:40:39 +00:00
|
|
|
int i = 0;
|
2007-04-26 12:54:21 +00:00
|
|
|
for (; tabularFeature[i].action != Tabular::LAST_ACTION; ++i) {
|
2010-03-09 23:04:59 +00:00
|
|
|
if (tabularFeature[i].feature == s) {
|
2004-03-27 12:40:39 +00:00
|
|
|
action = tabularFeature[i].action;
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-03-27 12:40:39 +00:00
|
|
|
}
|
2007-04-26 12:54:21 +00:00
|
|
|
if (action == Tabular::LAST_ACTION) {
|
2004-03-27 12:40:39 +00:00
|
|
|
status.clear();
|
2010-04-16 10:51:20 +00:00
|
|
|
status.setUnknown(true);
|
2004-03-27 12:40:39 +00:00
|
|
|
return true;
|
|
|
|
}
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2010-03-09 23:04:59 +00:00
|
|
|
string const argument = cmd.getLongArg(2);
|
2004-03-27 12:40:39 +00:00
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
row_type sel_row_start = 0;
|
|
|
|
row_type sel_row_end = 0;
|
2007-05-12 20:59:21 +00:00
|
|
|
col_type sel_col_start = 0;
|
|
|
|
col_type sel_col_end = 0;
|
2007-04-26 12:54:21 +00:00
|
|
|
Tabular::ltType dummyltt;
|
2004-03-27 12:40:39 +00:00
|
|
|
bool flag = true;
|
|
|
|
|
2007-05-12 20:59:21 +00:00
|
|
|
getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
|
2004-03-27 12:40:39 +00:00
|
|
|
|
|
|
|
switch (action) {
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_PWIDTH:
|
|
|
|
case Tabular::SET_MPWIDTH:
|
|
|
|
case Tabular::SET_SPECIAL_COLUMN:
|
2010-02-11 01:07:54 +00:00
|
|
|
case Tabular::SET_SPECIAL_MULTICOLUMN:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::APPEND_ROW:
|
|
|
|
case Tabular::APPEND_COLUMN:
|
|
|
|
case Tabular::DELETE_ROW:
|
|
|
|
case Tabular::DELETE_COLUMN:
|
|
|
|
case Tabular::COPY_ROW:
|
|
|
|
case Tabular::COPY_COLUMN:
|
|
|
|
case Tabular::SET_TOP_SPACE:
|
|
|
|
case Tabular::SET_BOTTOM_SPACE:
|
|
|
|
case Tabular::SET_INTERLINE_SPACE:
|
2004-03-27 12:40:39 +00:00
|
|
|
status.clear();
|
|
|
|
return true;
|
|
|
|
|
2011-02-03 23:11:26 +00:00
|
|
|
case Tabular::SET_TABULAR_WIDTH:
|
2011-02-16 23:06:43 +00:00
|
|
|
status.setEnabled(!tabular.rotate && !tabular.is_long_tabular
|
|
|
|
&& tabular.tabular_valignment == Tabular::LYX_VALIGN_MIDDLE);
|
2011-02-03 23:11:26 +00:00
|
|
|
break;
|
|
|
|
|
2012-12-24 10:51:28 +00:00
|
|
|
case Tabular::MOVE_COLUMN_RIGHT:
|
|
|
|
case Tabular::MOVE_COLUMN_LEFT:
|
|
|
|
case Tabular::MOVE_ROW_DOWN:
|
|
|
|
case Tabular::MOVE_ROW_UP: {
|
|
|
|
if (cur.selection()) {
|
|
|
|
status.message(_("Selections not supported."));
|
|
|
|
status.setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((action == Tabular::MOVE_COLUMN_RIGHT &&
|
|
|
|
tabular.ncols() == tabular.cellColumn(cur.idx()) + 1) ||
|
|
|
|
(action == Tabular::MOVE_COLUMN_LEFT &&
|
|
|
|
tabular.cellColumn(cur.idx()) == 0) ||
|
|
|
|
(action == Tabular::MOVE_ROW_DOWN &&
|
|
|
|
tabular.nrows() == tabular.cellRow(cur.idx()) + 1) ||
|
|
|
|
(action == Tabular::MOVE_ROW_UP &&
|
|
|
|
tabular.cellRow(cur.idx()) == 0)) {
|
|
|
|
status.setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action == Tabular::MOVE_COLUMN_RIGHT ||
|
|
|
|
action == Tabular::MOVE_COLUMN_LEFT) {
|
|
|
|
if (tabular.hasMultiColumn(tabular.cellColumn(cur.idx())) ||
|
|
|
|
tabular.hasMultiColumn(tabular.cellColumn(cur.idx()) +
|
|
|
|
(action == Tabular::MOVE_COLUMN_RIGHT ? 1 : -1))) {
|
|
|
|
status.message(_("Multi-column in current or"
|
|
|
|
" destination column."));
|
|
|
|
status.setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (action == Tabular::MOVE_ROW_DOWN ||
|
|
|
|
action == Tabular::MOVE_ROW_UP) {
|
|
|
|
if (tabular.hasMultiRow(tabular.cellRow(cur.idx())) ||
|
|
|
|
tabular.hasMultiRow(tabular.cellRow(cur.idx()) +
|
|
|
|
(action == Tabular::MOVE_ROW_DOWN ? 1 : -1))) {
|
|
|
|
status.message(_("Multi-row in current or"
|
|
|
|
" destination row."));
|
|
|
|
status.setEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
status.setEnabled(true);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-06-05 07:44:44 +00:00
|
|
|
case Tabular::SET_DECIMAL_POINT:
|
|
|
|
status.setEnabled(
|
|
|
|
tabular.getAlignment(cur.idx()) == LYX_ALIGN_DECIMAL);
|
|
|
|
break;
|
|
|
|
|
2010-10-29 04:09:49 +00:00
|
|
|
case Tabular::SET_MULTICOLUMN:
|
|
|
|
case Tabular::UNSET_MULTICOLUMN:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::MULTICOLUMN:
|
2009-05-18 06:22:25 +00:00
|
|
|
// If a row is set as longtable caption, it must not be allowed
|
2009-02-12 03:02:34 +00:00
|
|
|
// to unset that this row is a multicolumn.
|
|
|
|
status.setEnabled(sel_row_start == sel_row_end
|
2010-03-04 20:20:45 +00:00
|
|
|
&& !tabular.ltCaption(tabular.cellRow(cur.idx())));
|
2004-10-23 09:21:38 +00:00
|
|
|
status.setOnOff(tabular.isMultiColumn(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2010-10-29 04:09:49 +00:00
|
|
|
case Tabular::SET_MULTIROW:
|
|
|
|
case Tabular::UNSET_MULTIROW:
|
2010-02-11 01:07:54 +00:00
|
|
|
case Tabular::MULTIROW:
|
|
|
|
// If a row is set as longtable caption, it must not be allowed
|
|
|
|
// to unset that this row is a multirow.
|
|
|
|
status.setEnabled(sel_col_start == sel_col_end
|
2010-03-04 20:20:45 +00:00
|
|
|
&& !tabular.ltCaption(tabular.cellRow(cur.idx())));
|
2010-02-11 01:07:54 +00:00
|
|
|
status.setOnOff(tabular.isMultiRow(cur.idx()));
|
|
|
|
break;
|
|
|
|
|
2008-05-04 07:51:50 +00:00
|
|
|
case Tabular::SET_ALL_LINES:
|
|
|
|
case Tabular::UNSET_ALL_LINES:
|
|
|
|
case Tabular::SET_BORDER_LINES:
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
|
2008-05-04 07:51:50 +00:00
|
|
|
break;
|
|
|
|
|
2010-02-19 10:03:03 +00:00
|
|
|
case Tabular::SET_LINE_TOP:
|
|
|
|
case Tabular::SET_LINE_BOTTOM:
|
|
|
|
case Tabular::SET_LINE_LEFT:
|
|
|
|
case Tabular::SET_LINE_RIGHT:
|
|
|
|
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_TOP:
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
|
2008-03-18 18:08:32 +00:00
|
|
|
status.setOnOff(tabular.topLine(cur.idx()));
|
2004-03-18 13:57:20 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_BOTTOM:
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
|
2008-03-18 18:08:32 +00:00
|
|
|
status.setOnOff(tabular.bottomLine(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_LEFT:
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
|
2008-03-18 18:08:32 +00:00
|
|
|
status.setOnOff(tabular.leftLine(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_RIGHT:
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(!tabular.ltCaption(tabular.cellRow(cur.idx())));
|
2008-03-18 18:08:32 +00:00
|
|
|
status.setOnOff(tabular.rightLine(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2010-11-20 07:57:35 +00:00
|
|
|
// multirow cells only inherit the alignment of the column if the column has
|
|
|
|
// no width, otherwise they are left-aligned
|
|
|
|
// therefore allow always left but right and center only if there is no width
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_ALIGN_LEFT:
|
2004-03-27 12:40:39 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::ALIGN_LEFT:
|
2004-10-23 09:21:38 +00:00
|
|
|
status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_LEFT);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_ALIGN_RIGHT:
|
2004-03-27 12:40:39 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::ALIGN_RIGHT:
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setEnabled(!(tabular.isMultiRow(cur.idx())
|
2010-11-20 07:57:35 +00:00
|
|
|
&& !tabular.getPWidth(cur.idx()).zero()));
|
2004-10-23 09:21:38 +00:00
|
|
|
status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_RIGHT);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_ALIGN_CENTER:
|
2004-03-27 12:40:39 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::ALIGN_CENTER:
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setEnabled(!(tabular.isMultiRow(cur.idx())
|
2010-11-20 07:57:35 +00:00
|
|
|
&& !tabular.getPWidth(cur.idx()).zero()));
|
2004-10-23 09:21:38 +00:00
|
|
|
status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_CENTER);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::ALIGN_BLOCK:
|
2010-03-05 03:37:21 +00:00
|
|
|
status.setEnabled(!tabular.getPWidth(cur.idx()).zero()
|
|
|
|
&& !tabular.isMultiRow(cur.idx()));
|
2004-10-23 09:21:38 +00:00
|
|
|
status.setOnOff(tabular.getAlignment(cur.idx(), flag) == LYX_ALIGN_BLOCK);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2010-06-05 07:44:44 +00:00
|
|
|
case Tabular::ALIGN_DECIMAL:
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setEnabled(!tabular.isMultiRow(cur.idx())
|
2010-06-05 07:44:44 +00:00
|
|
|
&& !tabular.isMultiColumn(cur.idx()));
|
|
|
|
status.setOnOff(tabular.getAlignment(cur.idx(), true) == LYX_ALIGN_DECIMAL);
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_VALIGN_TOP:
|
2004-03-27 12:40:39 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::VALIGN_TOP:
|
2010-03-05 03:37:21 +00:00
|
|
|
status.setEnabled(!tabular.getPWidth(cur.idx()).zero()
|
|
|
|
&& !tabular.isMultiRow(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
status.setOnOff(
|
2007-04-26 12:54:21 +00:00
|
|
|
tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_TOP);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_VALIGN_BOTTOM:
|
2004-03-27 12:40:39 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::VALIGN_BOTTOM:
|
2010-03-05 03:37:21 +00:00
|
|
|
status.setEnabled(!tabular.getPWidth(cur.idx()).zero()
|
|
|
|
&& !tabular.isMultiRow(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
status.setOnOff(
|
2007-04-26 12:54:21 +00:00
|
|
|
tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_BOTTOM);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_VALIGN_MIDDLE:
|
2004-03-27 12:40:39 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::VALIGN_MIDDLE:
|
2010-03-05 03:37:21 +00:00
|
|
|
status.setEnabled(!tabular.getPWidth(cur.idx()).zero()
|
|
|
|
&& !tabular.isMultiRow(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
status.setOnOff(
|
2007-04-26 12:54:21 +00:00
|
|
|
tabular.getVAlignment(cur.idx(), flag) == Tabular::LYX_VALIGN_MIDDLE);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LONGTABULAR:
|
2010-10-29 01:18:18 +00:00
|
|
|
// setting as longtable is not allowed when table is inside a float
|
2010-10-29 01:29:53 +00:00
|
|
|
if (cur.innerInsetOfType(FLOAT_CODE) != 0
|
|
|
|
|| cur.innerInsetOfType(WRAP_CODE) != 0)
|
2010-10-29 01:18:18 +00:00
|
|
|
status.setEnabled(false);
|
2010-10-29 04:09:49 +00:00
|
|
|
else
|
|
|
|
status.setEnabled(true);
|
2008-04-21 13:33:39 +00:00
|
|
|
status.setOnOff(tabular.is_long_tabular);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LONGTABULAR:
|
2008-04-21 13:33:39 +00:00
|
|
|
status.setOnOff(!tabular.is_long_tabular);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-05-12 20:59:21 +00:00
|
|
|
case Tabular::TOGGLE_ROTATE_TABULAR:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_ROTATE_TABULAR:
|
2012-03-21 22:04:45 +00:00
|
|
|
status.setOnOff(tabular.rotate != 0);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2009-01-03 18:33:09 +00:00
|
|
|
case Tabular::TABULAR_VALIGN_TOP:
|
2011-02-03 23:11:26 +00:00
|
|
|
status.setEnabled(tabular.tabular_width.zero());
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setOnOff(tabular.tabular_valignment
|
2009-01-03 18:33:09 +00:00
|
|
|
== Tabular::LYX_VALIGN_TOP);
|
|
|
|
break;
|
|
|
|
case Tabular::TABULAR_VALIGN_MIDDLE:
|
2011-02-03 23:11:26 +00:00
|
|
|
status.setEnabled(tabular.tabular_width.zero());
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setOnOff(tabular.tabular_valignment
|
2009-01-03 18:33:09 +00:00
|
|
|
== Tabular::LYX_VALIGN_MIDDLE);
|
|
|
|
break;
|
|
|
|
case Tabular::TABULAR_VALIGN_BOTTOM:
|
2011-02-03 23:11:26 +00:00
|
|
|
status.setEnabled(tabular.tabular_width.zero());
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setOnOff(tabular.tabular_valignment
|
2009-01-03 18:33:09 +00:00
|
|
|
== Tabular::LYX_VALIGN_BOTTOM);
|
|
|
|
break;
|
|
|
|
|
2009-07-11 13:09:45 +00:00
|
|
|
case Tabular::LONGTABULAR_ALIGN_LEFT:
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setOnOff(tabular.longtabular_alignment
|
2009-07-11 13:09:45 +00:00
|
|
|
== Tabular::LYX_LONGTABULAR_ALIGN_LEFT);
|
|
|
|
break;
|
|
|
|
case Tabular::LONGTABULAR_ALIGN_CENTER:
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setOnOff(tabular.longtabular_alignment
|
2009-07-11 13:09:45 +00:00
|
|
|
== Tabular::LYX_LONGTABULAR_ALIGN_CENTER);
|
|
|
|
break;
|
|
|
|
case Tabular::LONGTABULAR_ALIGN_RIGHT:
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setOnOff(tabular.longtabular_alignment
|
2009-07-11 13:09:45 +00:00
|
|
|
== Tabular::LYX_LONGTABULAR_ALIGN_RIGHT);
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_ROTATE_TABULAR:
|
2012-03-21 22:04:45 +00:00
|
|
|
status.setOnOff(tabular.rotate == 0);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-05-12 20:59:21 +00:00
|
|
|
case Tabular::TOGGLE_ROTATE_CELL:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_ROTATE_CELL:
|
2007-05-28 22:27:45 +00:00
|
|
|
status.setOnOff(!oneCellHasRotationState(false,
|
2007-05-12 20:59:21 +00:00
|
|
|
sel_row_start, sel_row_end, sel_col_start, sel_col_end));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_ROTATE_CELL:
|
2007-05-28 22:27:45 +00:00
|
|
|
status.setOnOff(!oneCellHasRotationState(true,
|
2007-05-12 20:59:21 +00:00
|
|
|
sel_row_start, sel_row_end, sel_col_start, sel_col_end));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_USEBOX:
|
2005-01-27 21:05:44 +00:00
|
|
|
status.setOnOff(convert<int>(argument) == tabular.getUsebox(cur.idx()));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2009-02-11 03:18:16 +00:00
|
|
|
// every row can only be one thing:
|
2011-12-18 21:27:17 +00:00
|
|
|
// either a footer or header
|
2009-05-17 11:27:44 +00:00
|
|
|
case Tabular::SET_LTFIRSTHEAD:
|
2011-12-18 21:27:17 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2009-02-11 03:18:16 +00:00
|
|
|
status.setOnOff(tabular.getRowOfLTFirstHead(sel_row_start, dummyltt));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTFIRSTHEAD:
|
2014-02-24 09:12:21 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2009-02-11 03:18:16 +00:00
|
|
|
status.setOnOff(!tabular.getRowOfLTFirstHead(sel_row_start, dummyltt));
|
2005-04-23 17:39:12 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTHEAD:
|
2011-12-18 21:27:17 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2004-03-27 12:40:39 +00:00
|
|
|
status.setOnOff(tabular.getRowOfLTHead(sel_row_start, dummyltt));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTHEAD:
|
2014-02-24 09:12:21 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2005-04-23 17:39:12 +00:00
|
|
|
status.setOnOff(!tabular.getRowOfLTHead(sel_row_start, dummyltt));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTFOOT:
|
2011-12-18 21:27:17 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2004-03-27 12:40:39 +00:00
|
|
|
status.setOnOff(tabular.getRowOfLTFoot(sel_row_start, dummyltt));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTFOOT:
|
2014-02-24 09:12:21 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2005-04-23 17:39:12 +00:00
|
|
|
status.setOnOff(!tabular.getRowOfLTFoot(sel_row_start, dummyltt));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTLASTFOOT:
|
2011-12-18 21:27:17 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2009-02-11 03:18:16 +00:00
|
|
|
status.setOnOff(tabular.getRowOfLTLastFoot(sel_row_start, dummyltt));
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTLASTFOOT:
|
2014-02-24 09:12:21 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end);
|
2009-02-11 03:18:16 +00:00
|
|
|
status.setOnOff(!tabular.getRowOfLTLastFoot(sel_row_start, dummyltt));
|
2005-04-23 17:39:12 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTNEWPAGE:
|
2004-03-27 12:40:39 +00:00
|
|
|
status.setOnOff(tabular.getLTNewPage(sel_row_start));
|
|
|
|
break;
|
2012-05-31 11:56:07 +00:00
|
|
|
case Tabular::UNSET_LTNEWPAGE:
|
|
|
|
status.setOnOff(!tabular.getLTNewPage(sel_row_start));
|
|
|
|
break;
|
2006-09-09 15:27:44 +00:00
|
|
|
|
2011-12-18 21:27:17 +00:00
|
|
|
// only one row in head/firsthead/foot/lasthead can be the caption
|
2010-03-04 03:27:30 +00:00
|
|
|
// and a multirow cannot be set as caption
|
2010-10-29 04:09:49 +00:00
|
|
|
case Tabular::SET_LTCAPTION:
|
2009-02-10 18:08:09 +00:00
|
|
|
status.setEnabled(sel_row_start == sel_row_end
|
2011-12-18 21:27:17 +00:00
|
|
|
&& (!tabular.getRowOfLTFirstHead(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_FIRSTHEAD))
|
|
|
|
&& (!tabular.getRowOfLTHead(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_HEAD))
|
|
|
|
&& (!tabular.getRowOfLTFoot(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_FOOT))
|
|
|
|
&& (!tabular.getRowOfLTLastFoot(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_LASTFOOT))
|
2010-03-04 03:27:30 +00:00
|
|
|
&& !tabular.isMultiRow(sel_row_start));
|
2008-05-04 07:51:50 +00:00
|
|
|
status.setOnOff(tabular.ltCaption(sel_row_start));
|
|
|
|
break;
|
|
|
|
|
2011-12-18 21:27:17 +00:00
|
|
|
case Tabular::UNSET_LTCAPTION:
|
|
|
|
status.setEnabled(sel_row_start == sel_row_end && tabular.ltCaption(sel_row_start));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::TOGGLE_LTCAPTION:
|
|
|
|
status.setEnabled(sel_row_start == sel_row_end && (tabular.ltCaption(sel_row_start)
|
|
|
|
|| ((!tabular.getRowOfLTFirstHead(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_FIRSTHEAD))
|
|
|
|
&& (!tabular.getRowOfLTHead(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_HEAD))
|
|
|
|
&& (!tabular.getRowOfLTFoot(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_FOOT))
|
|
|
|
&& (!tabular.getRowOfLTLastFoot(sel_row_start, dummyltt)
|
|
|
|
|| !tabular.haveLTCaption(Tabular::CAPTION_LASTFOOT)))));
|
|
|
|
status.setOnOff(tabular.ltCaption(sel_row_start));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_BOOKTABS:
|
2008-04-21 13:33:39 +00:00
|
|
|
status.setOnOff(tabular.use_booktabs);
|
2006-07-03 19:13:56 +00:00
|
|
|
break;
|
2006-09-09 15:27:44 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_BOOKTABS:
|
2008-04-21 13:33:39 +00:00
|
|
|
status.setOnOff(!tabular.use_booktabs);
|
2006-07-03 19:13:56 +00:00
|
|
|
break;
|
2004-03-27 12:40:39 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
status.clear();
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(false);
|
2004-03-27 12:40:39 +00:00
|
|
|
break;
|
2004-03-18 13:57:20 +00:00
|
|
|
}
|
|
|
|
return true;
|
2004-03-27 12:40:39 +00:00
|
|
|
}
|
2004-03-18 13:57:20 +00:00
|
|
|
|
2012-12-29 09:31:41 +00:00
|
|
|
case LFUN_CAPTION_INSERT: {
|
|
|
|
// caption is only allowed in caption cell of longtable
|
|
|
|
if (!tabular.ltCaption(tabular.cellRow(cur.idx()))) {
|
|
|
|
status.setEnabled(false);
|
2012-12-30 17:29:02 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// only standard caption is allowed
|
|
|
|
string arg = cmd.getArg(0);
|
|
|
|
if (!arg.empty() && arg != "Standard") {
|
|
|
|
status.setEnabled(false);
|
2012-12-29 09:31:41 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// check if there is already a caption
|
|
|
|
bool have_caption = false;
|
|
|
|
InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()).get());
|
|
|
|
ParagraphList::const_iterator pit = itc.paragraphs().begin();
|
|
|
|
ParagraphList::const_iterator pend = itc.paragraphs().end();
|
|
|
|
for (; pit != pend; ++pit) {
|
|
|
|
InsetList::const_iterator it = pit->insetList().begin();
|
|
|
|
InsetList::const_iterator end = pit->insetList().end();
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
if (it->inset->lyxCode() == CAPTION_CODE) {
|
|
|
|
have_caption = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
status.setEnabled(!have_caption);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2005-03-21 11:14:54 +00:00
|
|
|
// These are only enabled inside tabular
|
|
|
|
case LFUN_CELL_BACKWARD:
|
|
|
|
case LFUN_CELL_FORWARD:
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(true);
|
2005-07-18 11:00:15 +00:00
|
|
|
return true;
|
2005-04-26 11:12:20 +00:00
|
|
|
|
2005-03-13 10:36:42 +00:00
|
|
|
// disable these with multiple cells selected
|
2005-04-13 09:43:58 +00:00
|
|
|
case LFUN_INSET_INSERT:
|
2005-06-16 15:20:09 +00:00
|
|
|
case LFUN_TABULAR_INSERT:
|
2007-09-05 18:40:56 +00:00
|
|
|
case LFUN_FLEX_INSERT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_FLOAT_INSERT:
|
|
|
|
case LFUN_FLOAT_WIDE_INSERT:
|
|
|
|
case LFUN_FOOTNOTE_INSERT:
|
|
|
|
case LFUN_MARGINALNOTE_INSERT:
|
|
|
|
case LFUN_MATH_INSERT:
|
2005-03-17 13:23:14 +00:00
|
|
|
case LFUN_MATH_MODE:
|
|
|
|
case LFUN_MATH_MUTATE:
|
|
|
|
case LFUN_MATH_DISPLAY:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_NOTE_INSERT:
|
2010-06-04 22:53:44 +00:00
|
|
|
case LFUN_ARGUMENT_INSERT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_BOX_INSERT:
|
|
|
|
case LFUN_BRANCH_INSERT:
|
2009-01-30 00:56:37 +00:00
|
|
|
case LFUN_PHANTOM_INSERT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_WRAP_INSERT:
|
2010-03-28 13:47:50 +00:00
|
|
|
case LFUN_PREVIEW_INSERT:
|
2006-05-05 20:23:12 +00:00
|
|
|
case LFUN_ERT_INSERT: {
|
2008-08-09 16:29:25 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(false);
|
2005-03-13 10:36:42 +00:00
|
|
|
return true;
|
2005-08-07 18:36:21 +00:00
|
|
|
} else
|
|
|
|
return cell(cur.idx())->getStatus(cur, cmd, status);
|
2005-03-13 10:36:42 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 09:45:43 +00:00
|
|
|
// disable in non-fixed-width cells
|
2012-09-29 16:06:42 +00:00
|
|
|
case LFUN_PARAGRAPH_BREAK:
|
2011-02-11 09:42:33 +00:00
|
|
|
// multirow does not allow paragraph breaks
|
|
|
|
if (tabular.isMultiRow(cur.idx())) {
|
|
|
|
status.setEnabled(false);
|
|
|
|
return true;
|
|
|
|
}
|
2015-03-30 21:12:39 +00:00
|
|
|
// Fall back
|
2011-02-11 09:42:33 +00:00
|
|
|
case LFUN_NEWLINE_INSERT: {
|
2005-07-28 09:45:43 +00:00
|
|
|
if (tabular.getPWidth(cur.idx()).zero()) {
|
2008-05-29 15:14:00 +00:00
|
|
|
status.setEnabled(false);
|
2005-07-28 09:45:43 +00:00
|
|
|
return true;
|
2005-08-07 18:36:21 +00:00
|
|
|
} else
|
|
|
|
return cell(cur.idx())->getStatus(cur, cmd, status);
|
2005-07-28 09:45:43 +00:00
|
|
|
}
|
|
|
|
|
2008-08-09 02:02:16 +00:00
|
|
|
case LFUN_NEWPAGE_INSERT:
|
|
|
|
status.setEnabled(false);
|
|
|
|
return true;
|
|
|
|
|
2006-03-17 13:11:32 +00:00
|
|
|
case LFUN_PASTE:
|
2007-01-04 12:05:24 +00:00
|
|
|
if (tabularStackDirty() && theClipboard().isInternal()) {
|
2009-05-17 21:22:02 +00:00
|
|
|
if (cur.selIsMultiCell()) {
|
|
|
|
row_type rs, re;
|
|
|
|
col_type cs, ce;
|
|
|
|
getSelection(cur, rs, re, cs, ce);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (paste_tabular && paste_tabular->ncols() == ce - cs + 1
|
|
|
|
&& paste_tabular->nrows() == re - rs + 1)
|
2014-07-26 14:29:23 +00:00
|
|
|
status.setEnabled(true);
|
2009-05-17 21:22:02 +00:00
|
|
|
else {
|
|
|
|
status.setEnabled(false);
|
|
|
|
status.message(_("Selection size should match clipboard content."));
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
status.setEnabled(true);
|
2006-03-17 13:11:32 +00:00
|
|
|
return true;
|
2009-05-17 21:22:02 +00:00
|
|
|
}
|
2008-08-08 17:28:25 +00:00
|
|
|
return cell(cur.idx())->getStatus(cur, cmd, status);
|
2006-03-17 13:11:32 +00:00
|
|
|
|
2009-04-10 00:17:34 +00:00
|
|
|
case LFUN_INSET_SETTINGS:
|
2009-04-22 20:55:13 +00:00
|
|
|
// relay this lfun to Inset, not to the cell.
|
|
|
|
return Inset::getStatus(cur, cmd, status);
|
|
|
|
|
2004-03-18 13:57:20 +00:00
|
|
|
default:
|
|
|
|
// we try to handle this event in the insets dispatch function.
|
2004-11-23 23:04:52 +00:00
|
|
|
return cell(cur.idx())->getStatus(cur, cmd, status);
|
2004-03-18 13:57:20 +00:00
|
|
|
}
|
2010-02-18 08:28:46 +00:00
|
|
|
return false;
|
2004-03-18 13:57:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-11 13:09:45 +00:00
|
|
|
Inset::DisplayType InsetTabular::display() const
|
|
|
|
{
|
|
|
|
if (tabular.is_long_tabular) {
|
|
|
|
switch (tabular.longtabular_alignment) {
|
|
|
|
case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
|
|
|
|
return AlignLeft;
|
|
|
|
case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
|
|
|
|
return AlignCenter;
|
|
|
|
case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
|
|
|
|
return AlignRight;
|
2009-07-11 13:41:34 +00:00
|
|
|
default:
|
|
|
|
return AlignCenter;
|
2009-07-11 13:09:45 +00:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
return Inline;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-10 20:02:48 +00:00
|
|
|
void InsetTabular::latex(otexstream & os, OutputParams const & runparams) const
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2011-02-10 20:02:48 +00:00
|
|
|
tabular.latex(os, runparams);
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2013-03-08 19:52:18 +00:00
|
|
|
int InsetTabular::plaintext(odocstringstream & os,
|
|
|
|
OutputParams const & runparams, size_t max_length) const
|
2000-04-24 20:58:23 +00:00
|
|
|
{
|
2007-02-18 10:47:08 +00:00
|
|
|
os << '\n'; // output table on a new line
|
|
|
|
int const dp = runparams.linelen > 0 ? runparams.depth : 0;
|
2013-03-08 19:52:18 +00:00
|
|
|
tabular.plaintext(os, runparams, dp, false, 0, max_length);
|
2007-02-20 17:52:41 +00:00
|
|
|
return PLAINTEXT_NEWLINE;
|
2000-04-24 20:58:23 +00:00
|
|
|
}
|
|
|
|
|
2000-07-15 23:51:46 +00:00
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
int InsetTabular::docbook(odocstream & os, OutputParams const & runparams) const
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2001-10-24 07:43:34 +00:00
|
|
|
int ret = 0;
|
2007-04-29 13:39:47 +00:00
|
|
|
Inset * master = 0;
|
2001-10-24 07:43:34 +00:00
|
|
|
|
2007-08-10 11:47:12 +00:00
|
|
|
// FIXME: Why not pass a proper DocIterator here?
|
2004-03-25 09:16:36 +00:00
|
|
|
#if 0
|
2001-10-24 07:43:34 +00:00
|
|
|
// if the table is inside a float it doesn't need the informaltable
|
|
|
|
// wrapper. Search for it.
|
2004-01-08 18:30:14 +00:00
|
|
|
for (master = owner(); master; master = master->owner())
|
2007-10-13 09:04:52 +00:00
|
|
|
if (master->lyxCode() == FLOAT_CODE)
|
2004-01-08 18:30:14 +00:00
|
|
|
break;
|
2004-03-25 09:16:36 +00:00
|
|
|
#endif
|
2001-10-24 07:43:34 +00:00
|
|
|
|
|
|
|
if (!master) {
|
2002-06-18 15:44:30 +00:00
|
|
|
os << "<informaltable>";
|
2003-07-31 10:48:50 +00:00
|
|
|
++ret;
|
2001-10-24 07:43:34 +00:00
|
|
|
}
|
2008-02-27 20:43:16 +00:00
|
|
|
ret += tabular.docbook(os, runparams);
|
2001-10-24 07:43:34 +00:00
|
|
|
if (!master) {
|
2002-06-18 15:44:30 +00:00
|
|
|
os << "</informaltable>";
|
2003-07-31 10:48:50 +00:00
|
|
|
++ret;
|
2001-10-24 07:43:34 +00:00
|
|
|
}
|
|
|
|
return ret;
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2009-12-14 15:39:13 +00:00
|
|
|
docstring InsetTabular::xhtml(XHTMLStream & xs, OutputParams const & rp) const
|
|
|
|
{
|
2011-01-13 21:04:52 +00:00
|
|
|
return tabular.xhtml(xs, rp);
|
2009-12-14 15:39:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-06-28 10:25:20 +00:00
|
|
|
void InsetTabular::validate(LaTeXFeatures & features) const
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2003-06-13 07:37:48 +00:00
|
|
|
tabular.validate(features);
|
2009-12-14 16:05:36 +00:00
|
|
|
// FIXME XHTML
|
|
|
|
// It'd be better to be able to get this from an InsetLayout, but at present
|
|
|
|
// InsetLayouts do not seem really to work for things that aren't InsetTexts.
|
|
|
|
if (features.runparams().flavor == OutputParams::HTML)
|
2011-12-06 22:17:13 +00:00
|
|
|
features.addCSSSnippet(
|
|
|
|
"table { border: 1px solid black; display: inline-block; }\n"
|
|
|
|
"td { border: 1px solid black; padding: 0.5ex; }");
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-21 06:16:05 +00:00
|
|
|
shared_ptr<InsetTableCell const> InsetTabular::cell(idx_type idx) const
|
2001-04-04 09:42:56 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
return tabular.cellInset(idx);
|
2004-02-16 11:58:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-21 06:16:05 +00:00
|
|
|
shared_ptr<InsetTableCell> InsetTabular::cell(idx_type idx)
|
2004-02-16 11:58:51 +00:00
|
|
|
{
|
2008-03-25 13:32:38 +00:00
|
|
|
return tabular.cellInset(idx);
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-17 16:23:27 +00:00
|
|
|
void InsetTabular::cursorPos(BufferView const & bv,
|
|
|
|
CursorSlice const & sl, bool boundary, int & x, int & y) const
|
2004-11-30 01:59:49 +00:00
|
|
|
{
|
2006-10-17 16:23:27 +00:00
|
|
|
cell(sl.idx())->cursorPos(bv, sl, boundary, x, y);
|
2004-11-30 01:59:49 +00:00
|
|
|
|
2010-02-11 01:07:54 +00:00
|
|
|
// y offset correction
|
2010-11-25 13:22:04 +00:00
|
|
|
y += cellYPos(sl.idx());
|
2010-02-11 01:07:54 +00:00
|
|
|
y += tabular.textVOffset(sl.idx());
|
2010-11-25 13:20:56 +00:00
|
|
|
y += offset_valign_;
|
2004-11-30 01:59:49 +00:00
|
|
|
|
2004-12-06 02:35:12 +00:00
|
|
|
// x offset correction
|
2010-11-25 13:22:04 +00:00
|
|
|
x += cellXPos(sl.idx());
|
2010-02-11 01:07:54 +00:00
|
|
|
x += tabular.textHOffset(sl.idx());
|
2004-11-30 01:59:49 +00:00
|
|
|
x += ADD_TO_TABULAR_WIDTH;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-13 16:44:44 +00:00
|
|
|
int InsetTabular::dist(BufferView & bv, idx_type const cell, int x, int y) const
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2004-11-30 01:59:49 +00:00
|
|
|
int xx = 0;
|
|
|
|
int yy = 0;
|
2008-03-25 13:32:38 +00:00
|
|
|
Inset const & inset = *tabular.cellInset(cell);
|
2006-10-13 16:44:44 +00:00
|
|
|
Point o = bv.coordCache().getInsets().xy(&inset);
|
2010-02-11 01:07:54 +00:00
|
|
|
int const xbeg = o.x_ - tabular.textHOffset(cell);
|
2010-06-14 10:42:42 +00:00
|
|
|
int const xend = xbeg + tabular.cellWidth(cell);
|
2007-09-04 10:52:08 +00:00
|
|
|
row_type const row = tabular.cellRow(cell);
|
2010-02-11 01:07:54 +00:00
|
|
|
int const ybeg = o.y_ - tabular.rowAscent(row)
|
2012-03-17 23:05:15 +00:00
|
|
|
- tabular.interRowSpace(row) - tabular.textVOffset(cell);
|
2010-03-16 21:42:16 +00:00
|
|
|
int const yend = ybeg + tabular.cellHeight(cell);
|
2005-06-27 12:53:35 +00:00
|
|
|
|
2005-07-15 11:43:07 +00:00
|
|
|
if (x < xbeg)
|
2005-06-27 12:53:35 +00:00
|
|
|
xx = xbeg - x;
|
2005-07-15 11:43:07 +00:00
|
|
|
else if (x > xend)
|
2005-06-27 12:53:35 +00:00
|
|
|
xx = x - xend;
|
|
|
|
|
2006-04-05 23:56:29 +00:00
|
|
|
if (y < ybeg)
|
2005-06-27 12:53:35 +00:00
|
|
|
yy = ybeg - y;
|
2006-04-05 23:56:29 +00:00
|
|
|
else if (y > yend)
|
2005-06-27 12:53:35 +00:00
|
|
|
yy = y - yend;
|
|
|
|
|
2005-07-15 11:43:07 +00:00
|
|
|
//lyxerr << " xbeg=" << xbeg << " xend=" << xend
|
|
|
|
// << " ybeg=" << ybeg << " yend=" << yend
|
|
|
|
// << " xx=" << xx << " yy=" << yy
|
|
|
|
// << " dist=" << xx + yy << endl;
|
2004-11-30 01:59:49 +00:00
|
|
|
return xx + yy;
|
2001-08-01 15:42:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-29 13:39:47 +00:00
|
|
|
Inset * InsetTabular::editXY(Cursor & cur, int x, int y)
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2005-03-21 18:21:13 +00:00
|
|
|
//lyxerr << "InsetTabular::editXY: " << this << endl;
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(false);
|
2005-07-15 00:39:44 +00:00
|
|
|
cur.push(*this);
|
2006-10-13 16:44:44 +00:00
|
|
|
cur.idx() = getNearestCell(cur.bv(), x, y);
|
2008-07-29 12:07:08 +00:00
|
|
|
return cur.bv().textMetrics(&cell(cur.idx())->text()).editXY(cur, x, y);
|
2005-03-21 18:21:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetTabular::setCursorFromCoordinates(Cursor & cur, int x, int y) const
|
2005-03-21 18:21:13 +00:00
|
|
|
{
|
2006-10-13 16:44:44 +00:00
|
|
|
cur.idx() = getNearestCell(cur.bv(), x, y);
|
2008-07-29 12:07:08 +00:00
|
|
|
cur.bv().textMetrics(&cell(cur.idx())->text()).setCursorFromCoordinates(cur, x, y);
|
2005-03-21 18:21:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-13 16:44:44 +00:00
|
|
|
InsetTabular::idx_type InsetTabular::getNearestCell(BufferView & bv, int x, int y) const
|
2005-03-21 18:21:13 +00:00
|
|
|
{
|
2004-12-03 13:57:50 +00:00
|
|
|
idx_type idx_min = 0;
|
2007-12-12 19:28:07 +00:00
|
|
|
int dist_min = numeric_limits<int>::max();
|
2005-07-18 12:57:08 +00:00
|
|
|
for (idx_type i = 0, n = nargs(); i != n; ++i) {
|
2008-03-25 13:32:38 +00:00
|
|
|
if (bv.coordCache().getInsets().has(tabular.cellInset(i).get())) {
|
2006-10-13 16:44:44 +00:00
|
|
|
int const d = dist(bv, i, x, y);
|
2004-11-30 01:59:49 +00:00
|
|
|
if (d < dist_min) {
|
|
|
|
dist_min = d;
|
|
|
|
idx_min = i;
|
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-21 18:21:13 +00:00
|
|
|
return idx_min;
|
2000-04-21 15:16:22 +00:00
|
|
|
}
|
|
|
|
|
2000-07-15 23:51:46 +00:00
|
|
|
|
2010-11-25 13:22:04 +00:00
|
|
|
int InsetTabular::cellYPos(idx_type const cell) const
|
|
|
|
{
|
|
|
|
row_type row = tabular.cellRow(cell);
|
|
|
|
int ly = 0;
|
|
|
|
for (row_type r = 0; r < row; ++r)
|
2014-07-26 14:29:23 +00:00
|
|
|
ly += tabular.rowDescent(r) + tabular.rowAscent(r + 1)
|
2010-11-25 13:22:04 +00:00
|
|
|
+ tabular.interRowSpace(r + 1);
|
|
|
|
return ly;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-25 13:32:38 +00:00
|
|
|
int InsetTabular::cellXPos(idx_type const cell) const
|
2000-05-15 14:49:36 +00:00
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
col_type col = tabular.cellColumn(cell);
|
2007-06-25 08:19:15 +00:00
|
|
|
int lx = 0;
|
2010-02-11 01:07:54 +00:00
|
|
|
for (col_type c = 0; c < col; ++c)
|
2010-06-13 20:27:28 +00:00
|
|
|
lx += tabular.column_info[c].width;
|
2007-06-25 08:19:15 +00:00
|
|
|
return lx;
|
2000-05-15 14:49:36 +00:00
|
|
|
}
|
2000-04-21 15:16:22 +00:00
|
|
|
|
2000-07-15 23:51:46 +00:00
|
|
|
|
2008-04-11 12:02:10 +00:00
|
|
|
void InsetTabular::moveNextCell(Cursor & cur, EntryDirection entry_from)
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
row_type const row = tabular.cellRow(cur.idx());
|
|
|
|
col_type const col = tabular.cellColumn(cur.idx());
|
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
if (isRightToLeft(cur)) {
|
2010-02-11 01:07:54 +00:00
|
|
|
if (tabular.cellColumn(cur.idx()) == 0) {
|
2010-03-05 18:10:34 +00:00
|
|
|
if (row == tabular.nrows() - 1)
|
2004-02-16 11:58:51 +00:00
|
|
|
return;
|
2008-03-25 13:32:38 +00:00
|
|
|
cur.idx() = tabular.cellBelow(tabular.getLastCellInRow(row));
|
2001-04-04 09:42:56 +00:00
|
|
|
} else {
|
2004-01-20 14:25:24 +00:00
|
|
|
if (cur.idx() == 0)
|
2004-02-16 11:58:51 +00:00
|
|
|
return;
|
2010-02-11 01:07:54 +00:00
|
|
|
if (col == 0)
|
|
|
|
cur.idx() = tabular.getLastCellInRow(row - 1);
|
|
|
|
else
|
|
|
|
cur.idx() = tabular.cellIndex(row, col - 1);
|
2001-04-04 09:42:56 +00:00
|
|
|
}
|
2001-01-08 16:14:09 +00:00
|
|
|
} else {
|
2004-01-20 14:25:24 +00:00
|
|
|
if (tabular.isLastCell(cur.idx()))
|
2004-02-16 11:58:51 +00:00
|
|
|
return;
|
2010-02-12 18:36:20 +00:00
|
|
|
if (cur.idx() == tabular.getLastCellInRow(row))
|
2010-02-11 01:07:54 +00:00
|
|
|
cur.idx() = tabular.cellIndex(row + 1, 0);
|
2010-03-07 17:33:33 +00:00
|
|
|
else {
|
|
|
|
col_type const colnextcell = col + tabular.columnSpan(cur.idx());
|
|
|
|
cur.idx() = tabular.cellIndex(row, colnextcell);
|
|
|
|
}
|
2001-01-08 16:14:09 +00:00
|
|
|
}
|
2008-10-01 08:18:57 +00:00
|
|
|
|
|
|
|
cur.boundary(false);
|
|
|
|
|
|
|
|
if (cur.selIsMultiCell()) {
|
|
|
|
cur.pit() = cur.lastpit();
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = 0;
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.pos() = 0;
|
2008-04-11 12:02:10 +00:00
|
|
|
|
|
|
|
// in visual mode, place cursor at extreme left or right
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2008-04-11 12:02:10 +00:00
|
|
|
switch(entry_from) {
|
|
|
|
|
|
|
|
case ENTRY_DIRECTION_RIGHT:
|
|
|
|
cur.posVisToRowExtremity(false /* !left */);
|
|
|
|
break;
|
|
|
|
case ENTRY_DIRECTION_LEFT:
|
|
|
|
cur.posVisToRowExtremity(true /* left */);
|
|
|
|
break;
|
|
|
|
case ENTRY_DIRECTION_IGNORE:
|
|
|
|
// nothing to do in this case
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
2009-12-17 17:47:09 +00:00
|
|
|
cur.setCurrentFont();
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2008-04-11 12:02:10 +00:00
|
|
|
void InsetTabular::movePrevCell(Cursor & cur, EntryDirection entry_from)
|
2000-04-19 14:42:19 +00:00
|
|
|
{
|
2010-02-11 01:07:54 +00:00
|
|
|
row_type const row = tabular.cellRow(cur.idx());
|
|
|
|
col_type const col = tabular.cellColumn(cur.idx());
|
|
|
|
|
2004-01-20 14:25:24 +00:00
|
|
|
if (isRightToLeft(cur)) {
|
2010-02-12 18:36:20 +00:00
|
|
|
if (cur.idx() == tabular.getLastCellInRow(row)) {
|
2001-04-04 09:42:56 +00:00
|
|
|
if (row == 0)
|
2004-02-16 11:58:51 +00:00
|
|
|
return;
|
2004-01-20 14:25:24 +00:00
|
|
|
cur.idx() = tabular.getFirstCellInRow(row);
|
2008-03-25 13:32:38 +00:00
|
|
|
cur.idx() = tabular.cellAbove(cur.idx());
|
2001-04-04 09:42:56 +00:00
|
|
|
} else {
|
2004-01-20 14:25:24 +00:00
|
|
|
if (tabular.isLastCell(cur.idx()))
|
2004-02-16 11:58:51 +00:00
|
|
|
return;
|
2010-02-12 18:36:20 +00:00
|
|
|
if (cur.idx() == tabular.getLastCellInRow(row))
|
2010-02-11 01:07:54 +00:00
|
|
|
cur.idx() = tabular.cellIndex(row + 1, 0);
|
|
|
|
else
|
|
|
|
cur.idx() = tabular.cellIndex(row, col + 1);
|
2001-04-04 09:42:56 +00:00
|
|
|
}
|
2001-01-08 16:14:09 +00:00
|
|
|
} else {
|
2004-01-20 14:25:24 +00:00
|
|
|
if (cur.idx() == 0) // first cell
|
2004-02-16 11:58:51 +00:00
|
|
|
return;
|
2010-02-11 01:07:54 +00:00
|
|
|
if (col == 0)
|
|
|
|
cur.idx() = tabular.getLastCellInRow(row - 1);
|
|
|
|
else
|
|
|
|
cur.idx() = tabular.cellIndex(row, col - 1);
|
2001-01-08 16:14:09 +00:00
|
|
|
}
|
2008-10-01 08:18:57 +00:00
|
|
|
|
|
|
|
if (cur.selIsMultiCell()) {
|
|
|
|
cur.pit() = cur.lastpit();
|
|
|
|
cur.pos() = cur.lastpos();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-03-17 13:23:14 +00:00
|
|
|
cur.pit() = cur.lastpit();
|
|
|
|
cur.pos() = cur.lastpos();
|
2006-10-20 16:11:30 +00:00
|
|
|
|
2008-04-11 12:02:10 +00:00
|
|
|
// in visual mode, place cursor at extreme left or right
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2008-04-11 12:02:10 +00:00
|
|
|
switch(entry_from) {
|
|
|
|
|
|
|
|
case ENTRY_DIRECTION_RIGHT:
|
|
|
|
cur.posVisToRowExtremity(false /* !left */);
|
|
|
|
break;
|
|
|
|
case ENTRY_DIRECTION_LEFT:
|
|
|
|
cur.posVisToRowExtremity(true /* left */);
|
|
|
|
break;
|
|
|
|
case ENTRY_DIRECTION_IGNORE:
|
|
|
|
// nothing to do in this case
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
2009-12-17 17:47:09 +00:00
|
|
|
cur.setCurrentFont();
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
|
|
|
|
2000-04-24 20:58:23 +00:00
|
|
|
|
2010-02-18 08:28:46 +00:00
|
|
|
bool InsetTabular::tabularFeatures(Cursor & cur, string const & argument)
|
2000-07-28 14:28:54 +00:00
|
|
|
{
|
2010-02-18 08:28:46 +00:00
|
|
|
istringstream is(argument);
|
|
|
|
string s;
|
|
|
|
is >> s;
|
|
|
|
if (insetCode(s) != TABULAR_CODE)
|
|
|
|
return false;
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2010-02-18 08:28:46 +00:00
|
|
|
// Safe guard.
|
|
|
|
size_t safe_guard = 0;
|
|
|
|
for (;;) {
|
2010-02-19 12:21:49 +00:00
|
|
|
if (is.eof())
|
|
|
|
break;
|
2010-02-18 08:28:46 +00:00
|
|
|
safe_guard++;
|
|
|
|
if (safe_guard > 1000) {
|
|
|
|
LYXERR0("parameter max count reached!");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
is >> s;
|
|
|
|
Tabular::Feature action = Tabular::LAST_ACTION;
|
|
|
|
|
|
|
|
size_t i = 0;
|
|
|
|
for (; tabularFeature[i].action != Tabular::LAST_ACTION; ++i) {
|
|
|
|
if (s != tabularFeature[i].feature)
|
|
|
|
continue;
|
2001-06-28 10:25:20 +00:00
|
|
|
action = tabularFeature[i].action;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-02-18 08:28:46 +00:00
|
|
|
if (action == Tabular::LAST_ACTION) {
|
|
|
|
LYXERR0("Feature not found " << s);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
string val;
|
|
|
|
if (tabularFeature[i].need_value)
|
|
|
|
is >> val;
|
|
|
|
LYXERR(Debug::DEBUG, "Feature: " << s << "\t\tvalue: " << val);
|
|
|
|
tabularFeatures(cur, action, val);
|
2000-07-28 14:28:54 +00:00
|
|
|
}
|
2001-04-04 09:42:56 +00:00
|
|
|
return true;
|
2000-07-28 14:28:54 +00:00
|
|
|
}
|
|
|
|
|
2003-12-15 15:33:15 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
static void checkLongtableSpecial(Tabular::ltType & ltt,
|
2003-02-14 15:01:06 +00:00
|
|
|
string const & special, bool & flag)
|
2001-12-19 16:13:21 +00:00
|
|
|
{
|
|
|
|
if (special == "dl_above") {
|
|
|
|
ltt.topDL = flag;
|
2001-12-20 14:52:15 +00:00
|
|
|
ltt.set = false;
|
2001-12-19 16:13:21 +00:00
|
|
|
} else if (special == "dl_below") {
|
|
|
|
ltt.bottomDL = flag;
|
2001-12-20 14:52:15 +00:00
|
|
|
ltt.set = false;
|
2001-12-19 16:13:21 +00:00
|
|
|
} else if (special == "empty") {
|
|
|
|
ltt.empty = flag;
|
2001-12-20 14:52:15 +00:00
|
|
|
ltt.set = false;
|
2001-12-19 21:25:34 +00:00
|
|
|
} else if (flag) {
|
|
|
|
ltt.empty = false;
|
2001-12-20 14:52:15 +00:00
|
|
|
ltt.set = true;
|
2001-12-19 16:13:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
|
2007-05-12 20:59:21 +00:00
|
|
|
bool InsetTabular::oneCellHasRotationState(bool rotated,
|
2007-05-28 22:27:45 +00:00
|
|
|
row_type row_start, row_type row_end,
|
2014-07-26 14:29:23 +00:00
|
|
|
col_type col_start, col_type col_end) const
|
2010-03-05 18:10:34 +00:00
|
|
|
{
|
|
|
|
for (row_type r = row_start; r <= row_end; ++r)
|
|
|
|
for (col_type c = col_start; c <= col_end; ++c)
|
2012-03-16 01:29:37 +00:00
|
|
|
if (rotated) {
|
|
|
|
if (tabular.getRotateCell(tabular.cellIndex(r, c)) != 0)
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if (tabular.getRotateCell(tabular.cellIndex(r, c)) == 0)
|
|
|
|
return true;
|
|
|
|
}
|
2007-05-12 20:59:21 +00:00
|
|
|
return false;
|
|
|
|
}
|
2000-07-28 14:28:54 +00:00
|
|
|
|
2012-03-19 00:21:26 +00:00
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetTabular::tabularFeatures(Cursor & cur,
|
2007-04-26 12:54:21 +00:00
|
|
|
Tabular::Feature feature, string const & value)
|
2001-04-04 09:42:56 +00:00
|
|
|
{
|
2004-12-03 13:57:50 +00:00
|
|
|
col_type sel_col_start;
|
|
|
|
col_type sel_col_end;
|
|
|
|
row_type sel_row_start;
|
|
|
|
row_type sel_row_end;
|
2001-04-04 22:08:13 +00:00
|
|
|
bool setLines = false;
|
2001-04-04 09:42:56 +00:00
|
|
|
LyXAlignment setAlign = LYX_ALIGN_LEFT;
|
2007-04-26 12:54:21 +00:00
|
|
|
Tabular::VAlignment setVAlign = Tabular::LYX_VALIGN_TOP;
|
2001-04-04 09:42:56 +00:00
|
|
|
|
|
|
|
switch (feature) {
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_ALIGN_LEFT:
|
|
|
|
case Tabular::ALIGN_LEFT:
|
2001-12-11 17:26:52 +00:00
|
|
|
setAlign = LYX_ALIGN_LEFT;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_ALIGN_RIGHT:
|
|
|
|
case Tabular::ALIGN_RIGHT:
|
2001-12-11 17:26:52 +00:00
|
|
|
setAlign = LYX_ALIGN_RIGHT;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_ALIGN_CENTER:
|
|
|
|
case Tabular::ALIGN_CENTER:
|
2001-12-11 17:26:52 +00:00
|
|
|
setAlign = LYX_ALIGN_CENTER;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::ALIGN_BLOCK:
|
2002-11-21 12:24:50 +00:00
|
|
|
setAlign = LYX_ALIGN_BLOCK;
|
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2010-06-05 07:44:44 +00:00
|
|
|
case Tabular::ALIGN_DECIMAL:
|
2015-05-25 13:55:11 +00:00
|
|
|
setAlign = LYX_ALIGN_DECIMAL;
|
2010-06-05 07:44:44 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_VALIGN_TOP:
|
|
|
|
case Tabular::VALIGN_TOP:
|
|
|
|
setVAlign = Tabular::LYX_VALIGN_TOP;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_VALIGN_BOTTOM:
|
|
|
|
case Tabular::VALIGN_BOTTOM:
|
|
|
|
setVAlign = Tabular::LYX_VALIGN_BOTTOM;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_VALIGN_MIDDLE:
|
|
|
|
case Tabular::VALIGN_MIDDLE:
|
|
|
|
setVAlign = Tabular::LYX_VALIGN_MIDDLE;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2001-04-04 09:42:56 +00:00
|
|
|
default:
|
|
|
|
break;
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2015-03-12 14:57:29 +00:00
|
|
|
cur.recordUndoInset(this);
|
2000-04-19 14:42:19 +00:00
|
|
|
|
2004-02-13 16:22:53 +00:00
|
|
|
getSelection(cur, sel_row_start, sel_row_end, sel_col_start, sel_col_end);
|
2007-09-04 10:52:08 +00:00
|
|
|
row_type const row = tabular.cellRow(cur.idx());
|
|
|
|
col_type const column = tabular.cellColumn(cur.idx());
|
2001-04-04 09:42:56 +00:00
|
|
|
bool flag = true;
|
2007-04-26 12:54:21 +00:00
|
|
|
Tabular::ltType ltt;
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2001-04-04 09:42:56 +00:00
|
|
|
switch (feature) {
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2011-02-03 23:11:26 +00:00
|
|
|
case Tabular::SET_TABULAR_WIDTH:
|
|
|
|
tabular.setTabularWidth(Length(value));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_PWIDTH: {
|
2007-04-28 12:58:49 +00:00
|
|
|
Length const len(value);
|
2005-11-28 11:52:03 +00:00
|
|
|
tabular.setColumnPWidth(cur, cur.idx(), len);
|
2003-10-10 09:01:23 +00:00
|
|
|
if (len.zero()
|
2004-10-23 09:21:38 +00:00
|
|
|
&& tabular.getAlignment(cur.idx(), true) == LYX_ALIGN_BLOCK)
|
2007-04-26 12:54:21 +00:00
|
|
|
tabularFeatures(cur, Tabular::ALIGN_CENTER, string());
|
2003-07-31 10:48:50 +00:00
|
|
|
break;
|
2001-04-04 09:42:56 +00:00
|
|
|
}
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_MPWIDTH:
|
2007-04-28 12:58:49 +00:00
|
|
|
tabular.setMColumnPWidth(cur, cur.idx(), Length(value));
|
2003-11-10 09:06:48 +00:00
|
|
|
break;
|
2003-10-14 13:01:49 +00:00
|
|
|
|
2010-11-07 05:32:28 +00:00
|
|
|
case Tabular::SET_MROFFSET:
|
|
|
|
tabular.setMROffset(cur, cur.idx(), Length(value));
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_SPECIAL_COLUMN:
|
2010-02-11 01:07:54 +00:00
|
|
|
case Tabular::SET_SPECIAL_MULTICOLUMN:
|
2010-02-18 08:28:46 +00:00
|
|
|
if (value == "none")
|
|
|
|
tabular.setAlignSpecial(cur.idx(), docstring(), feature);
|
|
|
|
else
|
|
|
|
tabular.setAlignSpecial(cur.idx(), from_utf8(value), feature);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-10-14 13:01:49 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::APPEND_ROW:
|
2001-04-04 09:42:56 +00:00
|
|
|
// append the row into the tabular
|
2012-01-22 22:15:11 +00:00
|
|
|
tabular.appendRow(row);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-10-14 13:01:49 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::APPEND_COLUMN:
|
2001-04-04 09:42:56 +00:00
|
|
|
// append the column into the tabular
|
2012-01-22 22:15:11 +00:00
|
|
|
tabular.appendColumn(column);
|
2007-09-04 10:52:08 +00:00
|
|
|
cur.idx() = tabular.cellIndex(row, column);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-10-14 13:01:49 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::DELETE_ROW:
|
2012-12-12 09:04:39 +00:00
|
|
|
if (sel_row_end == tabular.nrows() - 1 && sel_row_start != 0) {
|
|
|
|
for (col_type c = 0; c < tabular.ncols(); c++)
|
|
|
|
tabular.setBottomLine(tabular.cellIndex(sel_row_start - 1, c),
|
|
|
|
tabular.bottomLine(tabular.cellIndex(sel_row_end, c)));
|
|
|
|
}
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
2003-06-13 07:37:48 +00:00
|
|
|
tabular.deleteRow(sel_row_start);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (sel_row_start >= tabular.nrows())
|
2001-08-08 13:29:13 +00:00
|
|
|
--sel_row_start;
|
2007-09-04 10:52:08 +00:00
|
|
|
cur.idx() = tabular.cellIndex(sel_row_start, column);
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = 0;
|
2004-10-23 09:21:38 +00:00
|
|
|
cur.pos() = 0;
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(false);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-10-14 13:01:49 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::DELETE_COLUMN:
|
2012-12-12 09:04:39 +00:00
|
|
|
if (sel_col_end == tabular.ncols() - 1 && sel_col_start != 0) {
|
|
|
|
for (row_type r = 0; r < tabular.nrows(); r++)
|
|
|
|
tabular.setRightLine(tabular.cellIndex(r, sel_col_start - 1),
|
|
|
|
tabular.rightLine(tabular.cellIndex(r, sel_col_end)));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sel_col_start == 0 && sel_col_end != tabular.ncols() - 1) {
|
|
|
|
for (row_type r = 0; r < tabular.nrows(); r++)
|
|
|
|
tabular.setLeftLine(tabular.cellIndex(r, sel_col_end + 1),
|
|
|
|
tabular.leftLine(tabular.cellIndex(r, 0)));
|
|
|
|
}
|
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
2003-06-13 07:37:48 +00:00
|
|
|
tabular.deleteColumn(sel_col_start);
|
2010-03-05 18:10:34 +00:00
|
|
|
if (sel_col_start >= tabular.ncols())
|
2001-08-08 13:29:13 +00:00
|
|
|
--sel_col_start;
|
2007-09-04 10:52:08 +00:00
|
|
|
cur.idx() = tabular.cellIndex(row, sel_col_start);
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = 0;
|
2004-10-23 09:21:38 +00:00
|
|
|
cur.pos() = 0;
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(false);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-10-14 13:01:49 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::COPY_ROW:
|
2008-02-27 20:43:16 +00:00
|
|
|
tabular.copyRow(row);
|
2006-09-27 16:28:09 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::COPY_COLUMN:
|
2008-02-27 20:43:16 +00:00
|
|
|
tabular.copyColumn(column);
|
2007-09-04 10:52:08 +00:00
|
|
|
cur.idx() = tabular.cellIndex(row, column);
|
2006-09-27 16:28:09 +00:00
|
|
|
break;
|
|
|
|
|
2012-12-24 10:51:28 +00:00
|
|
|
case Tabular::MOVE_COLUMN_RIGHT:
|
|
|
|
tabular.moveColumn(column, Tabular::RIGHT);
|
|
|
|
cur.idx() = tabular.cellIndex(row, column + 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::MOVE_COLUMN_LEFT:
|
|
|
|
tabular.moveColumn(column, Tabular::LEFT);
|
|
|
|
cur.idx() = tabular.cellIndex(row, column - 1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::MOVE_ROW_DOWN:
|
|
|
|
tabular.moveRow(row, Tabular::DOWN);
|
|
|
|
cur.idx() = tabular.cellIndex(row + 1, column);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::MOVE_ROW_UP:
|
|
|
|
tabular.moveRow(row, Tabular::UP);
|
|
|
|
cur.idx() = tabular.cellIndex(row - 1, column);
|
|
|
|
break;
|
|
|
|
|
2010-02-19 10:03:03 +00:00
|
|
|
case Tabular::SET_LINE_TOP:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_TOP: {
|
2010-02-19 10:03:03 +00:00
|
|
|
bool lineSet = (feature == Tabular::SET_LINE_TOP)
|
|
|
|
? (value == "true") : !tabular.topLine(cur.idx());
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
|
|
|
tabular.setTopLine(tabular.cellIndex(r, c), lineSet);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2001-04-04 22:08:13 +00:00
|
|
|
}
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2010-02-19 10:03:03 +00:00
|
|
|
case Tabular::SET_LINE_BOTTOM:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_BOTTOM: {
|
2010-02-19 10:03:03 +00:00
|
|
|
bool lineSet = (feature == Tabular::SET_LINE_BOTTOM)
|
|
|
|
? (value == "true") : !tabular.bottomLine(cur.idx());
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
|
|
|
tabular.setBottomLine(tabular.cellIndex(r, c), lineSet);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2001-04-04 22:08:13 +00:00
|
|
|
}
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2010-02-19 10:03:03 +00:00
|
|
|
case Tabular::SET_LINE_LEFT:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_LEFT: {
|
2010-02-19 10:03:03 +00:00
|
|
|
bool lineSet = (feature == Tabular::SET_LINE_LEFT)
|
|
|
|
? (value == "true") : !tabular.leftLine(cur.idx());
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
|
|
|
tabular.setLeftLine(tabular.cellIndex(r, c), lineSet);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2001-04-04 22:08:13 +00:00
|
|
|
}
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2010-02-19 10:03:03 +00:00
|
|
|
case Tabular::SET_LINE_RIGHT:
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::TOGGLE_LINE_RIGHT: {
|
2010-02-19 10:03:03 +00:00
|
|
|
bool lineSet = (feature == Tabular::SET_LINE_RIGHT)
|
|
|
|
? (value == "true") : !tabular.rightLine(cur.idx());
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
|
|
|
tabular.setRightLine(tabular.cellIndex(r, c), lineSet);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2001-04-04 22:08:13 +00:00
|
|
|
}
|
2002-03-21 17:09:55 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_ALIGN_LEFT:
|
|
|
|
case Tabular::M_ALIGN_RIGHT:
|
|
|
|
case Tabular::M_ALIGN_CENTER:
|
|
|
|
case Tabular::ALIGN_LEFT:
|
|
|
|
case Tabular::ALIGN_RIGHT:
|
|
|
|
case Tabular::ALIGN_CENTER:
|
|
|
|
case Tabular::ALIGN_BLOCK:
|
2010-06-05 07:44:44 +00:00
|
|
|
case Tabular::ALIGN_DECIMAL:
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
2010-11-20 07:57:35 +00:00
|
|
|
tabular.setAlignment(tabular.cellIndex(r, c), setAlign,
|
|
|
|
!tabular.getPWidth(c).zero());
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::M_VALIGN_TOP:
|
|
|
|
case Tabular::M_VALIGN_BOTTOM:
|
|
|
|
case Tabular::M_VALIGN_MIDDLE:
|
2001-04-04 09:42:56 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::VALIGN_TOP:
|
|
|
|
case Tabular::VALIGN_BOTTOM:
|
|
|
|
case Tabular::VALIGN_MIDDLE:
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
|
|
|
tabular.setVAlignment(tabular.cellIndex(r, c), setVAlign, flag);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2010-10-29 10:15:50 +00:00
|
|
|
case Tabular::SET_MULTICOLUMN: {
|
2004-11-24 16:48:21 +00:00
|
|
|
if (!cur.selection()) {
|
|
|
|
// just multicol for one single cell
|
|
|
|
// check whether we are completely in a multicol
|
2010-10-29 10:15:50 +00:00
|
|
|
if (!tabular.isMultiColumn(cur.idx()))
|
2011-09-25 06:50:03 +00:00
|
|
|
tabular.setMultiColumn(cur.idx(), 1,
|
|
|
|
tabular.rightLine(cur.idx()));
|
2003-04-10 20:56:16 +00:00
|
|
|
break;
|
2001-04-04 09:42:56 +00:00
|
|
|
}
|
2012-12-24 10:51:28 +00:00
|
|
|
// we have a selection so this means we just add all these
|
2001-04-04 09:42:56 +00:00
|
|
|
// cells to form a multicolumn cell
|
2004-12-03 13:57:50 +00:00
|
|
|
idx_type const s_start = cur.selBegin().idx();
|
2010-02-12 18:36:20 +00:00
|
|
|
row_type const col_start = tabular.cellColumn(s_start);
|
|
|
|
row_type const col_end = tabular.cellColumn(cur.selEnd().idx());
|
2011-09-25 06:50:03 +00:00
|
|
|
cur.idx() = tabular.setMultiColumn(s_start, col_end - col_start + 1,
|
|
|
|
tabular.rightLine(cur.selEnd().idx()));
|
2010-02-11 01:07:54 +00:00
|
|
|
cur.pit() = 0;
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.setSelection(false);
|
|
|
|
break;
|
|
|
|
}
|
2010-10-29 10:15:50 +00:00
|
|
|
|
|
|
|
case Tabular::UNSET_MULTICOLUMN: {
|
2010-10-29 04:09:49 +00:00
|
|
|
if (!cur.selection()) {
|
2010-10-29 10:15:50 +00:00
|
|
|
if (tabular.isMultiColumn(cur.idx()))
|
|
|
|
tabular.unsetMultiColumn(cur.idx());
|
2010-10-29 04:09:49 +00:00
|
|
|
}
|
2010-11-01 03:26:25 +00:00
|
|
|
break;
|
2010-10-29 10:15:50 +00:00
|
|
|
}
|
2010-10-29 04:09:49 +00:00
|
|
|
|
2010-10-29 10:15:50 +00:00
|
|
|
case Tabular::MULTICOLUMN: {
|
2011-09-25 07:13:56 +00:00
|
|
|
if (!cur.selection()) {
|
|
|
|
if (tabular.isMultiColumn(cur.idx()))
|
|
|
|
tabularFeatures(cur, Tabular::UNSET_MULTICOLUMN);
|
|
|
|
else
|
|
|
|
tabularFeatures(cur, Tabular::SET_MULTICOLUMN);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bool merge = false;
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
|
|
|
|
row_type const r = sel_row_start;
|
|
|
|
if (!tabular.isMultiColumn(tabular.cellIndex(r, c))
|
|
|
|
|| (r > sel_row_start && !tabular.isPartOfMultiColumn(r, c)))
|
|
|
|
merge = true;
|
|
|
|
}
|
|
|
|
// If the selection contains at least one singlecol cell
|
|
|
|
// or multiple multicol cells,
|
|
|
|
// we assume the user will merge is to a single multicol
|
|
|
|
if (merge)
|
2010-10-29 10:15:50 +00:00
|
|
|
tabularFeatures(cur, Tabular::SET_MULTICOLUMN);
|
2011-09-25 07:13:56 +00:00
|
|
|
else
|
|
|
|
tabularFeatures(cur, Tabular::UNSET_MULTICOLUMN);
|
2010-10-29 10:15:50 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Tabular::SET_MULTIROW: {
|
2010-02-11 01:07:54 +00:00
|
|
|
if (!cur.selection()) {
|
|
|
|
// just multirow for one single cell
|
|
|
|
// check whether we are completely in a multirow
|
2010-10-29 10:15:50 +00:00
|
|
|
if (!tabular.isMultiRow(cur.idx()))
|
2011-09-23 17:12:20 +00:00
|
|
|
tabular.setMultiRow(cur.idx(), 1,
|
2014-02-14 02:17:20 +00:00
|
|
|
tabular.bottomLine(cur.idx()),
|
|
|
|
tabular.getAlignment(cur.idx()));
|
2010-02-11 01:07:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
// we have a selection so this means we just add all this
|
|
|
|
// cells to form a multirow cell
|
|
|
|
idx_type const s_start = cur.selBegin().idx();
|
2010-02-12 18:36:20 +00:00
|
|
|
row_type const row_start = tabular.cellRow(s_start);
|
|
|
|
row_type const row_end = tabular.cellRow(cur.selEnd().idx());
|
2011-09-23 17:12:20 +00:00
|
|
|
cur.idx() = tabular.setMultiRow(s_start, row_end - row_start + 1,
|
2014-02-14 02:17:20 +00:00
|
|
|
tabular.bottomLine(cur.selEnd().idx()),
|
|
|
|
tabular.getAlignment(cur.selEnd().idx()));
|
2004-11-24 21:53:46 +00:00
|
|
|
cur.pit() = 0;
|
2004-10-23 09:46:33 +00:00
|
|
|
cur.pos() = 0;
|
2008-09-24 21:27:41 +00:00
|
|
|
cur.setSelection(false);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2000-05-26 13:09:14 +00:00
|
|
|
}
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2010-10-29 10:15:50 +00:00
|
|
|
case Tabular::UNSET_MULTIROW: {
|
|
|
|
if (!cur.selection()) {
|
|
|
|
if (tabular.isMultiRow(cur.idx()))
|
|
|
|
tabular.unsetMultiRow(cur.idx());
|
|
|
|
}
|
2010-11-01 03:26:25 +00:00
|
|
|
break;
|
2010-10-29 10:15:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
case Tabular::MULTIROW: {
|
2011-09-25 07:13:56 +00:00
|
|
|
if (!cur.selection()) {
|
|
|
|
if (tabular.isMultiRow(cur.idx()))
|
|
|
|
tabularFeatures(cur, Tabular::UNSET_MULTIROW);
|
|
|
|
else
|
|
|
|
tabularFeatures(cur, Tabular::SET_MULTIROW);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bool merge = false;
|
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
col_type const c = sel_col_start;
|
|
|
|
if (!tabular.isMultiRow(tabular.cellIndex(r, c))
|
|
|
|
|| (r > sel_row_start && !tabular.isPartOfMultiRow(r, c)))
|
|
|
|
merge = true;
|
|
|
|
}
|
|
|
|
// If the selection contains at least one singlerow cell
|
|
|
|
// or multiple multirow cells,
|
|
|
|
// we assume the user will merge is to a single multirow
|
|
|
|
if (merge)
|
2010-10-29 10:15:50 +00:00
|
|
|
tabularFeatures(cur, Tabular::SET_MULTIROW);
|
2011-09-25 07:13:56 +00:00
|
|
|
else
|
|
|
|
tabularFeatures(cur, Tabular::UNSET_MULTIROW);
|
2010-10-29 10:15:50 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_ALL_LINES:
|
2001-04-04 22:08:13 +00:00
|
|
|
setLines = true;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_ALL_LINES:
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
|
|
|
|
idx_type const cell = tabular.cellIndex(r, c);
|
2010-03-04 20:20:45 +00:00
|
|
|
tabular.setTopLine(cell, setLines);
|
|
|
|
tabular.setBottomLine(cell, setLines);
|
|
|
|
tabular.setRightLine(cell, setLines);
|
|
|
|
tabular.setLeftLine(cell, setLines);
|
|
|
|
}
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2008-03-20 08:45:40 +00:00
|
|
|
case Tabular::SET_BORDER_LINES:
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
tabular.setLeftLine(tabular.cellIndex(r, sel_col_start), true);
|
|
|
|
tabular.setRightLine(tabular.cellIndex(r, sel_col_end), true);
|
2008-03-20 08:45:40 +00:00
|
|
|
}
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
|
|
|
|
tabular.setTopLine(tabular.cellIndex(sel_row_start, c), true);
|
|
|
|
tabular.setBottomLine(tabular.cellIndex(sel_row_end, c), true);
|
2008-03-20 08:45:40 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LONGTABULAR:
|
2008-04-21 13:33:39 +00:00
|
|
|
tabular.is_long_tabular = true;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LONGTABULAR:
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < tabular.nrows(); ++r) {
|
|
|
|
if (tabular.ltCaption(r)) {
|
|
|
|
cur.idx() = tabular.cellIndex(r, 0);
|
2009-11-22 18:37:08 +00:00
|
|
|
cur.pit() = 0;
|
|
|
|
cur.pos() = 0;
|
|
|
|
tabularFeatures(cur, Tabular::TOGGLE_LTCAPTION);
|
|
|
|
}
|
|
|
|
}
|
2008-04-21 13:33:39 +00:00
|
|
|
tabular.is_long_tabular = false;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_ROTATE_TABULAR:
|
2012-03-19 00:21:26 +00:00
|
|
|
tabular.rotate = convert<int>(value);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_ROTATE_TABULAR:
|
2012-03-19 00:21:26 +00:00
|
|
|
tabular.rotate = 0;
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-05-12 20:59:21 +00:00
|
|
|
case Tabular::TOGGLE_ROTATE_TABULAR:
|
2012-03-19 00:21:26 +00:00
|
|
|
// when pressing the rotate button we default to 90° rotation
|
2012-03-21 22:04:45 +00:00
|
|
|
tabular.rotate != 0 ? tabular.rotate = 0 : tabular.rotate = 90;
|
2007-05-12 20:59:21 +00:00
|
|
|
break;
|
|
|
|
|
2009-01-03 18:33:09 +00:00
|
|
|
case Tabular::TABULAR_VALIGN_TOP:
|
|
|
|
tabular.tabular_valignment = Tabular::LYX_VALIGN_TOP;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::TABULAR_VALIGN_MIDDLE:
|
|
|
|
tabular.tabular_valignment = Tabular::LYX_VALIGN_MIDDLE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::TABULAR_VALIGN_BOTTOM:
|
|
|
|
tabular.tabular_valignment = Tabular::LYX_VALIGN_BOTTOM;
|
|
|
|
break;
|
|
|
|
|
2009-07-11 13:09:45 +00:00
|
|
|
case Tabular::LONGTABULAR_ALIGN_LEFT:
|
|
|
|
tabular.longtabular_alignment = Tabular::LYX_LONGTABULAR_ALIGN_LEFT;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::LONGTABULAR_ALIGN_CENTER:
|
|
|
|
tabular.longtabular_alignment = Tabular::LYX_LONGTABULAR_ALIGN_CENTER;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Tabular::LONGTABULAR_ALIGN_RIGHT:
|
|
|
|
tabular.longtabular_alignment = Tabular::LYX_LONGTABULAR_ALIGN_RIGHT;
|
|
|
|
break;
|
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2009-07-11 13:09:45 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_ROTATE_CELL:
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
2012-03-16 01:29:37 +00:00
|
|
|
tabular.setRotateCell(tabular.cellIndex(r, c), convert<int>(value));
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_ROTATE_CELL:
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
2012-03-19 00:28:38 +00:00
|
|
|
tabular.setRotateCell(tabular.cellIndex(r, c), 0);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-05-12 20:59:21 +00:00
|
|
|
case Tabular::TOGGLE_ROTATE_CELL:
|
|
|
|
{
|
|
|
|
bool oneNotRotated = oneCellHasRotationState(false,
|
|
|
|
sel_row_start, sel_row_end, sel_col_start, sel_col_end);
|
2007-05-28 22:27:45 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
2012-03-16 01:29:37 +00:00
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c) {
|
|
|
|
// when pressing the rotate cell button we default to 90° rotation
|
|
|
|
if (oneNotRotated)
|
2012-03-19 00:28:38 +00:00
|
|
|
tabular.setRotateCell(tabular.cellIndex(r, c), 90);
|
2012-03-16 01:29:37 +00:00
|
|
|
else
|
2012-03-19 00:28:38 +00:00
|
|
|
tabular.setRotateCell(tabular.cellIndex(r, c), 0);
|
2012-03-16 01:29:37 +00:00
|
|
|
}
|
2007-05-12 20:59:21 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_USEBOX: {
|
|
|
|
Tabular::BoxType val = Tabular::BoxType(convert<int>(value));
|
2004-10-23 09:21:38 +00:00
|
|
|
if (val == tabular.getUsebox(cur.idx()))
|
2007-04-26 12:54:21 +00:00
|
|
|
val = Tabular::BOX_NONE;
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
|
|
|
tabular.setUsebox(tabular.cellIndex(r, c), val);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
|
|
|
}
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTFIRSTHEAD:
|
2001-12-19 16:13:21 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTFIRSTHEAD:
|
2003-07-18 16:23:17 +00:00
|
|
|
tabular.getRowOfLTFirstHead(row, ltt);
|
2001-12-19 21:25:34 +00:00
|
|
|
checkLongtableSpecial(ltt, value, flag);
|
2003-06-13 07:37:48 +00:00
|
|
|
tabular.setLTHead(row, flag, ltt, true);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTHEAD:
|
2001-12-19 16:13:21 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTHEAD:
|
2003-07-18 16:23:17 +00:00
|
|
|
tabular.getRowOfLTHead(row, ltt);
|
2001-12-19 21:25:34 +00:00
|
|
|
checkLongtableSpecial(ltt, value, flag);
|
2003-06-13 07:37:48 +00:00
|
|
|
tabular.setLTHead(row, flag, ltt, false);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTFOOT:
|
2001-12-19 16:13:21 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTFOOT:
|
2003-07-18 16:23:17 +00:00
|
|
|
tabular.getRowOfLTFoot(row, ltt);
|
2001-12-19 21:25:34 +00:00
|
|
|
checkLongtableSpecial(ltt, value, flag);
|
2003-06-13 07:37:48 +00:00
|
|
|
tabular.setLTFoot(row, flag, ltt, false);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_LTLASTFOOT:
|
2001-12-19 16:13:21 +00:00
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTLASTFOOT:
|
2003-07-18 16:23:17 +00:00
|
|
|
tabular.getRowOfLTLastFoot(row, ltt);
|
2001-12-19 21:25:34 +00:00
|
|
|
checkLongtableSpecial(ltt, value, flag);
|
2003-06-13 07:37:48 +00:00
|
|
|
tabular.setLTFoot(row, flag, ltt, true);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2012-05-31 11:56:07 +00:00
|
|
|
case Tabular::UNSET_LTNEWPAGE:
|
|
|
|
flag = false;
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_LTNEWPAGE:
|
2012-05-31 11:56:07 +00:00
|
|
|
tabular.setLTNewPage(row, flag);
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2010-10-29 04:09:49 +00:00
|
|
|
case Tabular::SET_LTCAPTION: {
|
2010-10-30 11:28:16 +00:00
|
|
|
if (tabular.ltCaption(row))
|
|
|
|
break;
|
2010-10-29 04:09:49 +00:00
|
|
|
cur.idx() = tabular.setLTCaption(row, true);
|
|
|
|
cur.pit() = 0;
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.setSelection(false);
|
2010-10-29 11:33:48 +00:00
|
|
|
// If a row is set as caption, then also insert
|
2010-10-29 04:09:49 +00:00
|
|
|
// a caption. Otherwise the LaTeX output is broken.
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_INSET_SELECT_ALL));
|
|
|
|
lyx::dispatch(FuncRequest(LFUN_CAPTION_INSERT));
|
|
|
|
break;
|
|
|
|
}
|
2014-07-26 14:29:23 +00:00
|
|
|
|
2010-10-29 04:09:49 +00:00
|
|
|
case Tabular::UNSET_LTCAPTION: {
|
2010-10-30 11:28:16 +00:00
|
|
|
if (!tabular.ltCaption(row))
|
|
|
|
break;
|
2010-10-29 04:09:49 +00:00
|
|
|
cur.idx() = tabular.setLTCaption(row, false);
|
|
|
|
cur.pit() = 0;
|
|
|
|
cur.pos() = 0;
|
|
|
|
cur.setSelection(false);
|
|
|
|
FuncRequest fr(LFUN_INSET_DISSOLVE, "caption");
|
|
|
|
if (lyx::getStatus(fr).enabled())
|
|
|
|
lyx::dispatch(fr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-03-01 15:50:46 +00:00
|
|
|
case Tabular::TOGGLE_LTCAPTION: {
|
2010-10-29 11:33:48 +00:00
|
|
|
if (tabular.ltCaption(row))
|
|
|
|
tabularFeatures(cur, Tabular::UNSET_LTCAPTION);
|
|
|
|
else
|
|
|
|
tabularFeatures(cur, Tabular::SET_LTCAPTION);
|
2008-05-04 07:51:50 +00:00
|
|
|
break;
|
2009-03-01 15:50:46 +00:00
|
|
|
}
|
2008-05-04 07:51:50 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_BOOKTABS:
|
2008-04-21 13:33:39 +00:00
|
|
|
tabular.use_booktabs = true;
|
2006-07-03 19:13:56 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::UNSET_BOOKTABS:
|
2008-04-21 13:33:39 +00:00
|
|
|
tabular.use_booktabs = false;
|
2006-07-03 19:13:56 +00:00
|
|
|
break;
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_TOP_SPACE: {
|
2007-04-28 12:58:49 +00:00
|
|
|
Length len;
|
2006-07-03 19:13:56 +00:00
|
|
|
if (value == "default")
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
tabular.row_info[r].top_space_default = true;
|
2010-02-18 08:28:46 +00:00
|
|
|
else if (value == "none")
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
tabular.row_info[r].top_space_default = false;
|
|
|
|
tabular.row_info[r].top_space = len;
|
2006-07-03 19:13:56 +00:00
|
|
|
}
|
2010-02-18 08:28:46 +00:00
|
|
|
else if (isValidLength(value, &len))
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
tabular.row_info[r].top_space_default = false;
|
|
|
|
tabular.row_info[r].top_space = len;
|
2006-07-03 19:13:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_BOTTOM_SPACE: {
|
2007-04-28 12:58:49 +00:00
|
|
|
Length len;
|
2006-07-03 19:13:56 +00:00
|
|
|
if (value == "default")
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
tabular.row_info[r].bottom_space_default = true;
|
2010-02-18 08:28:46 +00:00
|
|
|
else if (value == "none")
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
tabular.row_info[r].bottom_space_default = false;
|
|
|
|
tabular.row_info[r].bottom_space = len;
|
2006-07-03 19:13:56 +00:00
|
|
|
}
|
2010-02-18 08:28:46 +00:00
|
|
|
else if (isValidLength(value, &len))
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
tabular.row_info[r].bottom_space_default = false;
|
|
|
|
tabular.row_info[r].bottom_space = len;
|
2006-07-03 19:13:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::SET_INTERLINE_SPACE: {
|
2007-04-28 12:58:49 +00:00
|
|
|
Length len;
|
2006-07-03 19:13:56 +00:00
|
|
|
if (value == "default")
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r)
|
|
|
|
tabular.row_info[r].interline_space_default = true;
|
2010-02-18 08:28:46 +00:00
|
|
|
else if (value == "none")
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
tabular.row_info[r].interline_space_default = false;
|
|
|
|
tabular.row_info[r].interline_space = len;
|
2006-07-03 19:13:56 +00:00
|
|
|
}
|
2010-02-18 08:28:46 +00:00
|
|
|
else if (isValidLength(value, &len))
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = sel_row_start; r <= sel_row_end; ++r) {
|
|
|
|
tabular.row_info[r].interline_space_default = false;
|
|
|
|
tabular.row_info[r].interline_space = len;
|
2006-07-03 19:13:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-06-05 07:44:44 +00:00
|
|
|
case Tabular::SET_DECIMAL_POINT:
|
|
|
|
for (col_type c = sel_col_start; c <= sel_col_end; ++c)
|
|
|
|
tabular.column_info[c].decimal_point = from_utf8(value);
|
|
|
|
break;
|
|
|
|
|
2001-04-04 22:08:13 +00:00
|
|
|
// dummy stuff just to avoid warnings
|
2007-04-26 12:54:21 +00:00
|
|
|
case Tabular::LAST_ACTION:
|
2001-04-04 09:42:56 +00:00
|
|
|
break;
|
2000-05-26 13:09:14 +00:00
|
|
|
}
|
2000-04-19 14:42:19 +00:00
|
|
|
}
|
2000-05-04 08:14:34 +00:00
|
|
|
|
2000-07-15 23:51:46 +00:00
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetTabular::copySelection(Cursor & cur)
|
2000-08-23 15:18:19 +00:00
|
|
|
{
|
2004-02-13 16:22:53 +00:00
|
|
|
if (!cur.selection())
|
2001-04-04 09:42:56 +00:00
|
|
|
return false;
|
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
row_type rs, re;
|
|
|
|
col_type cs, ce;
|
2004-02-13 16:22:53 +00:00
|
|
|
getSelection(cur, rs, re, cs, ce);
|
2001-04-04 09:42:56 +00:00
|
|
|
|
2007-04-26 12:54:21 +00:00
|
|
|
paste_tabular.reset(new Tabular(tabular));
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < rs; ++r)
|
2003-06-12 11:52:44 +00:00
|
|
|
paste_tabular->deleteRow(0);
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
row_type const rows = re - rs + 1;
|
2010-03-05 18:10:34 +00:00
|
|
|
while (paste_tabular->nrows() > rows)
|
2003-06-12 11:52:44 +00:00
|
|
|
paste_tabular->deleteRow(rows);
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
for (col_type c = 0; c < cs; ++c)
|
2003-06-12 11:52:44 +00:00
|
|
|
paste_tabular->deleteColumn(0);
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
col_type const columns = ce - cs + 1;
|
2010-03-05 18:10:34 +00:00
|
|
|
while (paste_tabular->ncols() > columns)
|
2003-06-12 11:52:44 +00:00
|
|
|
paste_tabular->deleteColumn(columns);
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2008-07-23 12:13:41 +00:00
|
|
|
paste_tabular->setBuffer(tabular.buffer());
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
odocstringstream os;
|
2007-03-18 10:59:16 +00:00
|
|
|
OutputParams const runparams(0);
|
2013-03-08 19:52:18 +00:00
|
|
|
paste_tabular->plaintext(os, runparams, 0, true, '\t', INT_MAX);
|
2007-01-13 18:29:50 +00:00
|
|
|
// Needed for the "Edit->Paste recent" menu and the system clipboard.
|
|
|
|
cap::copySelection(cur, os.str());
|
|
|
|
|
2005-09-06 17:39:39 +00:00
|
|
|
// mark tabular stack dirty
|
2006-04-05 23:56:29 +00:00
|
|
|
// FIXME: this is a workaround for bug 1919. Should be removed for 1.5,
|
2005-09-06 17:39:39 +00:00
|
|
|
// when we (hopefully) have a one-for-all paste mechanism.
|
2007-01-13 18:29:50 +00:00
|
|
|
// This must be called after cap::copySelection.
|
2007-01-04 11:00:09 +00:00
|
|
|
dirtyTabularStack(true);
|
2005-09-06 17:39:39 +00:00
|
|
|
|
2001-04-04 09:42:56 +00:00
|
|
|
return true;
|
2000-08-23 15:18:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetTabular::pasteClipboard(Cursor & cur)
|
2000-08-23 15:18:19 +00:00
|
|
|
{
|
2001-04-04 09:42:56 +00:00
|
|
|
if (!paste_tabular)
|
|
|
|
return false;
|
2009-05-17 21:22:02 +00:00
|
|
|
col_type actcol = tabular.cellColumn(cur.idx());
|
|
|
|
row_type actrow = tabular.cellRow(cur.idx());
|
|
|
|
|
|
|
|
if (cur.selIsMultiCell()) {
|
|
|
|
row_type re;
|
|
|
|
col_type ce;
|
|
|
|
getSelection(cur, actrow, re, actcol, ce);
|
|
|
|
}
|
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
for (row_type r1 = 0, r2 = actrow;
|
2010-03-05 18:10:34 +00:00
|
|
|
r1 < paste_tabular->nrows() && r2 < tabular.nrows();
|
2001-04-04 22:08:13 +00:00
|
|
|
++r1, ++r2) {
|
2004-12-03 13:57:50 +00:00
|
|
|
for (col_type c1 = 0, c2 = actcol;
|
2010-03-05 18:10:34 +00:00
|
|
|
c1 < paste_tabular->ncols() && c2 < tabular.ncols();
|
2001-04-04 22:08:13 +00:00
|
|
|
++c1, ++c2) {
|
2003-07-21 11:01:29 +00:00
|
|
|
if (paste_tabular->isPartOfMultiColumn(r1, c1) &&
|
2009-05-17 21:22:02 +00:00
|
|
|
tabular.isPartOfMultiColumn(r2, c2))
|
2001-04-04 09:42:56 +00:00
|
|
|
continue;
|
2003-07-21 11:01:29 +00:00
|
|
|
if (paste_tabular->isPartOfMultiColumn(r1, c1)) {
|
2001-04-04 09:42:56 +00:00
|
|
|
--c2;
|
|
|
|
continue;
|
|
|
|
}
|
2003-07-21 11:01:29 +00:00
|
|
|
if (tabular.isPartOfMultiColumn(r2, c2)) {
|
2001-04-04 09:42:56 +00:00
|
|
|
--c1;
|
|
|
|
continue;
|
|
|
|
}
|
2008-03-21 06:16:05 +00:00
|
|
|
shared_ptr<InsetTableCell> inset(
|
2008-03-25 13:32:38 +00:00
|
|
|
new InsetTableCell(*paste_tabular->cellInset(r1, c1)));
|
2005-05-12 12:22:39 +00:00
|
|
|
tabular.setCellInset(r2, c2, inset);
|
2010-02-11 01:07:54 +00:00
|
|
|
// FIXME?: why do we need to do this explicitly? (EL)
|
|
|
|
tabular.cellInset(r2, c2)->setBuffer(tabular.buffer());
|
|
|
|
|
2006-10-20 09:29:19 +00:00
|
|
|
// FIXME: change tracking (MG)
|
2014-03-29 22:52:36 +00:00
|
|
|
inset->setChange(Change(buffer().params().track_changes ?
|
2007-05-28 22:27:45 +00:00
|
|
|
Change::INSERTED : Change::UNCHANGED));
|
2005-05-12 12:22:39 +00:00
|
|
|
cur.pos() = 0;
|
2001-04-04 09:42:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
2000-08-23 15:18:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetTabular::cutSelection(Cursor & cur)
|
2000-08-23 15:18:19 +00:00
|
|
|
{
|
2004-02-13 16:22:53 +00:00
|
|
|
if (!cur.selection())
|
|
|
|
return;
|
2003-07-31 10:48:50 +00:00
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
row_type rs, re;
|
|
|
|
col_type cs, ce;
|
2004-04-03 08:37:12 +00:00
|
|
|
getSelection(cur, rs, re, cs, ce);
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = rs; r <= re; ++r) {
|
|
|
|
for (col_type c = cs; c <= ce; ++c) {
|
2008-03-21 06:16:05 +00:00
|
|
|
shared_ptr<InsetTableCell> t
|
2010-03-05 18:10:34 +00:00
|
|
|
= cell(tabular.cellIndex(r, c));
|
2014-03-29 22:52:36 +00:00
|
|
|
if (buffer().params().track_changes)
|
2006-10-06 18:53:35 +00:00
|
|
|
// FIXME: Change tracking (MG)
|
2006-10-20 09:29:19 +00:00
|
|
|
t->setChange(Change(Change::DELETED));
|
2005-09-07 10:37:05 +00:00
|
|
|
else
|
|
|
|
t->clear();
|
|
|
|
}
|
|
|
|
}
|
2004-10-23 08:50:30 +00:00
|
|
|
|
|
|
|
// cursor position might be invalid now
|
2006-09-20 12:16:26 +00:00
|
|
|
if (cur.pit() > cur.lastpit())
|
|
|
|
cur.pit() = cur.lastpit();
|
|
|
|
if (cur.pos() > cur.lastpos())
|
|
|
|
cur.pos() = cur.lastpos();
|
2004-10-23 08:50:30 +00:00
|
|
|
cur.clearSelection();
|
2000-08-23 15:18:19 +00:00
|
|
|
}
|
|
|
|
|
2001-04-04 22:08:13 +00:00
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
bool InsetTabular::isRightToLeft(Cursor & cur) const
|
2001-01-08 16:14:09 +00:00
|
|
|
{
|
2013-04-25 21:27:10 +00:00
|
|
|
// LASSERT: It might be better to abandon this Buffer.
|
|
|
|
LASSERT(cur.depth() > 1, return false);
|
2005-02-08 13:18:05 +00:00
|
|
|
Paragraph const & parentpar = cur[cur.depth() - 2].paragraph();
|
2006-10-21 00:16:43 +00:00
|
|
|
pos_type const parentpos = cur[cur.depth() - 2].pos();
|
2008-11-17 11:46:07 +00:00
|
|
|
return parentpar.getFontSettings(buffer().params(),
|
2006-04-09 00:26:19 +00:00
|
|
|
parentpos).language()->rightToLeft();
|
2001-01-08 16:14:09 +00:00
|
|
|
}
|
2001-04-27 14:03:25 +00:00
|
|
|
|
2010-03-05 18:10:34 +00:00
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
docstring InsetTabular::asString(idx_type stidx, idx_type enidx,
|
2008-08-08 21:26:18 +00:00
|
|
|
bool intoInsets)
|
|
|
|
{
|
|
|
|
LASSERT(stidx <= enidx, return docstring());
|
|
|
|
docstring retval;
|
|
|
|
col_type const col1 = tabular.cellColumn(stidx);
|
|
|
|
col_type const col2 = tabular.cellColumn(enidx);
|
|
|
|
row_type const row1 = tabular.cellRow(stidx);
|
|
|
|
row_type const row2 = tabular.cellRow(enidx);
|
|
|
|
bool first = true;
|
|
|
|
for (col_type col = col1; col <= col2; col++)
|
|
|
|
for (row_type row = row1; row <= row2; row++) {
|
|
|
|
if (!first)
|
|
|
|
retval += "\n";
|
|
|
|
else
|
|
|
|
first = false;
|
|
|
|
retval += tabular.cellInset(row, col)->asString(intoInsets);
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2001-06-25 00:06:33 +00:00
|
|
|
|
2007-04-26 14:56:30 +00:00
|
|
|
void InsetTabular::getSelection(Cursor & cur,
|
2004-12-03 13:57:50 +00:00
|
|
|
row_type & rs, row_type & re, col_type & cs, col_type & ce) const
|
2001-05-28 15:11:24 +00:00
|
|
|
{
|
2004-03-25 09:16:36 +00:00
|
|
|
CursorSlice const & beg = cur.selBegin();
|
|
|
|
CursorSlice const & end = cur.selEnd();
|
2007-09-04 10:52:08 +00:00
|
|
|
cs = tabular.cellColumn(beg.idx());
|
|
|
|
ce = tabular.cellColumn(end.idx());
|
2010-03-04 21:31:06 +00:00
|
|
|
if (cs > ce)
|
|
|
|
swap(cs, ce);
|
2001-05-28 15:11:24 +00:00
|
|
|
|
2007-09-04 10:52:08 +00:00
|
|
|
rs = tabular.cellRow(beg.idx());
|
|
|
|
re = tabular.cellRow(end.idx());
|
2004-02-13 16:22:53 +00:00
|
|
|
if (rs > re)
|
|
|
|
swap(rs, re);
|
2001-05-28 15:11:24 +00:00
|
|
|
}
|
|
|
|
|
2001-07-24 22:08:49 +00:00
|
|
|
|
2007-04-29 23:33:02 +00:00
|
|
|
Text * InsetTabular::getText(int idx) const
|
2003-10-14 13:01:49 +00:00
|
|
|
{
|
2004-11-23 23:04:52 +00:00
|
|
|
return size_t(idx) < nargs() ? cell(idx)->getText(0) : 0;
|
2003-10-14 13:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-20 09:29:19 +00:00
|
|
|
void InsetTabular::setChange(Change const & change)
|
2003-02-08 19:18:01 +00:00
|
|
|
{
|
2004-02-16 11:58:51 +00:00
|
|
|
for (idx_type idx = 0; idx < nargs(); ++idx)
|
2006-10-20 09:29:19 +00:00
|
|
|
cell(idx)->setChange(change);
|
2003-02-08 19:18:01 +00:00
|
|
|
}
|
|
|
|
|
2003-03-03 23:19:01 +00:00
|
|
|
|
2009-07-16 08:37:32 +00:00
|
|
|
void InsetTabular::acceptChanges()
|
2006-10-24 06:11:45 +00:00
|
|
|
{
|
|
|
|
for (idx_type idx = 0; idx < nargs(); ++idx)
|
2009-07-16 08:37:32 +00:00
|
|
|
cell(idx)->acceptChanges();
|
2006-10-24 06:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-07-16 08:37:32 +00:00
|
|
|
void InsetTabular::rejectChanges()
|
2006-10-24 21:38:47 +00:00
|
|
|
{
|
|
|
|
for (idx_type idx = 0; idx < nargs(); ++idx)
|
2009-07-16 08:37:32 +00:00
|
|
|
cell(idx)->rejectChanges();
|
2006-10-24 21:38:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Fix bug 4037 and related problems. The patch has been cleaned up a bit
from the one posted to the list.
The basic idea has two parts. First, we hard code an "empty layout"
(called PlainLayout, for want of a better name) in TextClass and read it
before doing anything else. It can therefore be customized by classes,
if they want---say, to make it left-aligned. Second, InsetText's are
divided into three types: (i) normal ones, that use the "default" layout
defined by the text class; (ii) highly restrictive ones, such as ERT and
(not quite an inset) table cells, which demand the empty layout; (iii)
middling ones, which default to an empty layout and use the empty layout
in place of the default. (This is so we don't get the same problem we
had with ERT in e.g. footnotes.) The type of inset is signaled by new
methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout().
(The latter might better be called: useEmptyLayoutInsteadOfDefault(),
but that's silly.) The old InsetText::forceDefaultParagraphs() has been
split into these, plus a new method InsetText::allowParagraphCustomization().
A lot of the changes just adapt to this change.
The other big change is in GuiToolbar: We want to show LyXDefault and
the "default" layout only when they're active.
There are a handful of places where I'm not entirely sure whether we
should be using forceEmptyLayout or !allowParagraphCustomization() or
both. The InsetCaption is one of these. These places, and some others,
are marked with FIXMEs, so I'd appreciate it if people would search
through the patch and let me know whether these need changing. If they
don't, the FIXMEs can be deleted.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
|
|
|
bool InsetTabular::allowParagraphCustomization(idx_type cell) const
|
2002-01-08 14:24:49 +00:00
|
|
|
{
|
2004-12-03 13:57:50 +00:00
|
|
|
return tabular.getPWidth(cell).zero();
|
2002-01-08 14:24:49 +00:00
|
|
|
}
|
2002-03-04 15:42:54 +00:00
|
|
|
|
2003-07-18 16:13:33 +00:00
|
|
|
|
2008-07-10 17:41:52 +00:00
|
|
|
bool InsetTabular::forcePlainLayout(idx_type cell) const
|
2008-03-19 16:21:33 +00:00
|
|
|
{
|
|
|
|
return !tabular.getPWidth(cell).zero();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-15 22:49:14 +00:00
|
|
|
bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
|
2002-03-21 17:09:55 +00:00
|
|
|
bool usePaste)
|
2002-03-04 15:42:54 +00:00
|
|
|
{
|
2002-03-26 11:05:30 +00:00
|
|
|
if (buf.length() <= 0)
|
|
|
|
return true;
|
2002-04-22 16:31:14 +00:00
|
|
|
|
2004-12-03 13:57:50 +00:00
|
|
|
col_type cols = 1;
|
|
|
|
row_type rows = 1;
|
|
|
|
col_type maxCols = 1;
|
2008-02-27 23:03:26 +00:00
|
|
|
size_t const len = buf.length();
|
|
|
|
size_t p = 0;
|
2002-03-04 15:42:54 +00:00
|
|
|
|
2006-09-03 07:02:38 +00:00
|
|
|
while (p < len &&
|
2006-10-21 00:16:43 +00:00
|
|
|
(p = buf.find_first_of(from_ascii("\t\n"), p)) != docstring::npos) {
|
2002-03-04 15:42:54 +00:00
|
|
|
switch (buf[p]) {
|
|
|
|
case '\t':
|
|
|
|
++cols;
|
|
|
|
break;
|
|
|
|
case '\n':
|
2003-10-14 13:01:49 +00:00
|
|
|
if (p + 1 < len)
|
2002-03-04 15:42:54 +00:00
|
|
|
++rows;
|
|
|
|
maxCols = max(cols, maxCols);
|
|
|
|
cols = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++p;
|
|
|
|
}
|
|
|
|
maxCols = max(cols, maxCols);
|
2007-04-26 12:54:21 +00:00
|
|
|
Tabular * loctab;
|
2004-12-03 13:57:50 +00:00
|
|
|
idx_type cell = 0;
|
|
|
|
col_type ocol = 0;
|
|
|
|
row_type row = 0;
|
2002-03-04 15:42:54 +00:00
|
|
|
if (usePaste) {
|
2009-11-08 15:53:21 +00:00
|
|
|
paste_tabular.reset(new Tabular(buffer_, rows, maxCols));
|
2003-11-03 17:47:28 +00:00
|
|
|
loctab = paste_tabular.get();
|
2002-03-04 15:42:54 +00:00
|
|
|
cols = 0;
|
2006-03-28 14:04:14 +00:00
|
|
|
dirtyTabularStack(true);
|
2002-03-04 15:42:54 +00:00
|
|
|
} else {
|
2003-06-13 07:37:48 +00:00
|
|
|
loctab = &tabular;
|
2004-10-23 09:21:38 +00:00
|
|
|
cell = bv.cursor().idx();
|
2007-09-04 10:52:08 +00:00
|
|
|
ocol = tabular.cellColumn(cell);
|
|
|
|
row = tabular.cellRow(cell);
|
2002-03-04 15:42:54 +00:00
|
|
|
}
|
2003-02-08 19:18:01 +00:00
|
|
|
|
2008-02-27 23:03:26 +00:00
|
|
|
size_t op = 0;
|
2008-04-21 13:33:39 +00:00
|
|
|
idx_type const cells = loctab->numberofcells;
|
2002-03-04 15:42:54 +00:00
|
|
|
p = 0;
|
|
|
|
cols = ocol;
|
2010-03-05 18:10:34 +00:00
|
|
|
rows = loctab->nrows();
|
|
|
|
col_type const columns = loctab->ncols();
|
2003-03-03 23:19:01 +00:00
|
|
|
|
2003-07-18 16:13:33 +00:00
|
|
|
while (cell < cells && p < len && row < rows &&
|
2006-10-21 00:16:43 +00:00
|
|
|
(p = buf.find_first_of(from_ascii("\t\n"), p)) != docstring::npos)
|
2002-03-04 15:42:54 +00:00
|
|
|
{
|
|
|
|
if (p >= len)
|
|
|
|
break;
|
|
|
|
switch (buf[p]) {
|
|
|
|
case '\t':
|
|
|
|
// we can only set this if we are not too far right
|
|
|
|
if (cols < columns) {
|
2008-03-25 13:32:38 +00:00
|
|
|
shared_ptr<InsetTableCell> inset = loctab->cellInset(cell);
|
2008-07-29 12:07:08 +00:00
|
|
|
Font const font = bv.textMetrics(&inset->text()).
|
2008-02-27 23:03:26 +00:00
|
|
|
displayFont(0, 0);
|
2006-10-20 11:44:58 +00:00
|
|
|
inset->setText(buf.substr(op, p - op), font,
|
2014-03-29 22:52:36 +00:00
|
|
|
buffer().params().track_changes);
|
2002-03-04 15:42:54 +00:00
|
|
|
++cols;
|
|
|
|
++cell;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
// we can only set this if we are not too far right
|
2002-03-26 11:05:30 +00:00
|
|
|
if (cols < columns) {
|
2008-03-25 13:32:38 +00:00
|
|
|
shared_ptr<InsetTableCell> inset = tabular.cellInset(cell);
|
2008-07-29 12:07:08 +00:00
|
|
|
Font const font = bv.textMetrics(&inset->text()).
|
2008-02-27 23:03:26 +00:00
|
|
|
displayFont(0, 0);
|
2006-10-20 11:44:58 +00:00
|
|
|
inset->setText(buf.substr(op, p - op), font,
|
2014-03-29 22:52:36 +00:00
|
|
|
buffer().params().track_changes);
|
2002-03-26 11:05:30 +00:00
|
|
|
}
|
2002-03-04 15:42:54 +00:00
|
|
|
cols = ocol;
|
|
|
|
++row;
|
|
|
|
if (row < rows)
|
2007-09-04 10:52:08 +00:00
|
|
|
cell = loctab->cellIndex(row, cols);
|
2002-03-04 15:42:54 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
++p;
|
|
|
|
op = p;
|
|
|
|
}
|
|
|
|
// check for the last cell if there is no trailing '\n'
|
2003-07-18 16:13:33 +00:00
|
|
|
if (cell < cells && op < len) {
|
2008-03-25 13:32:38 +00:00
|
|
|
shared_ptr<InsetTableCell> inset = loctab->cellInset(cell);
|
2008-07-29 12:07:08 +00:00
|
|
|
Font const font = bv.textMetrics(&inset->text()).displayFont(0, 0);
|
2006-10-20 11:44:58 +00:00
|
|
|
inset->setText(buf.substr(op, len - op), font,
|
2014-03-29 22:52:36 +00:00
|
|
|
buffer().params().track_changes);
|
2002-03-26 11:05:30 +00:00
|
|
|
}
|
2002-03-04 15:42:54 +00:00
|
|
|
return true;
|
|
|
|
}
|
2002-08-02 16:39:43 +00:00
|
|
|
|
|
|
|
|
2009-11-22 20:50:35 +00:00
|
|
|
void InsetTabular::addPreview(DocIterator const & inset_pos,
|
|
|
|
PreviewLoader & loader) const
|
2002-08-02 16:39:43 +00:00
|
|
|
{
|
2009-11-22 20:50:35 +00:00
|
|
|
DocIterator cell_pos = inset_pos;
|
|
|
|
|
|
|
|
cell_pos.push_back(CursorSlice(*const_cast<InsetTabular *>(this)));
|
2010-03-05 18:10:34 +00:00
|
|
|
for (row_type r = 0; r < tabular.nrows(); ++r) {
|
|
|
|
for (col_type c = 0; c < tabular.ncols(); ++c) {
|
|
|
|
cell_pos.top().idx() = tabular.cellIndex(r, c);
|
|
|
|
tabular.cellInset(r, c)->addPreview(cell_pos, loader);
|
2009-11-22 20:50:35 +00:00
|
|
|
}
|
2003-11-10 09:06:48 +00:00
|
|
|
}
|
2002-08-02 16:39:43 +00:00
|
|
|
}
|
2003-03-09 18:11:57 +00:00
|
|
|
|
|
|
|
|
2008-03-15 12:22:28 +00:00
|
|
|
bool InsetTabular::completionSupported(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
Cursor const & bvCur = cur.bv().cursor();
|
|
|
|
if (&bvCur.inset() != this)
|
|
|
|
return false;
|
|
|
|
return cur.text()->completionSupported(cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetTabular::inlineCompletionSupported(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
return completionSupported(cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetTabular::automaticInlineCompletion() const
|
|
|
|
{
|
|
|
|
return lyxrc.completion_inline_text;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetTabular::automaticPopupCompletion() const
|
|
|
|
{
|
|
|
|
return lyxrc.completion_popup_text;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-16 17:07:10 +00:00
|
|
|
bool InsetTabular::showCompletionCursor() const
|
|
|
|
{
|
|
|
|
return lyxrc.completion_cursor_text;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-15 12:22:28 +00:00
|
|
|
CompletionList const * InsetTabular::createCompletionList(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
return completionSupported(cur) ? cur.text()->createCompletionList(cur) : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
docstring InsetTabular::completionPrefix(Cursor const & cur) const
|
|
|
|
{
|
|
|
|
if (!completionSupported(cur))
|
|
|
|
return docstring();
|
|
|
|
return cur.text()->completionPrefix(cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool InsetTabular::insertCompletion(Cursor & cur, docstring const & s, bool finished)
|
|
|
|
{
|
|
|
|
if (!completionSupported(cur))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return cur.text()->insertCompletion(cur, s, finished);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-26 14:29:23 +00:00
|
|
|
void InsetTabular::completionPosAndDim(Cursor const & cur, int & x, int & y,
|
2008-03-15 12:22:28 +00:00
|
|
|
Dimension & dim) const
|
|
|
|
{
|
|
|
|
TextMetrics const & tm = cur.bv().textMetrics(cur.text());
|
|
|
|
tm.completionPosAndDim(cur, x, y, dim);
|
|
|
|
}
|
2004-02-16 11:58:51 +00:00
|
|
|
|
|
|
|
|
2008-03-27 22:26:24 +00:00
|
|
|
void InsetTabular::string2params(string const & in, InsetTabular & inset)
|
2003-03-09 18:11:57 +00:00
|
|
|
{
|
2003-09-15 11:00:00 +00:00
|
|
|
istringstream data(in);
|
2008-04-02 23:06:22 +00:00
|
|
|
Lexer lex;
|
2003-03-09 18:11:57 +00:00
|
|
|
lex.setStream(data);
|
|
|
|
|
2003-04-24 20:02:49 +00:00
|
|
|
if (in.empty())
|
2004-11-18 12:58:19 +00:00
|
|
|
return;
|
2003-04-29 23:59:39 +00:00
|
|
|
|
2004-11-18 12:58:19 +00:00
|
|
|
string token;
|
|
|
|
lex >> token;
|
2008-03-27 22:26:24 +00:00
|
|
|
if (!lex || token != "tabular") {
|
|
|
|
LYXERR0("Expected arg 1 to be \"tabular\" in " << in);
|
|
|
|
return;
|
|
|
|
}
|
2003-03-09 18:11:57 +00:00
|
|
|
|
|
|
|
// This is part of the inset proper that is usually swallowed
|
|
|
|
// by Buffer::readInset
|
2004-11-18 12:58:19 +00:00
|
|
|
lex >> token;
|
2008-03-27 22:26:24 +00:00
|
|
|
if (!lex || token != "Tabular") {
|
|
|
|
LYXERR0("Expected arg 2 to be \"Tabular\" in " << in);
|
|
|
|
return;
|
|
|
|
}
|
2003-03-10 03:11:54 +00:00
|
|
|
|
2008-02-27 20:43:16 +00:00
|
|
|
inset.read(lex);
|
2003-03-09 18:11:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-27 22:26:24 +00:00
|
|
|
string InsetTabular::params2string(InsetTabular const & inset)
|
2003-03-09 18:11:57 +00:00
|
|
|
{
|
|
|
|
ostringstream data;
|
2008-03-27 22:26:24 +00:00
|
|
|
data << "tabular" << ' ';
|
2008-02-27 20:43:16 +00:00
|
|
|
inset.write(data);
|
2003-03-09 18:11:57 +00:00
|
|
|
data << "\\end_inset\n";
|
2003-09-15 11:00:00 +00:00
|
|
|
return data.str();
|
2003-03-09 18:11:57 +00:00
|
|
|
}
|
2006-10-21 00:16:43 +00:00
|
|
|
|
|
|
|
|
2014-10-13 08:59:50 +00:00
|
|
|
void InsetTabular::setLayoutForHiddenCells(DocumentClass const & dc)
|
|
|
|
{
|
Possible fix for the mystery crash, which is bug #9049.
Investigation of bug #9236 showed that crash to be due to a Paragraph's
holding a dangling pointer to an old and deleted Layout after the
DocumentClass was reset. Since the backtraces look almost identical, it
seems likely that we have the same problem here.
Since this crash seems almost always to involve tables, I looked at the
code in switchBetweenClasses() and found that the Paragraphs that belong
to "hidden" table cells are not seen by the initial recursion using a
ParIterator: It skips right over them. This was confirmed by test code
suggested by Enrico, with results reported in Trac.
The present patch attempts to deal with this problem in the second
recursion, over Insets. When we see an InsetTabular, we call a new
routine that recurses through the cells, looking for hidden ones. If it
finds a hidden one, it then resets the Layout for the cell's Paragraphs
(there should be only one, but we do not make any assumptions) to the
PlainLayout that belongs to the new DocumentClass. This is good enough,
since such cells never have content.
There is extensive discussion of the patch here:
https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg185095.html
Additional testing by Enrico and me confirmed the existence of the
dangling pointer.
2014-08-07 19:00:35 +00:00
|
|
|
for (Tabular::col_type c = 0; c < tabular.ncols(); ++c) {
|
|
|
|
for (Tabular::row_type r = 0; r < tabular.nrows(); ++r) {
|
|
|
|
if (!tabular.isPartOfMultiColumn(r,c) &&
|
|
|
|
!tabular.isPartOfMultiRow(r,c))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ParagraphList & parlist = tabular.cellInset(r,c)->paragraphs();
|
|
|
|
ParagraphList::iterator it = parlist.begin();
|
|
|
|
ParagraphList::iterator const en = parlist.end();
|
|
|
|
for (; it != en; ++it)
|
|
|
|
it->setLayout(dc.plainLayout());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-10-21 00:16:43 +00:00
|
|
|
} // namespace lyx
|