Am 10.05.2015 um 16:52 schrieb Uwe Stöhr:
If you insist in having the new feature not to be truncated, I have to output ERT.
The attached better patch does this. It also addresses now tex2lyx.
In general we should think about dropping the support to revert documents to older versions of LyX....
Of course for LyX 2.2 we cannot change our policy but we should at least discuss to drop it for LyX 2.3.
regards Uwe
development/FORMAT | 8 + lib/lyx2lyx/LyX.py | 2 +- lib/lyx2lyx/lyx_2_2.py | 60 +++++- src/frontends/qt4/GuiBox.cpp | 139 ++++++++++++-- src/frontends/qt4/ui/BoxUi.ui | 432 +++++++++++++++++++++++++----------------- src/insets/InsetBox.cpp | 110 ++++++++++- src/insets/InsetBox.h | 7 + src/tex2lyx/text.cpp | 6 + src/version.h | 4 +- 9 files changed, 561 insertions(+), 207 deletions(-) diff --git a/development/FORMAT b/development/FORMAT index a0bf4fa..058e382 100644 --- a/development/FORMAT +++ b/development/FORMAT @@ -11,6 +11,14 @@ adjustments are made to tex2lyx and bugs are fixed in lyx2lyx. ----------------------- +2015-05-xx Uwe Stöhr <uwesto...@web.de> + * Format incremented to 489: support to set line thickness, box separation + and shadow size in the box dialog + New box parameters: + - thickness + - separation + - shadowsize + 2015-04-21 Jürgen Spitzmüller <sp...@lyx.org> * Format incremented to 488: Rewrite the Glosse insets (Glosse and Tri-Glosse). These insets now do not any longer use PassThru. Instead, they use an optional diff --git a/lib/lyx2lyx/LyX.py b/lib/lyx2lyx/LyX.py index f5e6e40..934f995 100644 --- a/lib/lyx2lyx/LyX.py +++ b/lib/lyx2lyx/LyX.py @@ -85,7 +85,7 @@ format_relation = [("0_06", [200], minor_versions("0.6" , 4)), ("1_6", list(range(277,346)), minor_versions("1.6" , 10)), ("2_0", list(range(346,414)), minor_versions("2.0" , 8)), ("2_1", list(range(414,475)), minor_versions("2.1" , 0)), - ("2_2", list(range(475,489)), minor_versions("2.2" , 0)) + ("2_2", list(range(475,490)), minor_versions("2.2" , 0)) ] #################################################################### diff --git a/lib/lyx2lyx/lyx_2_2.py b/lib/lyx2lyx/lyx_2_2.py index 68545dd..b848402 100644 --- a/lib/lyx2lyx/lyx_2_2.py +++ b/lib/lyx2lyx/lyx_2_2.py @@ -956,6 +956,62 @@ def convert_newgloss(document): i = endPlain + 1 +def convert_BoxFeatures(document): + " adds new box features " + + i = 0 + while True: + i = find_token(document.body, "height_special", i) + if i == -1: + return + document.body.insert(i + 1, 'thickness "0.4pt"\nseparation "3pt"\nshadowsize "4pt"\n') + i = i + 1 + + +def revert_BoxFeatures(document): + " deletes new box features " + + i = 0 + while True: + i = find_token(document.body, "height_special", i) + if i == -1: + return + # read out the values + beg = document.body[i+1].find('"'); + end = document.body[i+1].rfind('"'); + thickness = document.body[i+1][beg+1:end]; + beg = document.body[i+2].find('"'); + end = document.body[i+2].rfind('"'); + separation = document.body[i+2][beg+1:end]; + beg = document.body[i+3].find('"'); + end = document.body[i+3].rfind('"'); + shadowsize = document.body[i+3][beg+1:end]; + # delete the specification + del document.body[i+1:i+4] + # output ERT + # first output the closing braces + if shadowsize != "4pt" or separation != "3pt" or thickness != "0.4pt": + document.body[i + 10 : i + 10] = put_cmd_in_ert("}") + # now output the lengths + if shadowsize != "4pt" or separation != "3pt" or thickness != "0.4pt": + document.body[i - 10 : i - 10] = put_cmd_in_ert("{") + if thickness != "0.4pt": + document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness] + if separation != "3pt" and thickness == "0.4pt": + document.body[i - 5 : i - 4] = ["{\\backslash fboxsep " + separation] + if separation != "3pt" and thickness != "0.4pt": + document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation] + if shadowsize != "4pt" and separation == "3pt" and thickness == "0.4pt": + document.body[i - 5 : i - 4] = ["{\\backslash shadowsize " + shadowsize] + if shadowsize != "4pt" and separation != "3pt" and thickness == "0.4pt": + document.body[i - 5 : i - 4] = ["{\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize] + if shadowsize != "4pt" and separation == "3pt" and thickness != "0.4pt": + document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash shadowsize " + shadowsize] + if shadowsize != "4pt" and separation != "3pt" and thickness != "0.4pt": + document.body[i - 5 : i - 4] = ["{\\backslash fboxrule " + thickness + "\\backslash fboxsep " + separation + "\\backslash shadowsize " + shadowsize] + i = i + 11 + + ## # Conversion hub # @@ -978,10 +1034,12 @@ convert = [ [485, []], [486, []], [487, []], - [488, [convert_newgloss]] + [488, [convert_newgloss]], + [489, [convert_BoxFeatures]] ] revert = [ + [488, [revert_BoxFeatures]], [487, [revert_newgloss, revert_glossgroup]], [486, [revert_forest]], [485, [revert_ex_itemargs]], diff --git a/src/frontends/qt4/GuiBox.cpp b/src/frontends/qt4/GuiBox.cpp index 86cdf8e..c5244d0 100644 --- a/src/frontends/qt4/GuiBox.cpp +++ b/src/frontends/qt4/GuiBox.cpp @@ -6,6 +6,7 @@ * \author Jürgen Vigna (Minipage stuff) * \author Martin Vermeer * \author Jürgen Spitzmüller + * \author Uwe Stöhr * * Full author contact details are available in file CREDITS. */ @@ -98,13 +99,28 @@ GuiBox::GuiBox(QWidget * parent) : InsetParamsWidget(parent) this, SIGNAL(changed())); connect(halignCO, SIGNAL(activated(int)), this, SIGNAL(changed())); connect(ialignCO, SIGNAL(activated(int)), this, SIGNAL(changed())); + connect(thicknessED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(thicknessUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT)), + this, SIGNAL(changed())); + connect(separationED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(separationUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT)), + this, SIGNAL(changed())); + connect(shadowsizeED, SIGNAL(textChanged(QString)), this, SIGNAL(changed())); + connect(shadowsizeUnitsLC, SIGNAL(selectionChanged(lyx::Length::UNIT)), + this, SIGNAL(changed())); heightED->setValidator(unsignedLengthValidator(heightED)); widthED->setValidator(unsignedLengthValidator(widthED)); + thicknessED->setValidator(unsignedLengthValidator(thicknessED)); + separationED->setValidator(unsignedLengthValidator(separationED)); + shadowsizeED->setValidator(unsignedLengthValidator(shadowsizeED)); // initialize the length validator addCheckedWidget(widthED, widthCB); addCheckedWidget(heightED, heightCB); + addCheckedWidget(thicknessED, thicknessLA); + addCheckedWidget(separationED, separationLA); + addCheckedWidget(shadowsizeED, shadowsizeLA); initDialog(); } @@ -142,11 +158,10 @@ void GuiBox::on_typeCO_activated(int index) heightCB->setChecked(false); setSpecial(ibox); } - if (type != "Boxed") { + if (type != "Boxed") if (type != "Frameless") widthCB->setChecked(itype != "none"); pagebreakCB->setChecked(false); - } changed(); } @@ -160,6 +175,15 @@ void GuiBox::initDialog() widthUnitsLC->setCurrentItem(Length::PCW); heightED->setText("1"); heightUnitsLC->setCurrentItem("totalheight"); + // LaTeX's default for \fboxrule is 0.4 pt + thicknessED->setText("0.4"); + thicknessUnitsLC->setCurrentItem(Length::PT); + // LaTeX's default for \fboxsep is 3 pt + separationED->setText("3"); + separationUnitsLC->setCurrentItem(Length::PT); + // LaTeX's default for \shadowsize is 4 pt + shadowsizeED->setText("4"); + shadowsizeUnitsLC->setCurrentItem(Length::PT); } @@ -226,10 +250,14 @@ void GuiBox::paramsToDialog(Inset const * inset) ialignCO->setEnabled(ibox); setSpecial(ibox); - // halign is only allowed without inner box and if a width is used and if - // pagebreak is not used - halignCO->setEnabled(!pagebreakCB->isChecked() && widthCB->isChecked() - && ((!ibox && type == "Boxed") || params.use_makebox)); + // halign is only allowed if a width is used + halignCO->setEnabled(widthCB->isChecked()); + // add the entry "Stretch" if the box is \makebox or \framebox and if not already there + if ((inner_type == "makebox" || (type == "Boxed" && inner_type == "none")) + && halignCO->count() < 4) + halignCO->addItem(toqstr("Stretch")); + else if (inner_type != "makebox" && (type != "Boxed" && inner_type != "none")) + halignCO->removeItem(3); // pagebreak is only allowed for Boxed without inner box pagebreakCB->setEnabled(!ibox && type == "Boxed"); @@ -271,6 +299,24 @@ void GuiBox::paramsToDialog(Inset const * inset) heightCB->setCheckState(Qt::Checked); heightCB->setEnabled(ibox); + + // enable line thickness only for the rectangular frame types and drop shadow + thicknessED->setEnabled(type == "Boxed" || type == "Doublebox" || type == "Shadowbox"); + thicknessUnitsLC->setEnabled(type == "Boxed" || type == "Doublebox" || type == "Shadowbox"); + lengthToWidgets(thicknessED, thicknessUnitsLC, + (params.thickness).asString(), default_unit); + // enable line separation for the allowed frame types + separationED->setEnabled(type == "Boxed" || type == "ovalbox" || type == "Ovalbox" + || type == "Doublebox" || type == "Shadowbox"); + separationUnitsLC->setEnabled(type == "Boxed" || type == "ovalbox" || type == "Ovalbox" + || type == "Doublebox" || type == "Shadowbox"); + lengthToWidgets(separationED, separationUnitsLC, + (params.separation).asString(), default_unit); + // enable shadow size for drop shadow + shadowsizeED->setEnabled(type == "Shadowbox"); + shadowsizeUnitsLC->setEnabled(type == "Shadowbox"); + lengthToWidgets(shadowsizeED, shadowsizeUnitsLC, + (params.shadowsize).asString(), default_unit); } @@ -338,6 +384,21 @@ docstring GuiBox::dialogToParams() const Length(widgetsToLength(heightED, heightUnitsLC)); } } + + // handle the line thickness, line separation and shadow size + if (thicknessED->isEnabled()) + params.thickness = Length(widgetsToLength(thicknessED, thicknessUnitsLC)); + else + params.thickness = Length(); + if (separationED->isEnabled()) + params.separation = Length(widgetsToLength(separationED, separationUnitsLC)); + else + params.separation = Length(); + if (separationED->isEnabled()) + params.shadowsize = Length(widgetsToLength(shadowsizeED, shadowsizeUnitsLC)); + else + params.shadowsize = Length(); + return from_ascii(InsetBox::params2string(params)); } @@ -358,39 +419,79 @@ bool GuiBox::checkWidgets(bool readonly) const heightED->setEnabled(false); heightUnitsLC->setEnabled(false); heightCB->setEnabled(false); + thicknessED->setEnabled(false); + thicknessUnitsLC->setEnabled(false); + separationED->setEnabled(false); + separationUnitsLC->setEnabled(false); + shadowsizeED->setEnabled(false); + shadowsizeUnitsLC->setEnabled(false); } else { QString const outer = typeCO->itemData(typeCO->currentIndex()).toString(); QString const itype = innerBoxCO->itemData(innerBoxCO->currentIndex()).toString(); bool const ibox = (itype != "none" && itype != "makebox"); - // pagebreak is only allowed for Boxed without inner box - pagebreakCB->setEnabled(!ibox && outer == "Boxed"); - innerBoxCO->setEnabled(!pagebreakCB->isChecked()); valignCO->setEnabled(ibox); ialignCO->setEnabled(ibox); - // halign is only allowed without inner box and if a width is used and if - // pagebreak is not used - halignCO->setEnabled(!pagebreakCB->isChecked() && widthCB->isChecked() - && ((!ibox && outer == "Boxed") || itype == "makebox")); + if (heightCB->isChecked() && !ibox) + heightCB->setChecked(false); + heightCB->setEnabled(ibox); // the width can only be selected for makebox or framebox widthCB->setEnabled(itype == "makebox" - || (outer == "Boxed" - && !ibox && !pagebreakCB->isChecked())); - // except for frameless and boxed, the width cannot be specified if + || (outer == "Boxed" && itype == "none") + && !pagebreakCB->isChecked()); + // except for Frameless and Boxed, the width cannot be specified if // there is no inner box bool const width_enabled = ibox || outer == "Frameless" || outer == "Boxed"; - // enable if width_enabled, except if checkbox is active but unset - widthED->setEnabled(width_enabled || (widthCB->isEnabled() && widthCB->isChecked())); - widthUnitsLC->setEnabled(width_enabled || (widthCB->isEnabled() && widthCB->isChecked())); + // enable if width_enabled + widthED->setEnabled(width_enabled); + widthUnitsLC->setEnabled(width_enabled); if (!widthCB->isChecked() && widthCB->isEnabled()) { widthED->setEnabled(false); widthUnitsLC->setEnabled(false); } + // halign is only allowed if a width is used + halignCO->setEnabled(widthCB->isChecked()); + // add the entry "Stretch" if the box is \makebox or \framebox and if not already there + if ((itype == "makebox" || (outer == "Boxed" && itype == "none")) + && halignCO->count() < 4) + halignCO->addItem(toqstr("Stretch")); + else if (itype != "makebox" && (outer != "Boxed" && itype != "none")) + halignCO->removeItem(3); + // pagebreak is only allowed for Boxed without inner box + pagebreakCB->setEnabled(!ibox && outer == "Boxed"); + heightED->setEnabled(itype != "none" && heightCB->isChecked()); heightUnitsLC->setEnabled(itype != "none" && heightCB->isChecked()); heightCB->setEnabled(ibox); + + // enable line thickness for the rectangular frame types and drop shadow + thicknessED->setEnabled(outer == "Boxed" || outer == "Doublebox" || outer == "Shadowbox"); + thicknessUnitsLC->setEnabled(outer == "Boxed" || outer == "Doublebox" || outer == "Shadowbox"); + // set default values if empty + if (thicknessED->text().isEmpty() && thicknessED->isEnabled()) { + thicknessED->setText("0.4"); + thicknessUnitsLC->setCurrentItem(Length::PT); + } + // enable line separation for the allowed frame types + separationED->setEnabled(outer == "Boxed" || outer == "ovalbox" || outer == "Ovalbox" + || outer == "Doublebox" || outer == "Shadowbox"); + separationUnitsLC->setEnabled(outer == "Boxed" || outer == "ovalbox" || outer == "Ovalbox" + || outer == "Doublebox" || outer == "Shadowbox"); + // set default values if empty + if (separationED->text().isEmpty() && separationED->isEnabled()) { + separationED->setText("3"); + separationUnitsLC->setCurrentItem(Length::PT); + } + // enable shadow size for drop shadow + shadowsizeED->setEnabled(outer == "Shadowbox"); + shadowsizeUnitsLC->setEnabled(outer == "Shadowbox"); + // set default values if empty + if (shadowsizeED->text().isEmpty() && shadowsizeED->isEnabled()) { + shadowsizeED->setText("4"); + shadowsizeUnitsLC->setCurrentItem(Length::PT); + } } return InsetParamsWidget::checkWidgets(); diff --git a/src/frontends/qt4/ui/BoxUi.ui b/src/frontends/qt4/ui/BoxUi.ui index 982b077..bd530c2 100644 --- a/src/frontends/qt4/ui/BoxUi.ui +++ b/src/frontends/qt4/ui/BoxUi.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>261</width> - <height>245</height> + <width>262</width> + <height>411</height> </rect> </property> <property name="windowTitle"> @@ -16,40 +16,137 @@ <property name="sizeGripEnabled" stdset="0"> <bool>true</bool> </property> - <layout class="QGridLayout"> - <property name="margin"> - <number>9</number> - </property> - <property name="spacing"> - <number>6</number> - </property> - <item row="4" column="0" colspan="2"> - <widget class="QCheckBox" name="pagebreakCB"> - <property name="toolTip"> - <string>Check this if the box should break across pages</string> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <widget class="QGroupBox" name="TypesizeGB"> + <property name="title"> + <string>Type and size</string> </property> - <property name="text"> - <string>Allow &page breaks</string> + <property name="flat"> + <bool>true</bool> </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="innerBoxLA"> + <property name="toolTip"> + <string/> + </property> + <property name="text"> + <string>Inner Bo&x:</string> + </property> + <property name="buddy"> + <cstring>innerBoxCO</cstring> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="widthCB"> + <property name="toolTip"> + <string/> + </property> + <property name="text"> + <string>&Width:</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="widthED"> + <property name="toolTip"> + <string>Width value</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="lyx::frontend::LengthCombo" name="widthUnitsLC"/> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="heightCB"> + <property name="toolTip"> + <string/> + </property> + <property name="text"> + <string>&Height:</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="heightED"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Height value</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="lyx::frontend::LengthCombo" name="heightUnitsLC"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QCheckBox" name="pagebreakCB"> + <property name="toolTip"> + <string>Check this if the box should break across pages</string> + </property> + <property name="text"> + <string>Allow &page breaks</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QComboBox" name="innerBoxCO"> + <property name="toolTip"> + <string>Inner box -- needed for fixed width & line breaks</string> + </property> + <item> + <property name="text"> + <string>None</string> + </property> + </item> + <item> + <property name="text"> + <string>Parbox</string> + </property> + </item> + <item> + <property name="text"> + <string>Minipage</string> + </property> + </item> + </widget> + </item> + </layout> </widget> </item> - <item row="5" column="0" colspan="3"> - <widget class="QGroupBox" name="groupBox_2"> + <item row="1" column="0"> + <widget class="QGroupBox" name="AlignmentGB"> <property name="title"> <string>Alignment</string> </property> <property name="flat"> <bool>true</bool> </property> - <layout class="QGridLayout"> - <property name="margin"> - <number>9</number> - </property> - <property name="spacing"> - <number>6</number> - </property> + <layout class="QGridLayout" name="gridLayout_2"> <item row="1" column="2"> <widget class="QComboBox" name="halignCO"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -74,15 +171,58 @@ <string>Right</string> </property> </item> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="ialignLA"> + <property name="toolTip"> + <string>Vertical alignment of the content inside the box</string> + </property> + <property name="text"> + <string>Vertical</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="halignLA"> + <property name="toolTip"> + <string>Horizontal alignment of the content inside the box</string> + </property> + <property name="text"> + <string>Horizontal</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="valignCO"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="toolTip"> + <string>Vertical alignment of the box (with regard to baseline)</string> + </property> <item> <property name="text"> - <string>Stretch</string> + <string>Top</string> + </property> + </item> + <item> + <property name="text"> + <string>Middle</string> + </property> + </item> + <item> + <property name="text"> + <string>Bottom</string> </property> </item> </widget> </item> <item row="1" column="1"> <widget class="QComboBox" name="ialignCO"> + <property name="enabled"> + <bool>true</bool> + </property> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -114,26 +254,14 @@ </item> </widget> </item> - <item row="2" column="1"> - <widget class="QComboBox" name="valignCO"> - <property name="toolTip"> - <string>Vertical alignment of the box (with regard to baseline)</string> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Co&ntent:</string> + </property> + <property name="buddy"> + <cstring>ialignCO</cstring> </property> - <item> - <property name="text"> - <string>Top</string> - </property> - </item> - <item> - <property name="text"> - <string>Middle</string> - </property> - </item> - <item> - <property name="text"> - <string>Bottom</string> - </property> - </item> </widget> </item> <item row="2" column="0"> @@ -149,153 +277,113 @@ </property> </widget> </item> - <item row="1" column="0"> - <widget class="QLabel" name="label"> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QGroupBox" name="DecorationGB"> + <property name="title"> + <string>Decoration</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="typeLA"> + <property name="toolTip"> + <string/> + </property> <property name="text"> - <string>Co&ntent:</string> + <string>&Decoration:</string> </property> <property name="buddy"> - <cstring>ialignCO</cstring> + <cstring>typeCO</cstring> </property> </widget> </item> - <item row="0" column="1"> - <widget class="QLabel" name="ialignLA"> + <item row="0" column="1" colspan="2"> + <widget class="QComboBox" name="typeCO"> <property name="toolTip"> - <string>Vertical alignment of the content inside the box</string> + <string>Supported box types</string> </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="thicknessLA"> <property name="text"> - <string>Vertical</string> + <string>Line thickness:</string> </property> </widget> </item> - <item row="0" column="2"> - <widget class="QLabel" name="halignLA"> + <item row="1" column="1"> + <widget class="QLineEdit" name="thicknessED"> + <property name="enabled"> + <bool>false</bool> + </property> <property name="toolTip"> - <string>Horizontal alignment of the content inside the box</string> + <string>Width value</string> </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="lyx::frontend::LengthCombo" name="thicknessUnitsLC"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="separationLA"> <property name="text"> - <string>Horizontal</string> + <string>Box separation:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="separationED"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Width value</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="lyx::frontend::LengthCombo" name="separationUnitsLC"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="shadowsizeLA"> + <property name="text"> + <string>Shadow size:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="shadowsizeED"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Width value</string> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="lyx::frontend::LengthCombo" name="shadowsizeUnitsLC"> + <property name="enabled"> + <bool>false</bool> </property> </widget> </item> </layout> </widget> </item> - <item row="3" column="2"> - <widget class="lyx::frontend::LengthCombo" name="heightUnitsLC"> - <property name="enabled"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QCheckBox" name="heightCB"> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>&Height:</string> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <property name="tristate"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="innerBoxLA"> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>Inner Bo&x:</string> - </property> - <property name="buddy"> - <cstring>innerBoxCO</cstring> - </property> - </widget> - </item> - <item row="2" column="2"> - <widget class="lyx::frontend::LengthCombo" name="widthUnitsLC"/> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="typeLA"> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>&Decoration:</string> - </property> - <property name="buddy"> - <cstring>typeCO</cstring> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QCheckBox" name="widthCB"> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>&Width:</string> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <property name="tristate"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLineEdit" name="heightED"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="toolTip"> - <string>Height value</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="widthED"> - <property name="toolTip"> - <string>Width value</string> - </property> - </widget> - </item> - <item row="1" column="1" colspan="2"> - <widget class="QComboBox" name="innerBoxCO"> - <property name="toolTip"> - <string>Inner box -- needed for fixed width & line breaks</string> - </property> - <item> - <property name="text"> - <string>None</string> - </property> - </item> - <item> - <property name="text"> - <string>Parbox</string> - </property> - </item> - <item> - <property name="text"> - <string>Minipage</string> - </property> - </item> - </widget> - </item> - <item row="0" column="1" colspan="2"> - <widget class="QComboBox" name="typeCO"> - <property name="toolTip"> - <string>Supported box types</string> - </property> - </widget> - </item> </layout> </widget> <customwidgets> @@ -308,11 +396,7 @@ <tabstops> <tabstop>typeCO</tabstop> <tabstop>innerBoxCO</tabstop> - <tabstop>widthED</tabstop> - <tabstop>widthUnitsLC</tabstop> <tabstop>heightCB</tabstop> - <tabstop>heightED</tabstop> - <tabstop>heightUnitsLC</tabstop> <tabstop>ialignCO</tabstop> <tabstop>halignCO</tabstop> <tabstop>valignCO</tabstop> diff --git a/src/insets/InsetBox.cpp b/src/insets/InsetBox.cpp index ddb1dce..e6e873b 100644 --- a/src/insets/InsetBox.cpp +++ b/src/insets/InsetBox.cpp @@ -6,6 +6,7 @@ * \author Angus Leeming * \author Martin Vermeer * \author Jürgen Spitzmüller + * \author Uwe Stöhr * * Full author contact details are available in file CREDITS. */ @@ -272,20 +273,33 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const BoxType btype = boxtranslator().find(params_.type); string width_string = params_.width.asLatexString(); + string thickness_string = params_.thickness.asLatexString(); + string separation_string = params_.separation.asLatexString(); + string shadowsize_string = params_.shadowsize.asLatexString(); bool stdwidth = false; - // FIXME: do not test explicitely values of width_string - if (params_.inner_box && - (width_string.find("1.0\\columnwidth") != string::npos - || width_string.find("1.0\\textwidth") != string::npos)) { + // in general the overall width of some decorated boxes is wider thean the inner box + // we could therefore calculate the real width for all sizes so that if the user wants + // e.g. 0.1\columnwidth or 2cm he gets exactly this size + // however this makes problems when importing TeX code + // therefore only recalculate for the most common case that the box should not protrude + // the page margins + if (params_.inner_box + && ((width_string.find("1\\columnwidth") != string::npos + || width_string.find("1\\textwidth") != string::npos) + || width_string.find("1\\paperwidth") != string::npos + || width_string.find("1\\linewidth") != string::npos)) { stdwidth = true; switch (btype) { case Frameless: + break; case Framed: + width_string += " - 2\\FrameSep - 2\\FrameRule"; break; case Boxed: - case Shaded: width_string += " - 2\\fboxsep - 2\\fboxrule"; break; + case Shaded: + break; case ovalbox: width_string += " - 2\\fboxsep - 0.8pt"; break; @@ -293,8 +307,7 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const width_string += " - 2\\fboxsep - 1.6pt"; break; case Shadowbox: - // Shadow falls outside right margin... opinions? - width_string += " - 2\\fboxsep - 2\\fboxrule"/* "-\\shadowsize"*/; + width_string += " - 2\\fboxsep - 2\\fboxrule - \\shadowsize"; break; case Doublebox: width_string += " - 2\\fboxsep - 7.5\\fboxrule - 1pt"; @@ -306,17 +319,25 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const if (runparams.lastid != -1) os.texrow().start(runparams.lastid, runparams.lastpos); - // Adapt to column/text width correctly also if paragraphs indented: - if (stdwidth) + // adapt column/text width correctly also if paragraphs indented + if (stdwidth && !(buffer().params().paragraph_separation)) os << "\\noindent"; switch (btype) { case Frameless: break; case Framed: + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "{\\FrameRule " << from_ascii(thickness_string); + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "{\\FrameSep " << from_ascii(separation_string); os << "\\begin{framed}%\n"; break; case Boxed: + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "{\\fboxrule " << from_ascii(thickness_string); + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "{\\fboxsep " << from_ascii(separation_string); if (!width_string.empty()) { if (!params_.inner_box) { os << "\\framebox"; @@ -338,12 +359,22 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const os << "{"; break; case ovalbox: + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "{\\fboxsep " << from_ascii(separation_string); os << "\\ovalbox{"; break; case Ovalbox: + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "{\\fboxsep " << from_ascii(separation_string); os << "\\Ovalbox{"; break; case Shadowbox: + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "{\\fboxrule " << from_ascii(thickness_string); + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "{\\fboxsep " << from_ascii(separation_string); + if (!shadowsize_string.empty() && shadowsize_string.find("4pt") == string::npos) + os << "{\\shadowsize " << from_ascii(shadowsize_string); os << "\\shadowbox{"; break; case Shaded: @@ -351,6 +382,10 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const // it is inside a minipage or parbox break; case Doublebox: + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "{\\fboxrule " << from_ascii(thickness_string); + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "{\\fboxsep " << from_ascii(separation_string); os << "\\doublebox{"; break; } @@ -414,6 +449,23 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const os << "\\begin{shaded}%\n"; } + // \framebox and \makebox handle hor_pos their own way + // hor_pos is senseless for \mbox and \fbox + if (!(params_.use_makebox) + && !(btype == Boxed && !params_.inner_box)) { + switch (params_.hor_pos) { + case 'l': + // do nothing because this is LaTeX's default + break; + case 'c': + os << "\\centering "; + break; + case 'r': + os << "\\raggedleft "; + break; + } + } + InsetText::latex(os, runparams); if (btype == Shaded) @@ -431,15 +483,43 @@ void InsetBox::latex(otexstream & os, OutputParams const & runparams) const break; case Framed: os << "\\end{framed}"; + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "}"; + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "}"; break; case Boxed: os << "}"; + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "}"; + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "}"; break; case ovalbox: + os << "}"; + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "}"; + break; case Ovalbox: + os << "}"; + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "}"; + break; case Doublebox: + os << "}"; + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "}"; + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "}"; + break; case Shadowbox: os << "}"; + if (!shadowsize_string.empty() && shadowsize_string.find("4pt") == string::npos) + os << "}"; + if (!separation_string.empty() && separation_string.find("3pt") == string::npos) + os << "}"; + if (!thickness_string.empty() && thickness_string.find("0.4pt") == string::npos) + os << "}"; break; case Shaded: // already done @@ -548,6 +628,7 @@ void InsetBox::validate(LaTeXFeatures & features) const case Frameless: break; case Framed: + features.require("calc"); features.require("framed"); break; case Boxed: @@ -632,7 +713,10 @@ InsetBoxParams::InsetBoxParams(string const & label) hor_pos('c'), inner_pos('t'), height(Length("1in")), - height_special("totalheight") // default is 1\\totalheight + height_special("totalheight"), // default is 1\\totalheight + thickness(Length("0.4pt")), + separation(Length("3pt")), + shadowsize(Length("4pt")) {} @@ -649,6 +733,9 @@ void InsetBoxParams::write(ostream & os) const os << "special \"" << special << "\"\n"; os << "height \"" << height.asString() << "\"\n"; os << "height_special \"" << height_special << "\"\n"; + os << "thickness \"" << thickness.asString() << "\"\n"; + os << "separation \"" << separation.asString() << "\"\n"; + os << "shadowsize \"" << shadowsize.asString() << "\"\n"; } @@ -668,6 +755,9 @@ void InsetBoxParams::read(Lexer & lex) lex >> "special" >> special; lex >> "height" >> height; lex >> "height_special" >> height_special; + lex >> "thickness" >> thickness; + lex >> "separation" >> separation; + lex >> "shadowsize" >> shadowsize; } diff --git a/src/insets/InsetBox.h b/src/insets/InsetBox.h index 76b11f6..e8ea613 100644 --- a/src/insets/InsetBox.h +++ b/src/insets/InsetBox.h @@ -6,6 +6,7 @@ * * \author Angus Leeming * \author Martin Vermeer + * \author Uwe Stöhr * * Full author contact details are available in file CREDITS. */ @@ -52,6 +53,12 @@ public: Length height; /// std::string height_special; + /// + Length thickness; + /// + Length separation; + /// + Length shadowsize; }; diff --git a/src/tex2lyx/text.cpp b/src/tex2lyx/text.cpp index 33c389b..88ec91d 100644 --- a/src/tex2lyx/text.cpp +++ b/src/tex2lyx/text.cpp @@ -847,6 +847,9 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags, string width_unit; string latex_width; string width_special = "none"; + string thickness = "0.4pt"; + string separation = "3pt"; + string shadowsize = "4pt"; if (!inner_type.empty() && p.hasOpt()) { if (inner_type != "makebox") position = p.getArg('[', ']'); @@ -1071,6 +1074,9 @@ void parse_box(Parser & p, ostream & os, unsigned outer_flags, os << "special \"" << width_special << "\"\n"; os << "height \"" << height_value << height_unit << "\"\n"; os << "height_special \"" << height_special << "\"\n"; + os << "thickness \"" << thickness << "\"\n"; + os << "separation \"" << separation << "\"\n"; + os << "shadowsize \"" << shadowsize << "\"\n"; os << "status open\n\n"; // Unfortunately we can't use parse_text_in_inset: diff --git a/src/version.h b/src/version.h index e52d96b..8407528 100644 --- a/src/version.h +++ b/src/version.h @@ -32,8 +32,8 @@ extern char const * const lyx_version_info; // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -#define LYX_FORMAT_LYX 488 // spitz: rework the Glosse insets -#define LYX_FORMAT_TEX2LYX 488 +#define LYX_FORMAT_LYX 489 // uwestoehr: new box features +#define LYX_FORMAT_TEX2LYX 489 #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #ifndef _MSC_VER