* Licence details can be found in the file COPYING.
*
* \author John Levon
- * \author Jürgen Spitzmüller
- * \author Herbert Voß
+ * \author Jürgen Spitzmüller
+ * \author Herbert Voß
+ * \author Uwe Stöhr
*
* Full author contact details are available in file CREDITS.
*/
#include "GuiTabular.h"
+#include "GuiApplication.h"
#include "GuiSetBorder.h"
#include "GuiView.h"
#include "LengthCombo.h"
#include "BufferView.h"
#include "Cursor.h"
#include "FuncRequest.h"
+#include "FuncStatus.h"
+#include "LyX.h"
#include "LyXRC.h"
#include "insets/InsetTabular.h"
+#include "support/convert.h"
+#include "support/debug.h"
+
#include <QCheckBox>
#include <QPushButton>
#include <QRadioButton>
namespace lyx {
namespace frontend {
-GuiTabular::GuiTabular(GuiView & lv)
- : GuiDialog(lv, "tabular", qt_("Table Settings")),
- // tabular_ is initialised at dialog construction in initialiseParams()
- tabular_(*lv.buffer(), 0, 0)
-{
- active_cell_ = Tabular::npos;
+GuiTabular::GuiTabular(QWidget * parent)
+ : InsetParamsWidget(parent), firstheader_suppressable_(false),
+ lastfooter_suppressable_(false)
+{
setupUi(this);
- widthED->setValidator(unsignedLengthValidator(widthED));
+ tabularWidthED->setValidator(unsignedLengthValidator(tabularWidthED));
+ columnWidthED->setValidator(unsignedLengthValidator(columnWidthED));
+ multirowOffsetED->setValidator(new LengthValidator(multirowOffsetED));
topspaceED->setValidator(new LengthValidator(topspaceED));
bottomspaceED->setValidator(new LengthValidator(bottomspaceED));
interlinespaceED->setValidator(new LengthValidator(interlinespaceED));
- connect(topspaceED, SIGNAL(returnPressed()),
- this, SLOT(topspace_changed()));
- connect(topspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
- this, SLOT(topspace_changed()));
- connect(topspaceCO, SIGNAL(activated(int)), this, SLOT(topspace_changed()));
- connect(bottomspaceED, SIGNAL(returnPressed()),
- this, SLOT(bottomspace_changed()));
- connect(bottomspaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
- this, SLOT(bottomspace_changed()));
- connect(bottomspaceCO, SIGNAL(activated(int)), this, SLOT(bottomspace_changed()));
- connect(interlinespaceED, SIGNAL(returnPressed()),
- this, SLOT(interlinespace_changed()));
- connect(interlinespaceUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)),
- this, SLOT(interlinespace_changed()));
- connect(interlinespaceCO, SIGNAL(activated(int)), this, SLOT(interlinespace_changed()));
- connect(booktabsRB, SIGNAL(clicked(bool)), this, SLOT(booktabsChanged(bool)));
- connect(borderDefaultRB, SIGNAL(clicked(bool)), this, SLOT(booktabsChanged(bool)));
- connect(borderSetPB, SIGNAL(clicked()), this, SLOT(borderSet_clicked()));
- connect(borderUnsetPB, SIGNAL(clicked()), this, SLOT(borderUnset_clicked()));
- connect(longTabularCB, SIGNAL(toggled(bool)), longtableGB, SLOT(setEnabled(bool)));
- connect(longTabularCB, SIGNAL(toggled(bool)), newpageCB, SLOT(setEnabled(bool)));
- connect(hAlignCB, SIGNAL(activated(int)), this, SLOT(hAlign_changed(int)));
- connect(vAlignCB, SIGNAL(activated(int)), this, SLOT(vAlign_changed(int)));
- connect(multicolumnCB, SIGNAL(clicked()), this, SLOT(multicolumn_clicked()));
- connect(newpageCB, SIGNAL(clicked()), this, SLOT(ltNewpage_clicked()));
- connect(headerStatusCB, SIGNAL(clicked()), this, SLOT(ltHeaderStatus_clicked()));
- connect(headerBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltHeaderBorderAbove_clicked()));
- connect(headerBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltHeaderBorderBelow_clicked()));
- connect(firstheaderStatusCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderStatus_clicked()));
- connect(firstheaderBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderBorderAbove_clicked()));
- connect(firstheaderBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderBorderBelow_clicked()));
- connect(firstheaderNoContentsCB, SIGNAL(clicked()), this, SLOT(ltFirstHeaderEmpty_clicked()));
- connect(footerStatusCB, SIGNAL(clicked()), this, SLOT(ltFooterStatus_clicked()));
- connect(footerBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltFooterBorderAbove_clicked()));
- connect(footerBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltFooterBorderBelow_clicked()));
- connect(lastfooterStatusCB, SIGNAL(clicked()), this, SLOT(ltLastFooterStatus_clicked()));
- connect(lastfooterBorderAboveCB, SIGNAL(clicked()), this, SLOT(ltLastFooterBorderAbove_clicked()));
- connect(lastfooterBorderBelowCB, SIGNAL(clicked()), this, SLOT(ltLastFooterBorderBelow_clicked()));
- connect(lastfooterNoContentsCB, SIGNAL(clicked()), this, SLOT(ltLastFooterEmpty_clicked()));
- connect(specialAlignmentED, SIGNAL(returnPressed()), this, SLOT(specialAlignment_changed()));
- connect(widthED, SIGNAL(returnPressed()), this, SLOT(width_changed()));
- connect(widthUnit, SIGNAL(selectionChanged(lyx::Length::UNIT)), this, SLOT(width_changed()));
- connect(closePB, SIGNAL(clicked()), this, SLOT(close_clicked()));
- connect(borders, SIGNAL(topSet(bool)), this, SLOT(topBorder_changed()));
- connect(borders, SIGNAL(bottomSet(bool)), this, SLOT(bottomBorder_changed()));
- connect(borders, SIGNAL(rightSet(bool)), this, SLOT(rightBorder_changed()));
- connect(borders, SIGNAL(leftSet(bool)), this, SLOT(leftBorder_changed()));
- connect(rotateTabularCB, SIGNAL(clicked()), this, SLOT(rotateTabular()));
- connect(rotateCellCB, SIGNAL(clicked()), this, SLOT(rotateCell()));
- connect(longTabularCB, SIGNAL(clicked()), this, SLOT(longTabular()));
-
- bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
- bc().setCancel(closePB);
-
- bc().addReadOnly(topspaceED);
- bc().addReadOnly(topspaceUnit);
- bc().addReadOnly(topspaceCO);
- bc().addReadOnly(bottomspaceED);
- bc().addReadOnly(bottomspaceUnit);
- bc().addReadOnly(bottomspaceCO);
- bc().addReadOnly(interlinespaceED);
- bc().addReadOnly(interlinespaceUnit);
- bc().addReadOnly(interlinespaceCO);
- bc().addReadOnly(borderDefaultRB);
- bc().addReadOnly(booktabsRB);
-
- bc().addReadOnly(multicolumnCB);
- bc().addReadOnly(rotateCellCB);
- bc().addReadOnly(rotateTabularCB);
- bc().addReadOnly(specialAlignmentED);
- bc().addReadOnly(widthED);
- bc().addReadOnly(widthUnit);
- bc().addReadOnly(hAlignCB);
- bc().addReadOnly(vAlignCB);
- bc().addReadOnly(borderSetPB);
- bc().addReadOnly(borderUnsetPB);
- bc().addReadOnly(borders);
- bc().addReadOnly(longTabularCB);
- bc().addReadOnly(headerStatusCB);
- bc().addReadOnly(headerBorderAboveCB);
- bc().addReadOnly(headerBorderBelowCB);
- bc().addReadOnly(firstheaderStatusCB);
- bc().addReadOnly(firstheaderBorderAboveCB);
- bc().addReadOnly(firstheaderBorderBelowCB);
- bc().addReadOnly(firstheaderNoContentsCB);
- bc().addReadOnly(footerStatusCB);
- bc().addReadOnly(footerBorderAboveCB);
- bc().addReadOnly(footerBorderBelowCB);
- bc().addReadOnly(lastfooterStatusCB);
- bc().addReadOnly(lastfooterBorderAboveCB);
- bc().addReadOnly(lastfooterBorderBelowCB);
- bc().addReadOnly(lastfooterNoContentsCB);
- bc().addReadOnly(newpageCB);
+ tabularWidthUnitLC->setCurrentItem(Length::defaultUnit());
+ columnWidthUnitLC->setCurrentItem(Length::defaultUnit());
+ multirowOffsetUnitLC->setCurrentItem(Length::defaultUnit());
+ topspaceUnitLC->setCurrentItem(Length::defaultUnit());
+ bottomspaceUnitLC->setCurrentItem(Length::defaultUnit());
+ interlinespaceUnitLC->setCurrentItem(Length::defaultUnit());
+
+ connect(topspaceED, SIGNAL(textEdited(const QString &)),
+ this, SLOT(checkEnabled()));
+ connect(topspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(checkEnabled()));
+ connect(bottomspaceED, SIGNAL(textEdited(const QString &)),
+ this, SLOT(checkEnabled()));
+ connect(bottomspaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(checkEnabled()));
+ connect(interlinespaceED, SIGNAL(textEdited(const QString &)),
+ this, SLOT(checkEnabled()));
+ connect(interlinespaceUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(checkEnabled()));
+ connect(booktabsRB, SIGNAL(clicked(bool)),
+ this, SLOT(checkEnabled()));
+ connect(borderDefaultRB, SIGNAL(clicked(bool)),
+ this, SLOT(checkEnabled()));
+ connect(borderSetPB, SIGNAL(clicked()),
+ this, SLOT(borderSet_clicked()));
+ connect(borderUnsetPB, SIGNAL(clicked()),
+ this, SLOT(borderUnset_clicked()));
+ connect(hAlignCO, SIGNAL(activated(int)),
+ this, SLOT(checkEnabled()));
+ connect(vAlignCO, SIGNAL(activated(int)),
+ this, SLOT(checkEnabled()));
+ connect(multicolumnCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(multirowCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(multirowOffsetED, SIGNAL(textEdited(const QString &)),
+ this, SLOT(checkEnabled()));
+ connect(multirowOffsetUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(checkEnabled()));
+ connect(newpageCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(headerStatusCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(headerBorderAboveCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(headerBorderBelowCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(firstheaderStatusCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(firstheaderBorderAboveCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(firstheaderBorderBelowCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(firstheaderNoContentsCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(footerStatusCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(footerBorderAboveCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(footerBorderBelowCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(lastfooterStatusCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(lastfooterBorderAboveCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(lastfooterBorderBelowCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(lastfooterNoContentsCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(captionStatusCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(specialAlignmentED, SIGNAL(textEdited(const QString &)),
+ this, SLOT(checkEnabled()));
+ connect(columnWidthED, SIGNAL(textEdited(const QString &)),
+ this, SLOT(checkEnabled()));
+ connect(columnWidthUnitLC, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(topSet(bool)),
+ this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(bottomSet(bool)),
+ this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(rightSet(bool)),
+ this, SLOT(checkEnabled()));
+ connect(borders, SIGNAL(leftSet(bool)),
+ this, SLOT(checkEnabled()));
+ connect(rotateTabularCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(rotateTabularAngleSB, SIGNAL(valueChanged(int)),
+ this, SLOT(checkEnabled()));
+ connect(rotateCellCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(rotateCellAngleSB, SIGNAL(valueChanged(int)),
+ this, SLOT(checkEnabled()));
+ connect(TableAlignCO, SIGNAL(activated(int)),
+ this, SLOT(checkEnabled()));
+ connect(longTabularCB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(leftRB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(centerRB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(rightRB, SIGNAL(clicked()),
+ this, SLOT(checkEnabled()));
+ connect(tabularWidthED, SIGNAL(textEdited(const QString &)),
+ this, SLOT(checkEnabled()));
+
+ decimalPointED->setInputMask("X; ");
+ decimalPointED->setMaxLength(1);
// initialize the length validator
- bc().addCheckedLineEdit(widthED, fixedWidthColLA);
- bc().addCheckedLineEdit(topspaceED, topspaceLA);
- bc().addCheckedLineEdit(bottomspaceED, bottomspaceLA);
- bc().addCheckedLineEdit(interlinespaceED, interlinespaceLA);
-}
-
-
-GuiTabular::~GuiTabular()
-{
+ addCheckedWidget(columnWidthED, columnWidthLA);
+ addCheckedWidget(multirowOffsetED, multirowOffsetLA);
+ addCheckedWidget(topspaceED, topspaceLA);
+ addCheckedWidget(bottomspaceED, bottomspaceLA);
+ addCheckedWidget(interlinespaceED, interlinespaceLA);
+ addCheckedWidget(tabularWidthED, tabularWidthLA);
}
-void GuiTabular::change_adaptor()
+void GuiTabular::on_topspaceCO_activated(int index)
{
- changed();
+ bool const enable = (index == 2);
+ topspaceED->setEnabled(enable);
+ topspaceUnitLC->setEnabled(enable);
}
-void GuiTabular::booktabsChanged(bool)
+void GuiTabular::on_bottomspaceCO_activated(int index)
{
- changed();
- booktabs(booktabsRB->isChecked());
- update_borders();
+ bool const enable = (index == 2);
+ bottomspaceED->setEnabled(enable);
+ bottomspaceUnitLC->setEnabled(enable);
}
-void GuiTabular::topspace_changed()
+void GuiTabular::on_interlinespaceCO_activated(int index)
{
- switch (topspaceCO->currentIndex()) {
- case 0: {
- set(Tabular::SET_TOP_SPACE, "");
- topspaceED->setEnabled(false);
- topspaceUnit->setEnabled(false);
- break;
- }
- case 1: {
- set(Tabular::SET_TOP_SPACE, "default");
- topspaceED->setEnabled(false);
- topspaceUnit->setEnabled(false);
- break;
- }
- case 2: {
- if (!topspaceED->text().isEmpty())
- set(Tabular::SET_TOP_SPACE,
- widgetsToLength(topspaceED, topspaceUnit));
- if (!bc().policy().isReadOnly()) {
- topspaceED->setEnabled(true);
- topspaceUnit->setEnabled(true);
- }
- break;
- }
- }
- changed();
+ bool const enable = (index == 2);
+ interlinespaceED->setEnabled(enable);
+ interlinespaceUnitLC->setEnabled(enable);
}
-void GuiTabular::bottomspace_changed()
+void GuiTabular::enableWidgets() const
{
- switch (bottomspaceCO->currentIndex()) {
- case 0: {
- set(Tabular::SET_BOTTOM_SPACE, "");
- bottomspaceED->setEnabled(false);
- bottomspaceUnit->setEnabled(false);
- break;
- }
- case 1: {
- set(Tabular::SET_BOTTOM_SPACE, "default");
- bottomspaceED->setEnabled(false);
- bottomspaceUnit->setEnabled(false);
- break;
- }
- case 2: {
- if (!bottomspaceED->text().isEmpty())
- set(Tabular::SET_BOTTOM_SPACE,
- widgetsToLength(bottomspaceED, bottomspaceUnit));
- if (!bc().policy().isReadOnly()) {
- bottomspaceED->setEnabled(true);
- bottomspaceUnit->setEnabled(true);
- }
- break;
- }
- }
- changed();
+ // if there is a LaTeX argument, the width and alignment will be overwritten
+ // therefore disable them in this case
+ columnWidthED->setEnabled(specialAlignmentED->text().isEmpty());
+ columnWidthUnitLC->setEnabled(specialAlignmentED->text().isEmpty());
+ // if the column has a width, multirows are always left-aligned
+ // therefore disable hAlignCB in this case
+ hAlignCO->setEnabled(!(multirowCB->isChecked()
+ && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty())
+ && specialAlignmentED->text().isEmpty());
+ // decimal alignment is only possible for non-multicol and non-multirow cells
+ if ((multicolumnCB->isChecked() || multirowCB->isChecked())
+ && hAlignCO->findData(toqstr("decimal")))
+ hAlignCO->removeItem(hAlignCO->findData(toqstr("decimal")));
+ else if (!multicolumnCB->isChecked() && !multirowCB->isChecked()
+ && hAlignCO->findData(toqstr("decimal")) == -1)
+ hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
+ bool const dalign =
+ hAlignCO->itemData(hAlignCO->currentIndex()).toString() == QString("decimal");
+ decimalPointED->setEnabled(dalign);
+ decimalLA->setEnabled(dalign);
+
+ bool const setwidth = TableAlignCO->currentText() == qt_("Middle")
+ && !longTabularCB->isChecked();
+ tabularWidthLA->setEnabled(setwidth);
+ tabularWidthED->setEnabled(setwidth);
+ tabularWidthUnitLC->setEnabled(setwidth);
+
+ rotateTabularAngleSB->setEnabled(rotateTabularCB->isChecked());
+ rotateCellAngleSB->setEnabled(rotateCellCB->isChecked());
+
+ bool const enable_valign =
+ !multirowCB->isChecked()
+ && !widgetsToLength(columnWidthED, columnWidthUnitLC).empty()
+ && specialAlignmentED->text().isEmpty();
+ vAlignCO->setEnabled(enable_valign);
+ vAlignLA->setEnabled(enable_valign);
+
+ topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
+ topspaceED->setEnabled(topspaceCO->currentIndex() == 2);
+ topspaceUnitLC->setEnabled(topspaceCO->currentIndex() == 2);
+ bottomspaceED->setEnabled(bottomspaceCO->currentIndex() == 2);
+ bottomspaceUnitLC->setEnabled(bottomspaceCO->currentIndex() == 2);
+ interlinespaceED->setEnabled(interlinespaceCO->currentIndex() == 2);
+ interlinespaceUnitLC->setEnabled(interlinespaceCO->currentIndex() == 2);
+
+ // setting as longtable is not allowed when table is inside a float
+ bool const is_tabular_star = !tabularWidthED->text().isEmpty();
+ longTabularCB->setEnabled(!is_tabular_star && funcEnabled(Tabular::SET_LONGTABULAR));
+ bool const longtabular = longTabularCB->isChecked();
+ longtableGB->setEnabled(true);
+ newpageCB->setEnabled(longtabular);
+ alignmentGB->setEnabled(longtabular);
+ // longtables and tabular* cannot have a vertical alignment
+ TableAlignLA->setDisabled(is_tabular_star || longtabular);
+ TableAlignCO->setDisabled(is_tabular_star || longtabular);
+
+ // FIXME: This Dialog is really horrible, disabling/enabling a checkbox
+ // depending on the cursor position is very very unintuitive...
+ // We need some edit boxes to show which rows are header/footer/etc
+ // without having to move the cursor first.
+ headerStatusCB->setEnabled(longtabular
+ && (headerStatusCB->isChecked() ?
+ funcEnabled(Tabular::UNSET_LTHEAD) :
+ funcEnabled(Tabular::SET_LTHEAD)));
+ headerBorderAboveCB->setEnabled(longtabular
+ && headerStatusCB->isChecked());
+ headerBorderBelowCB->setEnabled(longtabular
+ && headerStatusCB->isChecked());
+
+ // first header can only be suppressed when there is a header
+ // firstheader_suppressable_ is set in paramsToDialog
+ firstheaderNoContentsCB->setEnabled(longtabular && firstheader_suppressable_);
+ // check if setting a first header is allowed
+ // additionally check firstheaderNoContentsCB because when this is
+ // the case a first header makes no sense
+ firstheaderStatusCB->setEnabled((firstheaderStatusCB->isChecked() ?
+ funcEnabled(Tabular::UNSET_LTFIRSTHEAD) :
+ funcEnabled(Tabular::SET_LTFIRSTHEAD))
+ && longtabular && !firstheaderNoContentsCB->isChecked());
+ firstheaderBorderAboveCB->setEnabled(longtabular
+ && firstheaderStatusCB->isChecked());
+ firstheaderBorderBelowCB->setEnabled(longtabular
+ && firstheaderStatusCB->isChecked());
+
+ footerStatusCB->setEnabled(longtabular
+ && (footerStatusCB->isChecked() ?
+ funcEnabled(Tabular::UNSET_LTFOOT) :
+ funcEnabled(Tabular::SET_LTFOOT)));
+ footerBorderAboveCB->setEnabled(longtabular
+ && footerBorderAboveCB->isChecked());
+ footerBorderBelowCB->setEnabled(longtabular
+ && footerBorderAboveCB->isChecked());
+
+ // last footer can only be suppressed when there is a footer
+ // lastfooter_suppressable_ is set in paramsToDialog
+ lastfooterNoContentsCB->setEnabled(longtabular && lastfooter_suppressable_);
+ // check if setting a last footer is allowed
+ // additionally check lastfooterNoContentsCB because when this is
+ // the case a last footer makes no sense
+ lastfooterStatusCB->setEnabled((lastfooterStatusCB->isChecked() ?
+ funcEnabled(Tabular::UNSET_LTLASTFOOT) :
+ funcEnabled(Tabular::SET_LTLASTFOOT))
+ && longtabular && !lastfooterNoContentsCB->isChecked());
+ lastfooterBorderAboveCB->setEnabled(longtabular
+ && lastfooterBorderAboveCB->isChecked());
+ lastfooterBorderBelowCB->setEnabled(longtabular
+ && lastfooterBorderAboveCB->isChecked());
+
+ captionStatusCB->setEnabled(funcEnabled(Tabular::TOGGLE_LTCAPTION)
+ && longtabular);
+
+ multicolumnCB->setEnabled(funcEnabled(Tabular::MULTICOLUMN)
+ && !dalign && !multirowCB->isChecked());
+ multirowCB->setEnabled(funcEnabled(Tabular::MULTIROW)
+ && !dalign && !multicolumnCB->isChecked());
+ bool const enable_mr = multirowCB->isChecked();
+ multirowOffsetLA->setEnabled(enable_mr);
+ multirowOffsetED->setEnabled(enable_mr);
+ multirowOffsetUnitLC->setEnabled(enable_mr);
+
+ // Vertical lines cannot be set in formal tables
+ borders->setLeftEnabled(!booktabsRB->isChecked());
+ borders->setRightEnabled(!booktabsRB->isChecked());
}
-void GuiTabular::interlinespace_changed()
+void GuiTabular::checkEnabled()
{
- switch (interlinespaceCO->currentIndex()) {
- case 0: {
- set(Tabular::SET_INTERLINE_SPACE, "");
- interlinespaceED->setEnabled(false);
- interlinespaceUnit->setEnabled(false);
- break;
- }
- case 1: {
- set(Tabular::SET_INTERLINE_SPACE, "default");
- interlinespaceED->setEnabled(false);
- interlinespaceUnit->setEnabled(false);
- break;
- }
- case 2: {
- if (!interlinespaceED->text().isEmpty())
- set(Tabular::SET_INTERLINE_SPACE,
- widgetsToLength(interlinespaceED, interlinespaceUnit));
- if (!bc().policy().isReadOnly()) {
- interlinespaceED->setEnabled(true);
- interlinespaceUnit->setEnabled(true);
- }
- break;
- }
- }
+ enableWidgets();
changed();
}
-void GuiTabular::close_clicked()
-{
- closeGUI();
- slotClose();
-}
-
-
void GuiTabular::borderSet_clicked()
{
- set(Tabular::SET_ALL_LINES);
- update_borders();
- changed();
+ borders->setTop(true);
+ borders->setBottom(true);
+ borders->setLeft(true);
+ borders->setRight(true);
+ // repaint the setborder widget
+ borders->update();
+ checkEnabled();
}
void GuiTabular::borderUnset_clicked()
{
- set(Tabular::UNSET_ALL_LINES);
- update_borders();
- changed();
-}
-
-
-void GuiTabular::leftBorder_changed()
-{
- set(Tabular::TOGGLE_LINE_LEFT);
- changed();
-}
-
-
-void GuiTabular::rightBorder_changed()
-{
- set(Tabular::TOGGLE_LINE_RIGHT);
- changed();
-}
-
-
-void GuiTabular::topBorder_changed()
-{
- set(Tabular::TOGGLE_LINE_TOP);
- changed();
+ borders->setTop(false);
+ borders->setBottom(false);
+ borders->setLeft(false);
+ borders->setRight(false);
+ // repaint the setborder widget
+ borders->update();
+ checkEnabled();
}
-void GuiTabular::bottomBorder_changed()
+static void setParam(string & param_str, Tabular::Feature f, string const & arg = string())
{
- set(Tabular::TOGGLE_LINE_BOTTOM);
- changed();
+ param_str += ' ';
+ param_str += featureAsString(f) + ' ' + arg;
}
-void GuiTabular::specialAlignment_changed()
+void GuiTabular::setHAlign(string & param_str) const
{
- string special = fromqstr(specialAlignmentED->text());
- setSpecial(special);
- changed();
-}
-
+ Tabular::Feature num = Tabular::ALIGN_LEFT;
+ Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
+ string const align =
+ fromqstr(hAlignCO->itemData(hAlignCO->currentIndex()).toString());
+ if (align == "left") {
+ num = Tabular::ALIGN_LEFT;
+ multi_num = Tabular::M_ALIGN_LEFT;
+ } else if (align == "center") {
+ num = Tabular::ALIGN_CENTER;
+ multi_num = Tabular::M_ALIGN_CENTER;
+ } else if (align == "right") {
+ num = Tabular::ALIGN_RIGHT;
+ multi_num = Tabular::M_ALIGN_RIGHT;
+ } else if (align == "justified") {
+ num = Tabular::ALIGN_BLOCK;
+ //multi_num: no equivalent
+ } else if (align == "decimal") {
+ num = Tabular::ALIGN_DECIMAL;
+ //multi_num: no equivalent
+ }
-void GuiTabular::width_changed()
-{
- changed();
- string const width = widgetsToLength(widthED, widthUnit);
- setWidth(width);
+ if (multicolumnCB->isChecked())
+ setParam(param_str, multi_num);
+ else
+ setParam(param_str, num);
}
-void GuiTabular::multicolumn_clicked()
+void GuiTabular::setVAlign(string & param_str) const
{
- toggleMultiColumn();
- changed();
-}
-
+ int const align = vAlignCO->currentIndex();
+ enum VALIGN { TOP, MIDDLE, BOTTOM };
+ VALIGN v = TOP;
-void GuiTabular::rotateTabular()
-{
- rotateTabular(rotateTabularCB->isChecked());
- changed();
-}
+ switch (align) {
+ case 0: v = TOP; break;
+ case 1: v = MIDDLE; break;
+ case 2: v = BOTTOM; break;
+ }
+ Tabular::Feature num = Tabular::VALIGN_MIDDLE;
+ Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
-void GuiTabular::rotateCell()
-{
- rotateCell(rotateCellCB->isChecked());
- changed();
+ switch (v) {
+ case TOP:
+ num = Tabular::VALIGN_TOP;
+ multi_num = Tabular::M_VALIGN_TOP;
+ break;
+ case MIDDLE:
+ num = Tabular::VALIGN_MIDDLE;
+ multi_num = Tabular::M_VALIGN_MIDDLE;
+ break;
+ case BOTTOM:
+ num = Tabular::VALIGN_BOTTOM;
+ multi_num = Tabular::M_VALIGN_BOTTOM;
+ break;
+ }
+ if (multicolumnCB->isChecked() || multirowCB->isChecked())
+ setParam(param_str, multi_num);
+ else
+ setParam(param_str, num);
}
-void GuiTabular::hAlign_changed(int align)
+void GuiTabular::setTableAlignment(string & param_str) const
{
- GuiTabular::HALIGN h = GuiTabular::LEFT;
-
+ int const align = TableAlignCO->currentIndex();
switch (align) {
- case 0: h = GuiTabular::LEFT; break;
- case 1: h = GuiTabular::CENTER; break;
- case 2: h = GuiTabular::RIGHT; break;
- case 3: h = GuiTabular::BLOCK; break;
+ case 0: setParam(param_str, Tabular::TABULAR_VALIGN_TOP);
+ break;
+ case 1: setParam(param_str, Tabular::TABULAR_VALIGN_MIDDLE);
+ break;
+ case 2: setParam(param_str, Tabular::TABULAR_VALIGN_BOTTOM);
+ break;
}
-
- halign(h);
}
-void GuiTabular::vAlign_changed(int align)
+docstring GuiTabular::dialogToParams() const
{
- GuiTabular::VALIGN v = GuiTabular::TOP;
-
- switch (align) {
- case 0: v = GuiTabular::TOP; break;
- case 1: v = GuiTabular::MIDDLE; break;
- case 2: v = GuiTabular::BOTTOM; break;
- }
+ string param_str = "tabular";
- valign(v);
-}
+ // table width
+ string tabwidth = widgetsToLength(tabularWidthED, tabularWidthUnitLC);
+ if (tabwidth.empty())
+ tabwidth = "0pt";
+ setParam(param_str, Tabular::SET_TABULAR_WIDTH, tabwidth);
+ // apply the fixed width values
+ // this must be done before applying the column alignment
+ // because its value influences the alignment of multirow cells
+ string width = widgetsToLength(columnWidthED, columnWidthUnitLC);
+ if (width.empty())
+ width = "0pt";
+ if (multicolumnCB->isChecked())
+ setParam(param_str, Tabular::SET_MPWIDTH, width);
+ else
+ setParam(param_str, Tabular::SET_PWIDTH, width);
+
+ // apply the column alignment
+ // multirows inherit the alignment from the column; if a column width
+ // is set, multirows are always left-aligned so that in this case
+ // its alignment must not be applied (see bug #8084)
+ if (!(multirowCB->isChecked() && width != "0pt"))
+ setHAlign(param_str);
+
+ // SET_DECIMAL_POINT must come after setHAlign() (ALIGN_DECIMAL)
+ string decimal_point = fromqstr(decimalPointED->text());
+ if (decimal_point.empty())
+ decimal_point = lyxrc.default_decimal_point;
+ setParam(param_str, Tabular::SET_DECIMAL_POINT, decimal_point);
+
+ setVAlign(param_str);
+ setTableAlignment(param_str);
+ //
+ if (booktabsRB->isChecked())
+ setParam(param_str, Tabular::SET_BOOKTABS);
+ else
+ setParam(param_str, Tabular::UNSET_BOOKTABS);
-void GuiTabular::longTabular()
-{
- longTabular(longTabularCB->isChecked());
- changed();
-}
+ //
+ switch (topspaceCO->currentIndex()) {
+ case 0:
+ setParam(param_str, Tabular::SET_TOP_SPACE, "none");
+ break;
+ case 1:
+ setParam(param_str, Tabular::SET_TOP_SPACE, "default");
+ break;
+ case 2:
+ if (!topspaceED->text().isEmpty())
+ setParam(param_str, Tabular::SET_TOP_SPACE,
+ widgetsToLength(topspaceED, topspaceUnitLC));
+ break;
+ }
+ //
+ switch (bottomspaceCO->currentIndex()) {
+ case 0:
+ setParam(param_str, Tabular::SET_BOTTOM_SPACE, "none");
+ break;
+ case 1:
+ setParam(param_str, Tabular::SET_BOTTOM_SPACE, "default");
+ break;
+ case 2:
+ if (!bottomspaceED->text().isEmpty())
+ setParam(param_str, Tabular::SET_BOTTOM_SPACE,
+ widgetsToLength(bottomspaceED,
+ bottomspaceUnitLC));
+ break;
+ }
-void GuiTabular::ltNewpage_clicked()
-{
- set(Tabular::SET_LTNEWPAGE);
- changed();
-}
+ //
+ switch (interlinespaceCO->currentIndex()) {
+ case 0:
+ setParam(param_str, Tabular::SET_INTERLINE_SPACE, "none");
+ break;
+ case 1:
+ setParam(param_str, Tabular::SET_INTERLINE_SPACE, "default");
+ break;
+ case 2:
+ if (!interlinespaceED->text().isEmpty())
+ setParam(param_str, Tabular::SET_INTERLINE_SPACE,
+ widgetsToLength(interlinespaceED,
+ interlinespaceUnitLC));
+ break;
+ }
+ //
+ if (borders->getTop() && borders->getBottom() && borders->getLeft()
+ && borders->getRight())
+ setParam(param_str, Tabular::SET_ALL_LINES);
+ else if (!borders->getTop() && !borders->getBottom() && !borders->getLeft()
+ && !borders->getRight())
+ setParam(param_str, Tabular::UNSET_ALL_LINES);
+ else {
+ setParam(param_str, Tabular::SET_LINE_LEFT,
+ borders->getLeft() ? "true" : "false");
+ setParam(param_str, Tabular::SET_LINE_RIGHT,
+ borders->getRight() ? "true" : "false");
+ setParam(param_str, Tabular::SET_LINE_TOP,
+ borders->getTop() ? "true" : "false");
+ setParam(param_str, Tabular::SET_LINE_BOTTOM,
+ borders->getBottom() ? "true" : "false");
+ }
-void GuiTabular::ltHeaderStatus_clicked()
-{
- bool enable = headerStatusCB->isChecked();
- if (enable)
- set(Tabular::SET_LTHEAD, "");
+ // apply the special alignment
+ string special = fromqstr(specialAlignmentED->text());
+ if (special.empty())
+ special = "none";
+ if (multicolumnCB->isChecked())
+ setParam(param_str, Tabular::SET_SPECIAL_MULTICOLUMN, special);
else
- set(Tabular::UNSET_LTHEAD, "");
- headerBorderAboveCB->setEnabled(enable);
- headerBorderBelowCB->setEnabled(enable);
- firstheaderNoContentsCB->setEnabled(enable);
- changed();
-}
+ setParam(param_str, Tabular::SET_SPECIAL_COLUMN, special);
-
-void GuiTabular::ltHeaderBorderAbove_clicked()
-{
+ //
+ if (multicolumnCB->isChecked())
+ setParam(param_str, Tabular::SET_MULTICOLUMN);
+ else
+ setParam(param_str, Tabular::UNSET_MULTICOLUMN);
+
+ // apply the multirow offset
+ string mroffset = widgetsToLength(multirowOffsetED, multirowOffsetUnitLC);
+ if (mroffset.empty())
+ mroffset = "0pt";
+ if (multirowCB->isChecked())
+ setParam(param_str, Tabular::SET_MROFFSET, mroffset);
+ //
+ if (multirowCB->isChecked())
+ setParam(param_str, Tabular::SET_MULTIROW);
+ else
+ setParam(param_str, Tabular::UNSET_MULTIROW);
+ // store the table rotation angle
+ string const tabular_angle = convert<string>(rotateTabularAngleSB->value());
+ if (rotateTabularCB->isChecked())
+ setParam(param_str, Tabular::SET_ROTATE_TABULAR, tabular_angle);
+ else
+ setParam(param_str, Tabular::UNSET_ROTATE_TABULAR, tabular_angle);
+ // store the cell rotation angle
+ string const cell_angle = convert<string>(rotateCellAngleSB->value());
+ if (rotateCellCB->isChecked())
+ setParam(param_str, Tabular::SET_ROTATE_CELL, cell_angle);
+ else
+ setParam(param_str, Tabular::UNSET_ROTATE_CELL, cell_angle);
+ //
+ if (longTabularCB->isChecked())
+ setParam(param_str, Tabular::SET_LONGTABULAR);
+ else
+ setParam(param_str, Tabular::UNSET_LONGTABULAR);
+ //
+ if (newpageCB->isChecked())
+ setParam(param_str, Tabular::SET_LTNEWPAGE);
+ else
+ setParam(param_str, Tabular::UNSET_LTNEWPAGE);
+ //
+ if (captionStatusCB->isChecked())
+ setParam(param_str, Tabular::SET_LTCAPTION);
+ else
+ setParam(param_str, Tabular::UNSET_LTCAPTION);
+ //
+ if (headerStatusCB->isChecked())
+ setParam(param_str, Tabular::SET_LTHEAD, "none");
+ else
+ setParam(param_str, Tabular::UNSET_LTHEAD, "none");
+ //
if (headerBorderAboveCB->isChecked())
- set(Tabular::SET_LTHEAD, "dl_above");
+ setParam(param_str, Tabular::SET_LTHEAD, "dl_above");
else
- set(Tabular::UNSET_LTHEAD, "dl_above");
- changed();
-}
-
-
-void GuiTabular::ltHeaderBorderBelow_clicked()
-{
+ setParam(param_str, Tabular::UNSET_LTHEAD, "dl_above");
+ //
if (headerBorderBelowCB->isChecked())
- set(Tabular::SET_LTHEAD, "dl_below");
+ setParam(param_str, Tabular::SET_LTHEAD, "dl_below");
else
- set(Tabular::UNSET_LTHEAD, "dl_below");
- changed();
-}
-
-
-void GuiTabular::ltFirstHeaderBorderAbove_clicked()
-{
+ setParam(param_str, Tabular::UNSET_LTHEAD, "dl_below");
if (firstheaderBorderAboveCB->isChecked())
- set(Tabular::SET_LTFIRSTHEAD, "dl_above");
+ setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_above");
else
- set(Tabular::UNSET_LTFIRSTHEAD, "dl_above");
- changed();
-}
-
-
-void GuiTabular::ltFirstHeaderBorderBelow_clicked()
-{
+ setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_above");
if (firstheaderBorderBelowCB->isChecked())
- set(Tabular::SET_LTFIRSTHEAD, "dl_below");
+ setParam(param_str, Tabular::SET_LTFIRSTHEAD, "dl_below");
else
- set(Tabular::UNSET_LTFIRSTHEAD, "dl_below");
- changed();
-}
-
-
-void GuiTabular::ltFirstHeaderStatus_clicked()
-{
- bool enable = firstheaderStatusCB->isChecked();
- if (enable)
- set(Tabular::SET_LTFIRSTHEAD, "");
+ setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "dl_below");
+ if (firstheaderStatusCB->isChecked())
+ setParam(param_str, Tabular::SET_LTFIRSTHEAD, "none");
else
- set(Tabular::UNSET_LTFIRSTHEAD, "");
- firstheaderBorderAboveCB->setEnabled(enable);
- firstheaderBorderBelowCB->setEnabled(enable);
- changed();
-}
-
-
-void GuiTabular::ltFirstHeaderEmpty_clicked()
-{
- bool enable = firstheaderNoContentsCB->isChecked();
- if (enable)
- set(Tabular::SET_LTFIRSTHEAD, "empty");
+ setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "none");
+ if (firstheaderNoContentsCB->isChecked())
+ setParam(param_str, Tabular::SET_LTFIRSTHEAD, "empty");
else
- set(Tabular::UNSET_LTFIRSTHEAD, "empty");
- firstheaderStatusCB->setEnabled(!enable);
- firstheaderBorderAboveCB->setEnabled(!enable);
- firstheaderBorderBelowCB->setEnabled(!enable);
- changed();
-}
-
-
-void GuiTabular::ltFooterStatus_clicked()
-{
- bool enable = footerStatusCB->isChecked();
- if (enable)
- set(Tabular::SET_LTFOOT, "");
+ setParam(param_str, Tabular::UNSET_LTFIRSTHEAD, "empty");
+ if (footerStatusCB->isChecked())
+ setParam(param_str, Tabular::SET_LTFOOT, "none");
else
- set(Tabular::UNSET_LTFOOT, "");
- footerBorderAboveCB->setEnabled(enable);
- footerBorderBelowCB->setEnabled(enable);
- lastfooterNoContentsCB->setEnabled(enable);
- changed();
-}
-
-
-void GuiTabular::ltFooterBorderAbove_clicked()
-{
+ setParam(param_str, Tabular::UNSET_LTFOOT, "none");
if (footerBorderAboveCB->isChecked())
- set(Tabular::SET_LTFOOT, "dl_above");
+ setParam(param_str, Tabular::SET_LTFOOT, "dl_above");
else
- set(Tabular::UNSET_LTFOOT, "dl_above");
- changed();
-}
-
-
-void GuiTabular::ltFooterBorderBelow_clicked()
-{
+ setParam(param_str, Tabular::UNSET_LTFOOT, "dl_above");
if (footerBorderBelowCB->isChecked())
- set(Tabular::SET_LTFOOT, "dl_below");
+ setParam(param_str, Tabular::SET_LTFOOT, "dl_below");
else
- set(Tabular::UNSET_LTFOOT, "dl_below");
- changed();
-}
-
-
-void GuiTabular::ltLastFooterStatus_clicked()
-{
- bool enable = lastfooterStatusCB->isChecked();
- if (enable)
- set(Tabular::SET_LTLASTFOOT, "");
+ setParam(param_str, Tabular::UNSET_LTFOOT, "dl_below");
+ if (lastfooterStatusCB->isChecked())
+ setParam(param_str, Tabular::SET_LTLASTFOOT, "none");
else
- set(Tabular::UNSET_LTLASTFOOT, "");
- lastfooterBorderAboveCB->setEnabled(enable);
- lastfooterBorderBelowCB->setEnabled(enable);
- changed();
-}
-
-
-void GuiTabular::ltLastFooterBorderAbove_clicked()
-{
+ setParam(param_str, Tabular::UNSET_LTLASTFOOT, "none");
if (lastfooterBorderAboveCB->isChecked())
- set(Tabular::SET_LTLASTFOOT, "dl_above");
+ setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_above");
else
- set(Tabular::UNSET_LTLASTFOOT, "dl_above");
- changed();
-}
-
-
-void GuiTabular::ltLastFooterBorderBelow_clicked()
-{
+ setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_above");
if (lastfooterBorderBelowCB->isChecked())
- set(Tabular::SET_LTLASTFOOT, "dl_below");
+ setParam(param_str, Tabular::SET_LTLASTFOOT, "dl_below");
else
- set(Tabular::UNSET_LTLASTFOOT, "dl_below");
- changed();
-}
+ setParam(param_str, Tabular::UNSET_LTLASTFOOT, "dl_below");
+ if (lastfooterNoContentsCB->isChecked())
+ setParam(param_str, Tabular::SET_LTLASTFOOT, "empty");
+ else
+ setParam(param_str, Tabular::UNSET_LTLASTFOOT, "empty");
+ if (leftRB->isChecked())
+ setParam(param_str, Tabular::LONGTABULAR_ALIGN_LEFT);
+ else if (centerRB->isChecked())
+ setParam(param_str, Tabular::LONGTABULAR_ALIGN_CENTER);
+ else if (rightRB->isChecked())
+ setParam(param_str, Tabular::LONGTABULAR_ALIGN_RIGHT);
-void GuiTabular::ltLastFooterEmpty_clicked()
-{
- bool enable = lastfooterNoContentsCB->isChecked();
- if (enable)
- set(Tabular::SET_LTLASTFOOT, "empty");
- else
- set(Tabular::UNSET_LTLASTFOOT, "empty");
- lastfooterStatusCB->setEnabled(!enable);
- lastfooterBorderAboveCB->setEnabled(!enable);
- lastfooterBorderBelowCB->setEnabled(!enable);
- changed();
+ return from_utf8(param_str);
}
-void GuiTabular::update_borders()
+static Length getColumnPWidth(Tabular const & t, size_t cell)
{
- Tabular::idx_type const cell = getActiveCell();
- borders->setTop(tabular_.topLine(cell));
- borders->setBottom(tabular_.bottomLine(cell));
- borders->setLeft(tabular_.leftLine(cell));
- borders->setRight(tabular_.rightLine(cell));
- // repaint the setborder widget
- borders->update();
+ return t.column_info[t.cellColumn(cell)].p_width;
}
-namespace {
-
-Length getColumnPWidth(Tabular const & t, size_t cell)
+static Length getMColumnPWidth(Tabular const & t, size_t cell)
{
- return t.column_info[t.cellColumn(cell)].p_width;
+ if (t.isMultiColumn(cell) || t.isMultiRow(cell))
+ return t.cellInfo(cell).p_width;
+ return Length();
}
-Length getMColumnPWidth(Tabular const & t, size_t cell)
+static Length getMROffset(Tabular const & t, size_t cell)
{
- if (t.isMultiColumn(cell))
- return t.cellInfo(cell).p_width;
+ if (t.isMultiRow(cell))
+ return t.cellInfo(cell).mroffset;
return Length();
}
-docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
+static docstring getAlignSpecial(Tabular const & t, size_t cell, int what)
{
- if (what == Tabular::SET_SPECIAL_MULTI)
+ if (what == Tabular::SET_SPECIAL_MULTICOLUMN)
return t.cellInfo(cell).align_special;
return t.column_info[t.cellColumn(cell)].align_special;
}
-}
-
-
-void GuiTabular::updateContents()
+void GuiTabular::paramsToDialog(Inset const * inset)
{
- initialiseParams(string());
+ InsetTabular const * itab = static_cast<InsetTabular const *>(inset);
+ // Copy Tabular of current inset.
+ Tabular const & tabular = itab->tabular;
- size_t const cell = getActiveCell();
+ BufferView const * bv = guiApp->currentView()->currentBufferView();
+ size_t const cell = bv->cursor().idx();
- Tabular::row_type const row = tabular_.cellRow(cell);
- Tabular::col_type const col = tabular_.cellColumn(cell);
+ Tabular::row_type const row = tabular.cellRow(cell);
+ Tabular::col_type const col = tabular.cellColumn(cell);
tabularRowED->setText(QString::number(row + 1));
tabularColumnED->setText(QString::number(col + 1));
- bool const multicol(tabular_.isMultiColumn(cell));
-
+ bool const multicol = tabular.isMultiColumn(cell);
multicolumnCB->setChecked(multicol);
- rotateCellCB->setChecked(tabular_.getRotateCell(cell));
- rotateTabularCB->setChecked(tabular_.rotate);
+ bool const multirow = tabular.isMultiRow(cell);
+ multirowCB->setChecked(multirow);
+
+ rotateCellCB->setChecked(tabular.getRotateCell(cell) != 0);
+ if (rotateCellCB->isChecked()) {
+ if (tabular.getRotateCell(cell) != 0)
+ rotateCellAngleSB->setValue(tabular.getRotateCell(cell));
+ else
+ rotateCellAngleSB->setValue(90);
+ }
+
+ rotateTabularCB->setChecked(tabular.rotate != 0);
+ if (rotateTabularCB->isChecked())
+ rotateTabularAngleSB->setValue(tabular.rotate != 0 ? tabular.rotate : 90);
+
+ longTabularCB->setChecked(tabular.is_long_tabular);
- longTabularCB->setChecked(tabular_.is_long_tabular);
+ borders->setTop(tabular.topLine(cell));
+ borders->setBottom(tabular.bottomLine(cell));
+ borders->setLeft(tabular.leftLine(cell));
+ borders->setRight(tabular.rightLine(cell));
+ // repaint the setborder widget
+ borders->update();
- update_borders();
+ Length::UNIT const default_unit = Length::defaultUnit();
+
+ ///////////////////////////////////
+ // Set width and alignment
+
+ Length const tabwidth = tabular.tabularWidth();
+ if (tabwidth.zero()
+ && !(tabularWidthED->hasFocus() && tabularWidthED->text() == "0"))
+ tabularWidthED->clear();
+ else
+ lengthToWidgets(tabularWidthED, tabularWidthUnitLC,
+ tabwidth.asString(), default_unit);
Length pwidth;
docstring special;
-
if (multicol) {
- special = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_MULTI);
- pwidth = getMColumnPWidth(tabular_, cell);
+ special = getAlignSpecial(tabular, cell,
+ Tabular::SET_SPECIAL_MULTICOLUMN);
+ pwidth = getMColumnPWidth(tabular, cell);
} else {
- special = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_COLUMN);
- pwidth = getColumnPWidth(tabular_, cell);
+ special = getAlignSpecial(tabular, cell,
+ Tabular::SET_SPECIAL_COLUMN);
+ pwidth = getColumnPWidth(tabular, cell);
+ }
+ string colwidth;
+ if (pwidth.zero()
+ && !(columnWidthED->hasFocus() && columnWidthED->text() == "0"))
+ columnWidthED->clear();
+ else {
+ colwidth = pwidth.asString();
+ lengthToWidgets(columnWidthED, columnWidthUnitLC,
+ colwidth, default_unit);
+ }
+ Length mroffset;
+ if (multirow)
+ mroffset = getMROffset(tabular, cell);
+ string offset;
+ if (mroffset.zero()
+ && !(multirowOffsetED->hasFocus() && multirowOffsetED->text() == "0"))
+ multirowOffsetED->clear();
+ else {
+ offset = mroffset.asString();
+ lengthToWidgets(multirowOffsetED, multirowOffsetUnitLC,
+ offset, default_unit);
}
-
specialAlignmentED->setText(toqstr(special));
+ ///////////////////////////////////
- bool const isReadonly = bc().policy().isReadOnly();
- specialAlignmentED->setEnabled(!isReadonly);
-
- Length::UNIT default_unit =
- useMetricUnits() ? Length::CM : Length::IN;
- borderDefaultRB->setChecked(!tabular_.use_booktabs);
- booktabsRB->setChecked(tabular_.use_booktabs);
+ borderDefaultRB->setChecked(!tabular.use_booktabs);
+ booktabsRB->setChecked(tabular.use_booktabs);
- if (tabular_.row_info[row].top_space.empty()
- && !tabular_.row_info[row].top_space_default) {
+ if (tabular.row_info[row].top_space.empty()
+ && !tabular.row_info[row].top_space_default) {
topspaceCO->setCurrentIndex(0);
- } else if (tabular_.row_info[row].top_space_default) {
+ } else if (tabular.row_info[row].top_space_default) {
topspaceCO->setCurrentIndex(1);
} else {
topspaceCO->setCurrentIndex(2);
lengthToWidgets(topspaceED,
- topspaceUnit,
- tabular_.row_info[row].top_space.asString(),
+ topspaceUnitLC,
+ tabular.row_info[row].top_space.asString(),
default_unit);
}
- topspaceED->setEnabled(!isReadonly
- && (topspaceCO->currentIndex() == 2));
- topspaceUnit->setEnabled(!isReadonly
- && (topspaceCO->currentIndex() == 2));
- topspaceCO->setEnabled(!isReadonly);
-
- if (tabular_.row_info[row].bottom_space.empty()
- && !tabular_.row_info[row].bottom_space_default) {
+
+ if (tabular.row_info[row].bottom_space.empty()
+ && !tabular.row_info[row].bottom_space_default) {
bottomspaceCO->setCurrentIndex(0);
- } else if (tabular_.row_info[row].bottom_space_default) {
+ } else if (tabular.row_info[row].bottom_space_default) {
bottomspaceCO->setCurrentIndex(1);
} else {
bottomspaceCO->setCurrentIndex(2);
lengthToWidgets(bottomspaceED,
- bottomspaceUnit,
- tabular_.row_info[row].bottom_space.asString(),
+ bottomspaceUnitLC,
+ tabular.row_info[row].bottom_space.asString(),
default_unit);
}
- bottomspaceED->setEnabled(!isReadonly
- && (bottomspaceCO->currentIndex() == 2));
- bottomspaceUnit->setEnabled(!isReadonly
- && (bottomspaceCO->currentIndex() == 2));
- bottomspaceCO->setEnabled(!isReadonly);
-
- if (tabular_.row_info[row].interline_space.empty()
- && !tabular_.row_info[row].interline_space_default) {
+
+ if (tabular.row_info[row].interline_space.empty()
+ && !tabular.row_info[row].interline_space_default) {
interlinespaceCO->setCurrentIndex(0);
- } else if (tabular_.row_info[row].interline_space_default) {
+ } else if (tabular.row_info[row].interline_space_default) {
interlinespaceCO->setCurrentIndex(1);
} else {
interlinespaceCO->setCurrentIndex(2);
lengthToWidgets(interlinespaceED,
- interlinespaceUnit,
- tabular_.row_info[row].interline_space.asString(),
+ interlinespaceUnitLC,
+ tabular.row_info[row].interline_space.asString(),
default_unit);
}
- interlinespaceED->setEnabled(!isReadonly
- && (interlinespaceCO->currentIndex() == 2));
- interlinespaceUnit->setEnabled(!isReadonly
- && (interlinespaceCO->currentIndex() == 2));
- interlinespaceCO->setEnabled(!isReadonly);
- string colwidth;
- if (!pwidth.zero())
- colwidth = pwidth.asString();
- lengthToWidgets(widthED, widthUnit,
- colwidth, default_unit);
-
- widthED->setEnabled(!isReadonly);
- widthUnit->setEnabled(!isReadonly);
-
- hAlignCB->clear();
- hAlignCB->addItem(qt_("Left"));
- hAlignCB->addItem(qt_("Center"));
- hAlignCB->addItem(qt_("Right"));
+ hAlignCO->clear();
+ hAlignCO->addItem(qt_("Left"), toqstr("left"));
+ hAlignCO->addItem(qt_("Center"), toqstr("center"));
+ hAlignCO->addItem(qt_("Right"), toqstr("right"));
if (!multicol && !pwidth.zero())
- hAlignCB->addItem(qt_("Justified"));
-
- int align = 0;
- switch (tabular_.getAlignment(cell)) {
- case LYX_ALIGN_LEFT:
- align = 0;
- break;
- case LYX_ALIGN_CENTER:
- align = 1;
- break;
- case LYX_ALIGN_RIGHT:
- align = 2;
- break;
- case LYX_ALIGN_BLOCK:
- {
- if (!multicol && !pwidth.zero())
- align = 3;
- break;
- }
- default:
- align = 0;
- break;
+ hAlignCO->addItem(qt_("Justified"), toqstr("justified"));
+ if (!multicol && !multirow)
+ hAlignCO->addItem(qt_("At Decimal Separator"), toqstr("decimal"));
+
+ string align;
+ switch (tabular.getAlignment(cell)) {
+ case LYX_ALIGN_LEFT:
+ align = "left";
+ break;
+ case LYX_ALIGN_CENTER:
+ align = "center";
+ break;
+ case LYX_ALIGN_RIGHT:
+ align = "right";
+ break;
+ case LYX_ALIGN_BLOCK:
+ {
+ if (!multicol && !pwidth.zero())
+ align = "justified";
+ break;
+ }
+ case LYX_ALIGN_DECIMAL:
+ {
+ if (!multicol && !multirow)
+ align = "decimal";
+ break;
+ }
+ default:
+ // we should never end up here
+ break;
}
- hAlignCB->setCurrentIndex(align);
+ hAlignCO->setCurrentIndex(hAlignCO->findData(toqstr(align)));
+
+ //
+ QString decimal_point = toqstr(tabular.column_info[col].decimal_point);
+ if (decimal_point.isEmpty())
+ decimal_point = toqstr(from_utf8(lyxrc.default_decimal_point));
+ decimalPointED->setText(decimal_point);
int valign = 0;
- switch (tabular_.getVAlignment(cell)) {
+ switch (tabular.getVAlignment(cell)) {
case Tabular::LYX_VALIGN_TOP:
valign = 0;
break;
valign = 2;
break;
default:
- valign = 1;
+ valign = 0;
break;
}
if (pwidth.zero())
- valign = 1;
- vAlignCB->setCurrentIndex(valign);
+ valign = 0;
+ vAlignCO->setCurrentIndex(valign);
- hAlignCB->setEnabled(true);
- vAlignCB->setEnabled(!pwidth.zero());
+ int tableValign = 1;
+ switch (tabular.tabular_valignment) {
+ case Tabular::LYX_VALIGN_TOP:
+ tableValign = 0;
+ break;
+ case Tabular::LYX_VALIGN_MIDDLE:
+ tableValign = 1;
+ break;
+ case Tabular::LYX_VALIGN_BOTTOM:
+ tableValign = 2;
+ break;
+ default:
+ tableValign = 0;
+ break;
+ }
+ TableAlignCO->setCurrentIndex(tableValign);
- if (!tabular_.is_long_tabular) {
+ if (!tabular.is_long_tabular) {
headerStatusCB->setChecked(false);
headerBorderAboveCB->setChecked(false);
headerBorderBelowCB->setChecked(false);
lastfooterBorderBelowCB->setChecked(false);
lastfooterNoContentsCB->setChecked(false);
newpageCB->setChecked(false);
- newpageCB->setEnabled(false);
+ captionStatusCB->blockSignals(true);
+ captionStatusCB->setChecked(false);
+ captionStatusCB->blockSignals(false);
+ checkEnabled();
return;
+ } else {
+ // longtables cannot have a vertical alignment
+ TableAlignCO->setCurrentIndex(Tabular::LYX_VALIGN_MIDDLE);
}
+ switch (tabular.longtabular_alignment) {
+ case Tabular::LYX_LONGTABULAR_ALIGN_LEFT:
+ leftRB->setChecked(true);
+ break;
+ case Tabular::LYX_LONGTABULAR_ALIGN_CENTER:
+ centerRB->setChecked(true);
+ break;
+ case Tabular::LYX_LONGTABULAR_ALIGN_RIGHT:
+ rightRB->setChecked(true);
+ break;
+ default:
+ centerRB->setChecked(true);
+ break;
+ }
+ captionStatusCB->blockSignals(true);
+ captionStatusCB->setChecked(tabular.ltCaption(row));
+ captionStatusCB->blockSignals(false);
Tabular::ltType ltt;
bool use_empty;
- bool row_set = tabular_.getRowOfLTHead(row, ltt);
+ bool row_set = tabular.getRowOfLTHead(row, ltt);
headerStatusCB->setChecked(row_set);
if (ltt.set) {
headerBorderAboveCB->setChecked(ltt.topDL);
} else {
headerBorderAboveCB->setChecked(false);
headerBorderBelowCB->setChecked(false);
- headerBorderAboveCB->setEnabled(false);
- headerBorderBelowCB->setEnabled(false);
firstheaderNoContentsCB->setChecked(false);
- firstheaderNoContentsCB->setEnabled(false);
use_empty = false;
}
- row_set = tabular_.getRowOfLTFirstHead(row, ltt);
+ row_set = tabular.getRowOfLTFirstHead(row, ltt);
firstheaderStatusCB->setChecked(row_set);
if (ltt.set && (!ltt.empty || !use_empty)) {
firstheaderBorderAboveCB->setChecked(ltt.topDL);
firstheaderBorderBelowCB->setChecked(ltt.bottomDL);
} else {
- firstheaderBorderAboveCB->setEnabled(false);
- firstheaderBorderBelowCB->setEnabled(false);
firstheaderBorderAboveCB->setChecked(false);
firstheaderBorderBelowCB->setChecked(false);
- if (use_empty) {
- firstheaderNoContentsCB->setChecked(ltt.empty);
- if (ltt.empty)
- firstheaderStatusCB->setEnabled(false);
- }
}
- row_set = tabular_.getRowOfLTFoot(row, ltt);
+ row_set = tabular.getRowOfLTFoot(row, ltt);
footerStatusCB->setChecked(row_set);
if (ltt.set) {
footerBorderAboveCB->setChecked(ltt.topDL);
} else {
footerBorderAboveCB->setChecked(false);
footerBorderBelowCB->setChecked(false);
- footerBorderAboveCB->setEnabled(false);
- footerBorderBelowCB->setEnabled(false);
lastfooterNoContentsCB->setChecked(false);
- lastfooterNoContentsCB->setEnabled(false);
use_empty = false;
}
- row_set = tabular_.getRowOfLTLastFoot(row, ltt);
- lastfooterStatusCB->setChecked(row_set);
+ row_set = tabular.getRowOfLTLastFoot(row, ltt);
+ lastfooterStatusCB->setChecked(row_set);
if (ltt.set && (!ltt.empty || !use_empty)) {
lastfooterBorderAboveCB->setChecked(ltt.topDL);
lastfooterBorderBelowCB->setChecked(ltt.bottomDL);
} else {
- lastfooterBorderAboveCB->setEnabled(false);
- lastfooterBorderBelowCB->setEnabled(false);
lastfooterBorderAboveCB->setChecked(false);
lastfooterBorderBelowCB->setChecked(false);
- if (use_empty) {
- lastfooterNoContentsCB->setChecked(ltt.empty);
- if (ltt.empty)
- lastfooterStatusCB->setEnabled(false);
- }
- }
- newpageCB->setChecked(tabular_.getLTNewPage(row));
-}
-
-
-void GuiTabular::closeGUI()
-{
- // ugly hack to auto-apply the stuff that hasn't been
- // yet. don't let this continue to exist ...
-
- // Subtle here, we must /not/ apply any changes and
- // then refer to tabular, as it will have been freed
- // since the changes update the actual tabular_
- //
- // apply the fixed width values
- size_t const cell = getActiveCell();
- bool const multicol = tabular_.isMultiColumn(cell);
- string width = widgetsToLength(widthED, widthUnit);
- string width2;
-
- Length llen = getColumnPWidth(tabular_, cell);
- Length llenMulti = getMColumnPWidth(tabular_, cell);
-
- if (multicol && !llenMulti.zero())
- width2 = llenMulti.asString();
- else if (!multicol && !llen.zero())
- width2 = llen.asString();
-
- // apply the special alignment
- docstring const sa1 = qstring_to_ucs4(specialAlignmentED->text());
- docstring sa2;
-
- if (multicol)
- sa2 = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_MULTI);
- else
- sa2 = getAlignSpecial(tabular_, cell, Tabular::SET_SPECIAL_COLUMN);
-
- if (sa1 != sa2) {
- if (multicol)
- set(Tabular::SET_SPECIAL_MULTI, to_utf8(sa1));
- else
- set(Tabular::SET_SPECIAL_COLUMN, to_utf8(sa1));
- }
-
- if (width != width2) {
- if (multicol)
- set(Tabular::SET_MPWIDTH, width);
- else
- set(Tabular::SET_PWIDTH, width);
- }
-
- /* DO WE NEED THIS?
- switch (topspaceCO->currentIndex()) {
- case 0:
- set(Tabular::SET_TOP_SPACE, "");
- break;
- case 1:
- set(Tabular::SET_TOP_SPACE, "default");
- break;
- case 2:
- set(Tabular::SET_TOP_SPACE,
- widgetsToLength(topspaceED, topspaceUnit));
- break;
- }
-
- switch (bottomspaceCO->currentIndex()) {
- case 0:
- set(Tabular::SET_BOTTOM_SPACE, "");
- break;
- case 1:
- set(Tabular::SET_BOTTOM_SPACE, "default");
- break;
- case 2:
- set(Tabular::SET_BOTTOM_SPACE,
- widgetsToLength(bottomspaceED, bottomspaceUnit));
- break;
- }
-
- switch (interlinespaceCO->currentIndex()) {
- case 0:
- set(Tabular::SET_INTERLINE_SPACE, "");
- break;
- case 1:
- set(Tabular::SET_INTERLINE_SPACE, "default");
- break;
- case 2:
- set(Tabular::SET_INTERLINE_SPACE,
- widgetsToLength(interlinespaceED, interlinespaceUnit));
- break;
- }
-*/
-}
-
-
-bool GuiTabular::initialiseParams(string const & data)
-{
- // try to get the current cell
- BufferView const * const bv = bufferview();
- InsetTabular const * current_inset = 0;
- if (bv) {
- Cursor const & cur = bv->cursor();
- // get the innermost tabular inset;
- // assume that it is "ours"
- for (int i = cur.depth() - 1; i >= 0; --i)
- if (cur[i].inset().lyxCode() == TABULAR_CODE) {
- current_inset = static_cast<InsetTabular const *>(&cur[i].inset());
- active_cell_ = cur[i].idx();
- break;
- }
}
+ newpageCB->setChecked(tabular.getLTNewPage(row));
- if (current_inset && data.empty()) {
- tabular_ = Tabular(current_inset->tabular);
- return true;
- }
-
- InsetTabular tmp(buffer());
- InsetTabular::string2params(data, tmp);
- tabular_ = Tabular(tmp.tabular);
- return true;
-}
-
-
-void GuiTabular::clearParams()
-{
- InsetTabular tmp(buffer());
- tabular_ = tmp.tabular;
- active_cell_ = Tabular::npos;
-}
-
-
-Tabular::idx_type GuiTabular::getActiveCell() const
-{
- return active_cell_;
-}
-
-
-void GuiTabular::set(Tabular::Feature f, string const & arg)
-{
- string const data = featureAsString(f) + ' ' + arg;
- dispatch(FuncRequest(getLfun(), data));
-}
-
+ // first header can only be suppressed when there is a header
+ firstheader_suppressable_ = tabular.haveLTHead()
+ && !tabular.haveLTFirstHead();
+ // last footer can only be suppressed when there is a footer
+ lastfooter_suppressable_ = tabular.haveLTFoot()
+ && !tabular.haveLTLastFoot();
-bool GuiTabular::useMetricUnits() const
-{
- return lyxrc.default_papersize > PAPER_USEXECUTIVE;
-}
-
-
-void GuiTabular::setSpecial(string const & special)
-{
- if (tabular_.isMultiColumn(getActiveCell()))
- set(Tabular::SET_SPECIAL_MULTI, special);
- else
- set(Tabular::SET_SPECIAL_COLUMN, special);
+ // after setting the features, check if they are enabled
+ checkEnabled();
}
-void GuiTabular::setWidth(string const & width)
+bool GuiTabular::checkWidgets(bool readonly) const
{
- if (tabular_.isMultiColumn(getActiveCell()))
- set(Tabular::SET_MPWIDTH, width);
- else
- set(Tabular::SET_PWIDTH, width);
-
- updateView();
+ tabularRowED->setReadOnly(readonly);
+ tabularColumnED->setReadOnly(readonly);
+ tabularWidthED->setReadOnly(readonly);
+ specialAlignmentED->setReadOnly(readonly);
+ columnWidthED->setReadOnly(readonly);
+ multirowOffsetED->setReadOnly(readonly);
+ decimalPointED->setReadOnly(readonly);
+
+ if (readonly) {
+ multicolumnCB->setEnabled(false);
+ multirowCB->setEnabled(false);
+ rotateCellCB->setEnabled(false);
+ rotateCellAngleSB->setEnabled(false);
+ rotateTabularCB->setEnabled(false);
+ rotateTabularAngleSB->setEnabled(false);
+ longTabularCB->setEnabled(false);
+ borders->setEnabled(false);
+ tabularWidthUnitLC->setEnabled(false);
+ columnWidthUnitLC->setEnabled(false);
+ multirowOffsetUnitLC->setEnabled(false);
+ setBordersGB->setEnabled(false);
+ allBordersGB->setEnabled(false);
+ borderStyleGB->setEnabled(false);
+ booktabsRB->setEnabled(false);
+ topspaceCO->setEnabled(false);
+ topspaceUnitLC->setEnabled(false);
+ bottomspaceCO->setEnabled(false);
+ bottomspaceUnitLC->setEnabled(false);
+ interlinespaceCO->setEnabled(false);
+ interlinespaceUnitLC->setEnabled(false);
+ hAlignCO->setEnabled(false);
+ vAlignCO->setEnabled(false);
+ TableAlignCO->setEnabled(false);
+ longtableGB->setEnabled(false);
+ alignmentGB->setEnabled(false);
+ } else
+ enableWidgets();
+
+ return InsetParamsWidget::checkWidgets();
}
-void GuiTabular::toggleMultiColumn()
+bool GuiTabular::funcEnabled(Tabular::Feature f) const
{
- set(Tabular::MULTICOLUMN);
- updateView();
+ FuncRequest r(LFUN_INSET_MODIFY, "tabular for-dialog" + featureAsString(f));
+ return getStatus(r).enabled();
}
-void GuiTabular::rotateTabular(bool yes)
-{
- if (yes)
- set(Tabular::SET_ROTATE_TABULAR);
- else
- set(Tabular::UNSET_ROTATE_TABULAR);
-}
-
-
-void GuiTabular::rotateCell(bool yes)
-{
- if (yes)
- set(Tabular::SET_ROTATE_CELL);
- else
- set(Tabular::UNSET_ROTATE_CELL);
-}
-
-
-void GuiTabular::halign(GuiTabular::HALIGN h)
-{
- Tabular::Feature num = Tabular::ALIGN_LEFT;
- Tabular::Feature multi_num = Tabular::M_ALIGN_LEFT;
-
- switch (h) {
- case LEFT:
- num = Tabular::ALIGN_LEFT;
- multi_num = Tabular::M_ALIGN_LEFT;
- break;
- case CENTER:
- num = Tabular::ALIGN_CENTER;
- multi_num = Tabular::M_ALIGN_CENTER;
- break;
- case RIGHT:
- num = Tabular::ALIGN_RIGHT;
- multi_num = Tabular::M_ALIGN_RIGHT;
- break;
- case BLOCK:
- num = Tabular::ALIGN_BLOCK;
- //multi_num: no equivalent
- break;
- }
-
- if (tabular_.isMultiColumn(getActiveCell()))
- set(multi_num);
- else
- set(num);
-}
-
-
-void GuiTabular::valign(GuiTabular::VALIGN v)
-{
- Tabular::Feature num = Tabular::VALIGN_MIDDLE;
- Tabular::Feature multi_num = Tabular::M_VALIGN_MIDDLE;
-
- switch (v) {
- case TOP:
- num = Tabular::VALIGN_TOP;
- multi_num = Tabular::M_VALIGN_TOP;
- break;
- case MIDDLE:
- num = Tabular::VALIGN_MIDDLE;
- multi_num = Tabular::M_VALIGN_MIDDLE;
- break;
- case BOTTOM:
- num = Tabular::VALIGN_BOTTOM;
- multi_num = Tabular::M_VALIGN_BOTTOM;
- break;
- }
-
- if (tabular_.isMultiColumn(getActiveCell()))
- set(multi_num);
- else
- set(num);
-}
-
-
-void GuiTabular::booktabs(bool yes)
-{
- if (yes)
- set(Tabular::SET_BOOKTABS);
- else
- set(Tabular::UNSET_BOOKTABS);
-}
-
-
-void GuiTabular::longTabular(bool yes)
-{
- if (yes)
- set(Tabular::SET_LONGTABULAR);
- else
- set(Tabular::UNSET_LONGTABULAR);
-}
-
-
-Dialog * createGuiTabular(GuiView & lv) { return new GuiTabular(lv); }
-
-
} // namespace frontend
} // namespace lyx
-#include "GuiTabular_moc.cpp"
+#include "moc_GuiTabular.cpp"