fix bug 2558: hspace support in math

The basic idea was to reuse the corresponding text space inset in the same
fashion as is already done for references. The dialog displays a different
selection for math than for text. If wanted, the additional spaces could
also be enabled for text, but that would be a file format change.
Constructs like \hspace{\mylengthvariable} that are not supported are
treated by the math parser as ERT as before.

For reasons I don't know the context menu does not work, but this is not so
important IMHO (since a left click opens the dialog).


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@27954 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Georg Baum 2008-12-22 18:12:32 +00:00
parent df8bb4edcd
commit ac1fd9b37f
14 changed files with 520 additions and 148 deletions

View File

@ -128,13 +128,19 @@ vref ref none
lyxnegspace space none lyxnegspace space none
lyxposspace space none lyxposspace space none
! space none ! space none
negthinspace space none
negmedspace space none negmedspace space none
negthickspace space none negthickspace space none
, space none , space none
thinspace space none
: space none : space none
medspace space none
; space none ; space none
thickspace space none
enskip space none
quad space none quad space none
qquad space none qquad space none
hspace space none
# styles # styles
displaystyle style 0 displaystyle style 0

View File

@ -190,6 +190,24 @@ Menuset
Item "Settings...|S" "next-inset-toggle" Item "Settings...|S" "next-inset-toggle"
End End
#
# InsetMathSpace context menu
#
Menu "context-mathspace"
Item "Thin Space|T" "next-inset-modify mathspace \thinspace{}"
Item "Medium Space|M" "next-inset-modify mathspace \medspace{}"
Item "Thick Space|h" "next-inset-modify mathspace \thickspace{}"
Item "Negative Thin Space|N" "next-inset-modify mathspace \negthinspace{}"
Item "Negative Medium Space|u" "next-inset-modify mathspace \negmedspace{}"
Item "Negative Thick Space|i" "next-inset-modify mathspace \negthickspace{}"
Item "Half Quad Space (Enskip)|k" "next-inset-modify mathspace \enskip{}"
Item "Quad Space|Q" "next-inset-modify mathspace \quad{}"
Item "Double Quad Space|u" "next-inset-modify mathspace \qquad{}"
Item "Custom Length|C" "command-sequence next-inset-modify mathspace \hspace{} \length 1in; next-inset-toggle"
Separator
Item "Settings...|S" "next-inset-toggle"
End
# #
# InsetVSpace context menu # InsetVSpace context menu
# #

View File

@ -330,12 +330,17 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
break; break;
} }
InsetSpaceParams isp; InsetSpaceParams isp;
// The tests for isp.math might be disabled after a file format change
if (name == "normal") if (name == "normal")
isp.kind = InsetSpaceParams::NORMAL; isp.kind = InsetSpaceParams::NORMAL;
else if (name == "protected") else if (name == "protected")
isp.kind = InsetSpaceParams::PROTECTED; isp.kind = InsetSpaceParams::PROTECTED;
else if (name == "thin") else if (name == "thin")
isp.kind = InsetSpaceParams::THIN; isp.kind = InsetSpaceParams::THIN;
else if (isp.math && name == "med")
isp.kind = InsetSpaceParams::MEDIUM;
else if (isp.math && name == "thick")
isp.kind = InsetSpaceParams::THICK;
else if (name == "quad") else if (name == "quad")
isp.kind = InsetSpaceParams::QUAD; isp.kind = InsetSpaceParams::QUAD;
else if (name == "qquad") else if (name == "qquad")
@ -346,6 +351,10 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
isp.kind = InsetSpaceParams::ENSKIP; isp.kind = InsetSpaceParams::ENSKIP;
else if (name == "negthinspace") else if (name == "negthinspace")
isp.kind = InsetSpaceParams::NEGTHIN; isp.kind = InsetSpaceParams::NEGTHIN;
else if (isp.math && name == "negmedspace")
isp.kind = InsetSpaceParams::NEGMEDIUM;
else if (isp.math && name == "negthickspace")
isp.kind = InsetSpaceParams::NEGTHICK;
else if (name == "hfill") else if (name == "hfill")
isp.kind = InsetSpaceParams::HFILL; isp.kind = InsetSpaceParams::HFILL;
else if (name == "hfill*") else if (name == "hfill*")

View File

@ -35,9 +35,10 @@ using namespace std;
namespace lyx { namespace lyx {
namespace frontend { namespace frontend {
GuiHSpace::GuiHSpace(GuiView & lv) GuiHSpace::GuiHSpace(GuiView & lv, bool math)
: GuiDialog(lv, "space", qt_("Horizontal Space Settings")) : GuiDialog(lv, math ? "mathspace" : "space", qt_("Horizontal Space Settings"))
{ {
params_.math = math;
setupUi(this); setupUi(this);
connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK())); connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
@ -86,8 +87,23 @@ void GuiHSpace::change_adaptor()
} }
void GuiHSpace::setMath(bool custom)
{
valueLE->setEnabled(custom);
unitCO->setEnabled(custom);
fillPatternCO->setEnabled(false);
keepCB->setToolTip(qt_("Insert the spacing even after a line break"));
keepCB->setEnabled(false);
}
void GuiHSpace::enableWidgets(int selection) void GuiHSpace::enableWidgets(int selection)
{ {
if (params_.math) {
setMath(selection == 9);
changed();
return;
}
valueLE->setEnabled(selection == 7); valueLE->setEnabled(selection == 7);
unitCO->setEnabled(selection == 7); unitCO->setEnabled(selection == 7);
fillPatternCO->setEnabled(selection == 6); fillPatternCO->setEnabled(selection == 6);
@ -120,6 +136,33 @@ static void setWidgetsFromHSpace(InsetSpaceParams const & params,
QCheckBox * keep, QCheckBox * keep,
QComboBox * fillPattern) QComboBox * fillPattern)
{ {
spacing->clear();
if (params.math) {
spacing->addItem(qt_("Thin space"));
spacing->addItem(qt_("Medium space"));
spacing->addItem(qt_("Thick space"));
spacing->addItem(qt_("Negative thin space"));
spacing->addItem(qt_("Negative medium space"));
spacing->addItem(qt_("Negative thick space"));
spacing->addItem(qt_("Half Quad (0.5 em)"));
spacing->addItem(qt_("Quad (1 em)"));
spacing->addItem(qt_("Double Quad (2 em)"));
spacing->addItem(qt_("Custom"));
keep->setEnabled(false);
fillPattern->setEnabled(false);
} else {
spacing->addItem(qt_("Inter-word space"));
spacing->addItem(qt_("Thin space"));
spacing->addItem(qt_("Negative thin space"));
spacing->addItem(qt_("Half Quad (0.5 em)"));
spacing->addItem(qt_("Quad (1 em)"));
spacing->addItem(qt_("Double Quad (2 em)"));
spacing->addItem(qt_("Horizontal Fill"));
spacing->addItem(qt_("Custom"));
keep->setEnabled(true);
fillPattern->setEnabled(true);
}
int item = 0; int item = 0;
int pattern = 0; int pattern = 0;
bool protect = false; bool protect = false;
@ -129,64 +172,76 @@ static void setWidgetsFromHSpace(InsetSpaceParams const & params,
break; break;
case InsetSpaceParams::PROTECTED: case InsetSpaceParams::PROTECTED:
item = 0; item = 0;
protect = true; protect = !params.math;
break; break;
case InsetSpaceParams::THIN: case InsetSpaceParams::THIN:
item = params.math ? 0 : 1;
break;
case InsetSpaceParams::MEDIUM:
item = 1; item = 1;
break; break;
case InsetSpaceParams::THICK:
item = params.math ? 2 : 1;
break;
case InsetSpaceParams::NEGTHIN: case InsetSpaceParams::NEGTHIN:
item = 2; item = params.math ? 3 : 2;
break;
case InsetSpaceParams::NEGMEDIUM:
item = params.math ? 4 : 2;
break;
case InsetSpaceParams::NEGTHICK:
item = params.math ? 5 : 2;
break; break;
case InsetSpaceParams::ENSKIP: case InsetSpaceParams::ENSKIP:
item = 3; item = params.math ? 6 : 3;
break; break;
case InsetSpaceParams::ENSPACE: case InsetSpaceParams::ENSPACE:
item = 3; item = params.math ? 6 : 3;
protect = true; protect = !params.math;
break; break;
case InsetSpaceParams::QUAD: case InsetSpaceParams::QUAD:
item = 4; item = params.math ? 7 : 4;
break; break;
case InsetSpaceParams::QQUAD: case InsetSpaceParams::QQUAD:
item = 5; item = params.math ? 8 : 5;
break; break;
case InsetSpaceParams::HFILL: case InsetSpaceParams::HFILL:
item = 6; item = params.math ? 3 : 6;
break; break;
case InsetSpaceParams::HFILL_PROTECTED: case InsetSpaceParams::HFILL_PROTECTED:
item = 6; item = params.math ? 3 : 6;
protect = true; protect = !params.math;
break; break;
case InsetSpaceParams::DOTFILL: case InsetSpaceParams::DOTFILL:
item = 6; item = params.math ? 3 : 6;
pattern = 1; pattern = 1;
break; break;
case InsetSpaceParams::HRULEFILL: case InsetSpaceParams::HRULEFILL:
item = 6; item = params.math ? 3 : 6;
pattern = 2; pattern = 2;
break; break;
case InsetSpaceParams::LEFTARROWFILL: case InsetSpaceParams::LEFTARROWFILL:
item = 6; item = params.math ? 3 : 6;
pattern = 3; pattern = 3;
break; break;
case InsetSpaceParams::RIGHTARROWFILL: case InsetSpaceParams::RIGHTARROWFILL:
item = 6; item = params.math ? 3 : 6;
pattern = 4; pattern = 4;
break; break;
case InsetSpaceParams::UPBRACEFILL: case InsetSpaceParams::UPBRACEFILL:
item = 6; item = params.math ? 3 : 6;
pattern = 5; pattern = 5;
break; break;
case InsetSpaceParams::DOWNBRACEFILL: case InsetSpaceParams::DOWNBRACEFILL:
item = 6; item = params.math ? 3 : 6;
pattern = 6; pattern = 6;
break; break;
case InsetSpaceParams::CUSTOM: case InsetSpaceParams::CUSTOM:
item = 7; item = params.math ? 9 : 7;
break; break;
case InsetSpaceParams::CUSTOM_PROTECTED: case InsetSpaceParams::CUSTOM_PROTECTED:
item = 7; item = params.math ? 9 : 7;
protect = true; protect = !params.math;
break; break;
} }
spacing->setCurrentIndex(item); spacing->setCurrentIndex(item);
@ -195,7 +250,7 @@ static void setWidgetsFromHSpace(InsetSpaceParams const & params,
Length::UNIT default_unit = Length::UNIT default_unit =
(lyxrc.default_papersize > 3) ? Length::CM : Length::IN; (lyxrc.default_papersize > 3) ? Length::CM : Length::IN;
if (item == 7) if (item == (params.math ? 9 : 7))
lengthToWidgets(value, unit, params.length, default_unit); lengthToWidgets(value, unit, params.length, default_unit);
else else
lengthToWidgets(value, unit, "", default_unit); lengthToWidgets(value, unit, "", default_unit);
@ -203,9 +258,28 @@ static void setWidgetsFromHSpace(InsetSpaceParams const & params,
static InsetSpaceParams setHSpaceFromWidgets(int spacing, static InsetSpaceParams setHSpaceFromWidgets(int spacing,
QLineEdit * value, LengthCombo * unit, bool keep, int fill) QLineEdit * value, LengthCombo * unit, bool keep, int fill, bool math)
{ {
InsetSpaceParams params; InsetSpaceParams params(math);
if (math) {
switch (spacing) {
case 0: params.kind = InsetSpaceParams::THIN; break;
case 1: params.kind = InsetSpaceParams::MEDIUM; break;
case 2: params.kind = InsetSpaceParams::THICK; break;
case 3: params.kind = InsetSpaceParams::NEGTHIN; break;
case 4: params.kind = InsetSpaceParams::NEGMEDIUM; break;
case 5: params.kind = InsetSpaceParams::NEGTHICK; break;
case 6: params.kind = InsetSpaceParams::ENSKIP; break;
case 7: params.kind = InsetSpaceParams::QUAD; break;
case 8: params.kind = InsetSpaceParams::QQUAD; break;
case 9:
params.kind = InsetSpaceParams::CUSTOM;
params.length = Length(widgetsToLength(value, unit));
break;
}
return params;
}
switch (spacing) { switch (spacing) {
case 0: case 0:
if (keep) if (keep)
@ -265,7 +339,7 @@ void GuiHSpace::applyView()
{ {
params_ = setHSpaceFromWidgets(spacingCO->currentIndex(), params_ = setHSpaceFromWidgets(spacingCO->currentIndex(),
valueLE, unitCO, keepCB->isChecked(), valueLE, unitCO, keepCB->isChecked(),
fillPatternCO->currentIndex()); fillPatternCO->currentIndex(), params_.math);
} }
@ -279,7 +353,11 @@ void GuiHSpace::updateContents()
bool GuiHSpace::initialiseParams(string const & data) bool GuiHSpace::initialiseParams(string const & data)
{ {
bool const math = params_.math;
InsetSpace::string2params(data, params_); InsetSpace::string2params(data, params_);
params_.math = math;
if (params_.math)
setMath(params_.kind == InsetSpaceParams::CUSTOM);
setButtonsValid(true); setButtonsValid(true);
return true; return true;
} }
@ -287,7 +365,7 @@ bool GuiHSpace::initialiseParams(string const & data)
void GuiHSpace::clearParams() void GuiHSpace::clearParams()
{ {
params_ = InsetSpaceParams(); params_ = InsetSpaceParams(params_.math);
} }
@ -299,11 +377,15 @@ void GuiHSpace::dispatchParams()
bool GuiHSpace::isValid() bool GuiHSpace::isValid()
{ {
return spacingCO->currentIndex() != 7 || !valueLE->text().isEmpty(); return spacingCO->currentIndex() != (params_.math ? 9 : 7)
|| !valueLE->text().isEmpty();
} }
Dialog * createGuiHSpace(GuiView & lv) { return new GuiHSpace(lv); } Dialog * createGuiMathHSpace(GuiView & lv) { return new GuiHSpace(lv, true); }
Dialog * createGuiTextHSpace(GuiView & lv) { return new GuiHSpace(lv, false); }
} // namespace frontend } // namespace frontend

View File

@ -24,7 +24,7 @@ class GuiHSpace : public GuiDialog, public Ui::HSpaceUi
Q_OBJECT Q_OBJECT
public: public:
GuiHSpace(GuiView & lv); GuiHSpace(GuiView & lv, bool math);
private Q_SLOTS: private Q_SLOTS:
/// ///
@ -35,6 +35,8 @@ private Q_SLOTS:
void patternChanged(); void patternChanged();
private: private:
///
void setMath(bool custom);
/// Apply from dialog /// Apply from dialog
void applyView(); void applyView();
/// Update the dialog /// Update the dialog

View File

@ -2068,8 +2068,9 @@ bool GuiView::dispatch(FuncRequest const & cmd)
Inset * inset = getOpenInset(name); Inset * inset = getOpenInset(name);
if (inset) { if (inset) {
// put cursor in front of inset. // put cursor in front of inset.
if (!view()->setCursorFromInset(inset)) if (!view()->setCursorFromInset(inset)) {
LASSERT(false, break); LASSERT(false, break);
}
// useful if we are called from a dialog. // useful if we are called from a dialog.
view()->cursor().beginUndoGroup(); view()->cursor().beginUndoGroup();
@ -2289,7 +2290,7 @@ char const * const dialognames[] = {
"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character", "aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character",
"citation", "document", "errorlist", "ert", "external", "file", "citation", "document", "errorlist", "ert", "external", "file",
"findreplace", "float", "graphics", "include", "index", "info", "nomenclature", "label", "log", "findreplace", "float", "graphics", "include", "index", "info", "nomenclature", "label", "log",
"mathdelimiter", "mathmatrix", "note", "paragraph", "prefs", "print", "mathdelimiter", "mathmatrix", "mathspace", "note", "paragraph", "prefs", "print",
"ref", "sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate", "ref", "sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate",
#ifdef HAVE_LIBAIKSAURUS #ifdef HAVE_LIBAIKSAURUS
@ -2470,12 +2471,12 @@ Dialog * createGuiERT(GuiView & lv);
Dialog * createGuiExternal(GuiView & lv); Dialog * createGuiExternal(GuiView & lv);
Dialog * createGuiFloat(GuiView & lv); Dialog * createGuiFloat(GuiView & lv);
Dialog * createGuiGraphics(GuiView & lv); Dialog * createGuiGraphics(GuiView & lv);
Dialog * createGuiHSpace(GuiView & lv);
Dialog * createGuiInclude(GuiView & lv); Dialog * createGuiInclude(GuiView & lv);
Dialog * createGuiInfo(GuiView & lv); Dialog * createGuiInfo(GuiView & lv);
Dialog * createGuiLabel(GuiView & lv); Dialog * createGuiLabel(GuiView & lv);
Dialog * createGuiListings(GuiView & lv); Dialog * createGuiListings(GuiView & lv);
Dialog * createGuiLog(GuiView & lv); Dialog * createGuiLog(GuiView & lv);
Dialog * createGuiMathHSpace(GuiView & lv);
Dialog * createGuiMathMatrix(GuiView & lv); Dialog * createGuiMathMatrix(GuiView & lv);
Dialog * createGuiNomenclature(GuiView & lv); Dialog * createGuiNomenclature(GuiView & lv);
Dialog * createGuiNote(GuiView & lv); Dialog * createGuiNote(GuiView & lv);
@ -2492,6 +2493,7 @@ Dialog * createGuiSymbols(GuiView & lv);
Dialog * createGuiTabularCreate(GuiView & lv); Dialog * createGuiTabularCreate(GuiView & lv);
Dialog * createGuiTabular(GuiView & lv); Dialog * createGuiTabular(GuiView & lv);
Dialog * createGuiTexInfo(GuiView & lv); Dialog * createGuiTexInfo(GuiView & lv);
Dialog * createGuiTextHSpace(GuiView & lv);
Dialog * createGuiToc(GuiView & lv); Dialog * createGuiToc(GuiView & lv);
Dialog * createGuiThesaurus(GuiView & lv); Dialog * createGuiThesaurus(GuiView & lv);
Dialog * createGuiHyperlink(GuiView & lv); Dialog * createGuiHyperlink(GuiView & lv);
@ -2552,6 +2554,8 @@ Dialog * GuiView::build(string const & name)
return createGuiViewSource(*this); return createGuiViewSource(*this);
if (name == "mathdelimiter") if (name == "mathdelimiter")
return createGuiDelimiter(*this); return createGuiDelimiter(*this);
if (name == "mathspace")
return createGuiMathHSpace(*this);
if (name == "mathmatrix") if (name == "mathmatrix")
return createGuiMathMatrix(*this); return createGuiMathMatrix(*this);
if (name == "note") if (name == "note")
@ -2567,7 +2571,7 @@ Dialog * GuiView::build(string const & name)
if (name == "sendto") if (name == "sendto")
return createGuiSendTo(*this); return createGuiSendTo(*this);
if (name == "space") if (name == "space")
return createGuiHSpace(*this); return createGuiTextHSpace(*this);
if (name == "spellchecker") if (name == "spellchecker")
return createGuiSpellchecker(*this); return createGuiSpellchecker(*this);
if (name == "symbols") if (name == "symbols")

View File

@ -79,46 +79,6 @@
<property name="toolTip" > <property name="toolTip" >
<string>Supported spacing types</string> <string>Supported spacing types</string>
</property> </property>
<item>
<property name="text" >
<string>Inter-word space</string>
</property>
</item>
<item>
<property name="text" >
<string>Thin space</string>
</property>
</item>
<item>
<property name="text" >
<string>Negative thin space</string>
</property>
</item>
<item>
<property name="text" >
<string>Half Quad (0.5 em)</string>
</property>
</item>
<item>
<property name="text" >
<string>Quad (1 em)</string>
</property>
</item>
<item>
<property name="text" >
<string>Double Quad (2 em)</string>
</property>
</item>
<item>
<property name="text" >
<string>Horizontal Fill</string>
</property>
</item>
<item>
<property name="text" >
<string>Custom</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="1" column="0" > <item row="1" column="0" >

View File

@ -20,6 +20,7 @@
#include "Dimension.h" #include "Dimension.h"
#include "FuncRequest.h" #include "FuncRequest.h"
#include "FuncStatus.h" #include "FuncStatus.h"
#include "LaTeXFeatures.h"
#include "Length.h" #include "Length.h"
#include "Lexer.h" #include "Lexer.h"
#include "MetricsInfo.h" #include "MetricsInfo.h"
@ -28,6 +29,7 @@
#include "support/debug.h" #include "support/debug.h"
#include "support/docstream.h" #include "support/docstream.h"
#include "support/gettext.h" #include "support/gettext.h"
#include "support/lassert.h"
#include "support/lstrings.h" #include "support/lstrings.h"
#include "frontends/Application.h" #include "frontends/Application.h"
@ -75,6 +77,12 @@ docstring InsetSpace::toolTip(BufferView const &, int, int) const
case InsetSpaceParams::THIN: case InsetSpaceParams::THIN:
message = _("Thin Space"); message = _("Thin Space");
break; break;
case InsetSpaceParams::MEDIUM:
message = _("Medium Space");
break;
case InsetSpaceParams::THICK:
message = _("Thick Space");
break;
case InsetSpaceParams::QUAD: case InsetSpaceParams::QUAD:
message = _("Quad Space"); message = _("Quad Space");
break; break;
@ -90,6 +98,12 @@ docstring InsetSpace::toolTip(BufferView const &, int, int) const
case InsetSpaceParams::NEGTHIN: case InsetSpaceParams::NEGTHIN:
message = _("Negative Thin Space"); message = _("Negative Thin Space");
break; break;
case InsetSpaceParams::NEGMEDIUM:
message = _("Negative Mwedium Space");
break;
case InsetSpaceParams::NEGTHICK:
message = _("Negative Thick Space");
break;
case InsetSpaceParams::HFILL: case InsetSpaceParams::HFILL:
message = _("Horizontal Fill"); message = _("Horizontal Fill");
break; break;
@ -131,10 +145,13 @@ void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
{ {
switch (cmd.action) { switch (cmd.action) {
case LFUN_INSET_MODIFY: { case LFUN_INSET_MODIFY:
string2params(to_utf8(cmd.argument()), params_); string2params(to_utf8(cmd.argument()), params_);
break; break;
}
case LFUN_INSET_DIALOG_UPDATE:
cur.bv().updateDialog("space", params2string(params()));
break;
case LFUN_MOUSE_RELEASE: case LFUN_MOUSE_RELEASE:
if (!cur.selection() && cmd.button() == mouse_button::button1) if (!cur.selection() && cmd.button() == mouse_button::button1)
@ -159,6 +176,8 @@ bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
string2params(to_utf8(cmd.argument()), params); string2params(to_utf8(cmd.argument()), params);
status.setOnOff(params_.kind == params.kind); status.setOnOff(params_.kind == params.kind);
} }
// fall through
case LFUN_INSET_DIALOG_UPDATE:
status.setEnabled(true); status.setEnabled(true);
return true; return true;
default: default:
@ -196,6 +215,14 @@ void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
case InsetSpaceParams::NEGTHIN: case InsetSpaceParams::NEGTHIN:
dim.wid = fm.width(char_type('M')) / 6; dim.wid = fm.width(char_type('M')) / 6;
break; break;
case InsetSpaceParams::MEDIUM:
case InsetSpaceParams::NEGMEDIUM:
dim.wid = fm.width(char_type('M')) / 4;
break;
case InsetSpaceParams::THICK:
case InsetSpaceParams::NEGTHICK:
dim.wid = fm.width(char_type('M')) / 2;
break;
case InsetSpaceParams::PROTECTED: case InsetSpaceParams::PROTECTED:
case InsetSpaceParams::NORMAL: case InsetSpaceParams::NORMAL:
dim.wid = fm.width(char_type(' ')); dim.wid = fm.width(char_type(' '));
@ -269,12 +296,12 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const
if (params_.kind == InsetSpaceParams::HFILL) { if (params_.kind == InsetSpaceParams::HFILL) {
pi.pain.line(x0, y1, x0, y0, Color_added_space); pi.pain.line(x0, y1, x0, y0, Color_added_space);
pi.pain.line(x0, y2 , x1, y2, Color_added_space, pi.pain.line(x0, y2, x1, y2, Color_added_space,
frontend::Painter::line_onoffdash); frontend::Painter::line_onoffdash);
pi.pain.line(x1, y1, x1, y0, Color_added_space); pi.pain.line(x1, y1, x1, y0, Color_added_space);
} else if (params_.kind == InsetSpaceParams::HFILL_PROTECTED) { } else if (params_.kind == InsetSpaceParams::HFILL_PROTECTED) {
pi.pain.line(x0, y1, x0, y0, Color_latex); pi.pain.line(x0, y1, x0, y0, Color_latex);
pi.pain.line(x0, y2 , x1, y2, Color_latex, pi.pain.line(x0, y2, x1, y2, Color_latex,
frontend::Painter::line_onoffdash); frontend::Painter::line_onoffdash);
pi.pain.line(x1, y1, x1, y0, Color_latex); pi.pain.line(x1, y1, x1, y0, Color_latex);
} else if (params_.kind == InsetSpaceParams::DOTFILL) { } else if (params_.kind == InsetSpaceParams::DOTFILL) {
@ -344,6 +371,8 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const
if (params_.kind == InsetSpaceParams::PROTECTED || if (params_.kind == InsetSpaceParams::PROTECTED ||
params_.kind == InsetSpaceParams::ENSPACE || params_.kind == InsetSpaceParams::ENSPACE ||
params_.kind == InsetSpaceParams::NEGTHIN || params_.kind == InsetSpaceParams::NEGTHIN ||
params_.kind == InsetSpaceParams::NEGMEDIUM ||
params_.kind == InsetSpaceParams::NEGTHICK ||
params_.kind == InsetSpaceParams::CUSTOM_PROTECTED) params_.kind == InsetSpaceParams::CUSTOM_PROTECTED)
pi.pain.lines(xp, yp, 4, Color_latex); pi.pain.lines(xp, yp, 4, Color_latex);
else else
@ -364,6 +393,12 @@ void InsetSpaceParams::write(ostream & os) const
case InsetSpaceParams::THIN: case InsetSpaceParams::THIN:
os << "\\thinspace{}"; os << "\\thinspace{}";
break; break;
case InsetSpaceParams::MEDIUM:
os << "\\medspace{}";
break;
case InsetSpaceParams::THICK:
os << "\\thickspace{}";
break;
case InsetSpaceParams::QUAD: case InsetSpaceParams::QUAD:
os << "\\quad{}"; os << "\\quad{}";
break; break;
@ -379,6 +414,12 @@ void InsetSpaceParams::write(ostream & os) const
case InsetSpaceParams::NEGTHIN: case InsetSpaceParams::NEGTHIN:
os << "\\negthinspace{}"; os << "\\negthinspace{}";
break; break;
case InsetSpaceParams::NEGMEDIUM:
os << "\\negmedspace{}";
break;
case InsetSpaceParams::NEGTHICK:
os << "\\negthickspace{}";
break;
case InsetSpaceParams::HFILL: case InsetSpaceParams::HFILL:
os << "\\hfill{}"; os << "\\hfill{}";
break; break;
@ -422,12 +463,17 @@ void InsetSpaceParams::read(Lexer & lex)
string command; string command;
lex >> command; lex >> command;
// The tests for math might be disabled after a file format change
if (command == "\\space{}") if (command == "\\space{}")
kind = InsetSpaceParams::NORMAL; kind = InsetSpaceParams::NORMAL;
else if (command == "~") else if (command == "~")
kind = InsetSpaceParams::PROTECTED; kind = InsetSpaceParams::PROTECTED;
else if (command == "\\thinspace{}") else if (command == "\\thinspace{}")
kind = InsetSpaceParams::THIN; kind = InsetSpaceParams::THIN;
else if (math && command == "\\medspace{}")
kind = InsetSpaceParams::MEDIUM;
else if (math && command == "\\thickspace{}")
kind = InsetSpaceParams::THICK;
else if (command == "\\quad{}") else if (command == "\\quad{}")
kind = InsetSpaceParams::QUAD; kind = InsetSpaceParams::QUAD;
else if (command == "\\qquad{}") else if (command == "\\qquad{}")
@ -438,6 +484,10 @@ void InsetSpaceParams::read(Lexer & lex)
kind = InsetSpaceParams::ENSKIP; kind = InsetSpaceParams::ENSKIP;
else if (command == "\\negthinspace{}") else if (command == "\\negthinspace{}")
kind = InsetSpaceParams::NEGTHIN; kind = InsetSpaceParams::NEGTHIN;
else if (math && command == "\\negmedspace{}")
kind = InsetSpaceParams::NEGMEDIUM;
else if (math && command == "\\negthickspace{}")
kind = InsetSpaceParams::NEGTHICK;
else if (command == "\\hfill{}") else if (command == "\\hfill{}")
kind = InsetSpaceParams::HFILL; kind = InsetSpaceParams::HFILL;
else if (command == "\\hspace*{\\fill}") else if (command == "\\hspace*{\\fill}")
@ -492,6 +542,12 @@ int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const
case InsetSpaceParams::THIN: case InsetSpaceParams::THIN:
os << (runparams.free_spacing ? " " : "\\,"); os << (runparams.free_spacing ? " " : "\\,");
break; break;
case InsetSpaceParams::MEDIUM:
os << (runparams.free_spacing ? " " : "\\:");
break;
case InsetSpaceParams::THICK:
os << (runparams.free_spacing ? " " : "\\;");
break;
case InsetSpaceParams::QUAD: case InsetSpaceParams::QUAD:
os << (runparams.free_spacing ? " " : "\\quad{}"); os << (runparams.free_spacing ? " " : "\\quad{}");
break; break;
@ -507,6 +563,12 @@ int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const
case InsetSpaceParams::NEGTHIN: case InsetSpaceParams::NEGTHIN:
os << (runparams.free_spacing ? " " : "\\negthinspace{}"); os << (runparams.free_spacing ? " " : "\\negthinspace{}");
break; break;
case InsetSpaceParams::NEGMEDIUM:
os << (runparams.free_spacing ? " " : "\\negmedspace{}");
break;
case InsetSpaceParams::NEGTHICK:
os << (runparams.free_spacing ? " " : "\\negthickspace{}");
break;
case InsetSpaceParams::HFILL: case InsetSpaceParams::HFILL:
os << (runparams.free_spacing ? " " : "\\hfill{}"); os << (runparams.free_spacing ? " " : "\\hfill{}");
break; break;
@ -592,7 +654,11 @@ int InsetSpace::docbook(odocstream & os, OutputParams const &) const
case InsetSpaceParams::PROTECTED: case InsetSpaceParams::PROTECTED:
case InsetSpaceParams::ENSPACE: case InsetSpaceParams::ENSPACE:
case InsetSpaceParams::THIN: case InsetSpaceParams::THIN:
case InsetSpaceParams::MEDIUM:
case InsetSpaceParams::THICK:
case InsetSpaceParams::NEGTHIN: case InsetSpaceParams::NEGTHIN:
case InsetSpaceParams::NEGMEDIUM:
case InsetSpaceParams::NEGTHICK:
os << "&nbsp;"; os << "&nbsp;";
break; break;
case InsetSpaceParams::HFILL: case InsetSpaceParams::HFILL:
@ -617,6 +683,14 @@ int InsetSpace::docbook(odocstream & os, OutputParams const &) const
} }
void InsetSpace::validate(LaTeXFeatures & features) const
{
if (params_.kind == InsetSpaceParams::NEGMEDIUM ||
params_.kind == InsetSpaceParams::NEGTHICK)
features.require("amsmath");
}
void InsetSpace::tocString(odocstream & os) const void InsetSpace::tocString(odocstream & os) const
{ {
plaintext(os, OutputParams(0)); plaintext(os, OutputParams(0));
@ -652,7 +726,14 @@ void InsetSpace::string2params(string const & in, InsetSpaceParams & params)
Lexer lex; Lexer lex;
lex.setStream(data); lex.setStream(data);
lex.setContext("InsetSpace::string2params"); lex.setContext("InsetSpace::string2params");
lex >> "space"; lex.next();
string const name = lex.getString();
if (name == "mathspace")
params.math = true;
else {
params.math = false;
LASSERT(name == "space", /**/);
}
// There are cases, such as when we are called via getStatus() from // There are cases, such as when we are called via getStatus() from
// Dialog::canApply(), where we are just called with "space" rather // Dialog::canApply(), where we are just called with "space" rather
@ -665,6 +746,8 @@ void InsetSpace::string2params(string const & in, InsetSpaceParams & params)
string InsetSpace::params2string(InsetSpaceParams const & params) string InsetSpace::params2string(InsetSpaceParams const & params)
{ {
ostringstream data; ostringstream data;
if (params.math)
data << "math";
data << "space" << ' '; data << "space" << ' ';
params.write(data); params.write(data);
return data.str(); return data.str();

View File

@ -33,16 +33,24 @@ public:
PROTECTED, PROTECTED,
/// Thin space ('\,') /// Thin space ('\,')
THIN, THIN,
/// Medium space ('\:')
MEDIUM,
/// Thick space ('\;')
THICK,
/// \quad (1em) /// \quad (1em)
QUAD, QUAD,
/// \qquad (2em) /// \qquad (2em)
QQUAD, QQUAD,
/// \enspace (0.5em unbreakable) /// \enskip (0.5em unbreakable)
ENSPACE, ENSPACE,
/// \enspace (0.5em breakable) /// \enspace (0.5em breakable)
ENSKIP, ENSKIP,
/// Negative thin space ('\negthinspace') /// Negative thin space ('\negthinspace')
NEGTHIN, NEGTHIN,
/// Negative medium space ('\negmedspace')
NEGMEDIUM,
/// Negative thick space ('\negthickspace')
NEGTHICK,
/// rubber length /// rubber length
HFILL, HFILL,
/// \hspace*{\fill} /// \hspace*{\fill}
@ -65,7 +73,7 @@ public:
CUSTOM_PROTECTED CUSTOM_PROTECTED
}; };
/// ///
InsetSpaceParams() : kind(NORMAL), length(Length()) {} InsetSpaceParams(bool m = false) : kind(NORMAL), math(m) {}
/// ///
void write(std::ostream & os) const; void write(std::ostream & os) const;
/// ///
@ -74,6 +82,11 @@ public:
Kind kind; Kind kind;
/// ///
Length length; Length length;
/**
* Whether these params are to be used in mathed.
* This determines the set of valid kinds.
*/
bool math;
}; };
@ -99,7 +112,6 @@ public:
/// ///
Length length() const; Length length() const;
private:
/// ///
docstring toolTip(BufferView const & bv, int x, int y) const; docstring toolTip(BufferView const & bv, int x, int y) const;
/// ///
@ -116,6 +128,8 @@ private:
int plaintext(odocstream &, OutputParams const &) const; int plaintext(odocstream &, OutputParams const &) const;
/// ///
int docbook(odocstream &, OutputParams const &) const; int docbook(odocstream &, OutputParams const &) const;
///
void validate(LaTeXFeatures & features) const;
/// the string that is passed to the TOC /// the string that is passed to the TOC
void tocString(odocstream &) const; void tocString(odocstream &) const;
/// ///
@ -137,13 +151,16 @@ private:
bool isSpace() const { return true; } bool isSpace() const { return true; }
/// ///
docstring contextMenu(BufferView const & bv, int x, int y) const; docstring contextMenu(BufferView const & bv, int x, int y) const;
protected:
/// ///
Inset * clone() const { return new InsetSpace(*this); } Inset * clone() const { return new InsetSpace(*this); }
/// ///
void doDispatch(Cursor & cur, FuncRequest & cmd); void doDispatch(Cursor & cur, FuncRequest & cmd);
public:
/// ///
bool getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus &) const; bool getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus &) const;
private:
/// ///
InsetSpaceParams params_; InsetSpaceParams params_;
}; };

View File

@ -840,7 +840,6 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
break; break;
//case LFUN_SERVER_GET_XY: //case LFUN_SERVER_GET_XY:
// sprintf(dispatch_buffer, "%d %d",);
// break; // break;
case LFUN_SERVER_SET_XY: { case LFUN_SERVER_SET_XY: {
@ -1055,15 +1054,15 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_SPACE_INSERT: case LFUN_SPACE_INSERT:
cur.recordUndoSelection(); cur.recordUndoSelection();
cur.insert(MathAtom(new InsetMathSpace(from_ascii(",")))); cur.insert(MathAtom(new InsetMathSpace));
break; break;
case LFUN_MATH_SPACE: case LFUN_MATH_SPACE:
cur.recordUndoSelection(); cur.recordUndoSelection();
if (cmd.argument().empty()) if (cmd.argument().empty())
cur.insert(MathAtom(new InsetMathSpace(from_ascii(",")))); cur.insert(MathAtom(new InsetMathSpace));
else else
cur.insert(MathAtom(new InsetMathSpace(cmd.argument()))); cur.insert(MathAtom(new InsetMathSpace(to_utf8(cmd.argument()), "")));
break; break;
case LFUN_ERT_INSERT: case LFUN_ERT_INSERT:
@ -1131,6 +1130,9 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
if (name == "ref") { if (name == "ref") {
InsetMathRef tmp(name); InsetMathRef tmp(name);
data = tmp.createDialogStr(to_utf8(name)); data = tmp.createDialogStr(to_utf8(name));
} else if (name == "mathspace") {
InsetMathSpace tmp;
data = tmp.createDialogStr();
} }
cur.bv().showDialog(to_utf8(name), data); cur.bv().showDialog(to_utf8(name), data);
break; break;
@ -1274,7 +1276,7 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
// getStatus is not called with a valid reference and the // getStatus is not called with a valid reference and the
// dialog would not be applyable. // dialog would not be applyable.
string const name = cmd.getArg(0); string const name = cmd.getArg(0);
flag.setEnabled(name == "ref"); flag.setEnabled(name == "ref" || name == "mathspace");
break; break;
} }

View File

@ -12,63 +12,101 @@
#include "InsetMathSpace.h" #include "InsetMathSpace.h"
#include "MathData.h" #include "MathData.h"
#include "MathFactory.h"
#include "MathStream.h" #include "MathStream.h"
#include "MathSupport.h"
#include "BufferView.h"
#include "Cursor.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LaTeXFeatures.h" #include "LaTeXFeatures.h"
#include "insets/InsetSpace.h"
#include "frontends/Application.h"
#include "frontends/Painter.h" #include "frontends/Painter.h"
#include "support/lassert.h"
using namespace std; using namespace std;
namespace lyx { namespace lyx {
char const * latex_mathspace[] = {
"!", "negmedspace", "negthickspace", // negative space
",", ":", ";", "quad", "qquad", // positive space
"lyxnegspace", "lyxposspace" // LyX special ("unvisible space")
};
int const nSpace = sizeof(latex_mathspace)/sizeof(char *);
namespace { namespace {
int spaceToWidth(int space) struct SpaceInfo {
{ string name;
switch (space) { int width;
case 0: return 6; InsetSpaceParams::Kind kind;
case 1: return 8; bool negative;
case 2: return 10; bool visible;
case 3: return 6; bool custom;
case 4: return 8; };
case 5: return 10;
case 6: return 20; SpaceInfo space_info[] = {
case 7: return 40; // name width kind negative visible custom
case 8: return -2; {"!", 6, InsetSpaceParams::NEGTHIN, true, true, false},
case 9: return 2; {"negthinspace", 6, InsetSpaceParams::NEGTHIN, true, true, false},
default: return 6; {"negmedspace", 8, InsetSpaceParams::NEGMEDIUM, true, true, false},
} {"negthickspace", 10, InsetSpaceParams::NEGTHICK, true, true, false},
} {",", 6, InsetSpaceParams::THIN, false, true, false},
{"thinspace", 6, InsetSpaceParams::THIN, false, true, false},
{":", 8, InsetSpaceParams::MEDIUM, false, true, false},
{"medspace", 8, InsetSpaceParams::MEDIUM, false, true, false},
{";", 10, InsetSpaceParams::THICK, false, true, false},
{"thickspace", 10, InsetSpaceParams::THICK, false, true, false},
{"enskip", 10, InsetSpaceParams::ENSKIP, false, true, false},
{"quad", 20, InsetSpaceParams::QUAD, false, true, false},
{"qquad", 40, InsetSpaceParams::QQUAD, false, true, false},
{"lyxnegspace", -2, InsetSpaceParams::NEGTHIN, true, false, false},
{"lyxposspace", 2, InsetSpaceParams::THIN, false, false, false},
{"hspace", 0, InsetSpaceParams::CUSTOM, false, true, true},
};
int const nSpace = sizeof(space_info)/sizeof(SpaceInfo);
int const defaultSpace = 4;
} // anon namespace } // anon namespace
InsetMathSpace::InsetMathSpace(int sp) InsetMathSpace::InsetMathSpace()
: space_(sp) : space_(defaultSpace)
{ {
dim_.asc = 4;
dim_.des = 0;
dim_.wid = spaceToWidth(space_);
} }
InsetMathSpace::InsetMathSpace(docstring const & name) InsetMathSpace::InsetMathSpace(string const & name, string const & length)
: space_(1) : space_(defaultSpace)
{ {
dim_.asc = 4;
dim_.des = 0;
for (int i = 0; i < nSpace; ++i) for (int i = 0; i < nSpace; ++i)
if (latex_mathspace[i] == name) if (space_info[i].name == name) {
space_ = i; space_ = i;
dim_.wid = spaceToWidth(space_); break;
}
if (space_info[space_].custom) {
length_ = Length(length);
if (length_.zero() || length_.empty()) {
length_.value(1.0);
length_.unit(Length::EM);
}
}
}
InsetMathSpace::InsetMathSpace(Length const & length)
: space_(defaultSpace), length_(length)
{
for (int i = 0; i < nSpace; ++i)
if (space_info[i].name == "hspace") {
space_ = i;
break;
}
}
InsetMathSpace::~InsetMathSpace()
{
hideDialogs("mathspace", this);
} }
@ -78,9 +116,16 @@ Inset * InsetMathSpace::clone() const
} }
void InsetMathSpace::metrics(MetricsInfo &, Dimension & dim) const void InsetMathSpace::metrics(MetricsInfo & mi, Dimension & dim) const
{ {
dim = dim_; dim.asc = 4;
dim.des = 0;
if (space_info[space_].custom)
dim.wid = abs(length_.inPixels(
mi.base.textwidth,
mathed_char_width(mi.base.font, 'M')));
else
dim.wid = space_info[space_].width;
} }
@ -88,36 +133,45 @@ void InsetMathSpace::draw(PainterInfo & pi, int x, int y) const
{ {
// Sadly, HP-UX CC can't handle that kind of initialization. // Sadly, HP-UX CC can't handle that kind of initialization.
// XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}}; // XPoint p[4] = {{++x, y-3}, {x, y}, {x+width-2, y}, {x+width-2, y-3}};
if (space_ >= nSpace - 2) if (!space_info[space_].visible)
return; return;
Dimension const dim = dimension(*pi.base.bv);
int xp[4]; int xp[4];
int yp[4]; int yp[4];
int w = dim_.wid; int w = dim.wid;
xp[0] = ++x; yp[0] = y - 3; xp[0] = ++x; yp[0] = y - 3;
xp[1] = x; yp[1] = y; xp[1] = x; yp[1] = y;
xp[2] = x + w - 2; yp[2] = y; xp[2] = x + w - 2; yp[2] = y;
xp[3] = x + w - 2; yp[3] = y - 3; xp[3] = x + w - 2; yp[3] = y - 3;
pi.pain.lines(xp, yp, 4, (space_ < 3) ? Color_latex : Color_math); pi.pain.lines(xp, yp, 4,
space_info[space_].custom ?
Color_special :
(isNegative() ? Color_latex : Color_math));
} }
void InsetMathSpace::incSpace() void InsetMathSpace::incSpace()
{ {
space_ = (space_ + 1) % (nSpace - 2); int const oldwidth = space_info[space_].width;
dim_.wid = spaceToWidth(space_); do
space_ = (space_ + 1) % nSpace;
while ((space_info[space_].width == oldwidth && !space_info[space_].custom) ||
!space_info[space_].visible);
if (space_info[space_].custom && (length_.zero() || length_.empty())) {
length_.value(1.0);
length_.unit(Length::EM);
}
} }
void InsetMathSpace::validate(LaTeXFeatures & features) const void InsetMathSpace::validate(LaTeXFeatures & features) const
{ {
if (space_ >= 0 && space_< nSpace) { if (space_info[space_].name == "negmedspace" ||
if ((latex_mathspace[space_] == string("negmedspace")) space_info[space_].name == "negthickspace")
|| (latex_mathspace[space_] == string("negthickspace"))) features.require("amsmath");
features.require("amsmath");
}
} }
@ -146,12 +200,94 @@ void InsetMathSpace::normalize(NormalStream & os) const
void InsetMathSpace::write(WriteStream & os) const void InsetMathSpace::write(WriteStream & os) const
{ {
if (space_ >= 0 && space_ < nSpace) { // no MathEnsurer - all kinds work in text and math mode
MathEnsurer ensurer(os); os << '\\' << space_info[space_].name.c_str();
os << '\\' << latex_mathspace[space_]; if (space_info[space_].custom)
os << '{' << length_.asLatexString().c_str() << '}';
else
os.pendingSpace(true); os.pendingSpace(true);
}
string const InsetMathSpace::createDialogStr() const
{
LASSERT(space_info[space_].visible, /**/);
InsetSpaceParams isp(true);
isp.kind = space_info[space_].kind;
isp.length = length_;
return InsetSpace::params2string(isp);
}
docstring InsetMathSpace::contextMenu(BufferView const &, int, int) const
{
return from_ascii("context-mathspace");
}
bool InsetMathSpace::getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & status) const
{
switch (cmd.action) {
// we handle these
case LFUN_INSET_MODIFY:
case LFUN_INSET_DIALOG_UPDATE:
case LFUN_MOUSE_RELEASE:
case LFUN_MOUSE_PRESS:
case LFUN_MOUSE_MOTION:
status.setEnabled(true);
return true;
default:
bool retval = InsetMath::getStatus(cur, cmd, status);
return retval;
} }
} }
void InsetMathSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
{
switch (cmd.action) {
case LFUN_INSET_MODIFY:
if (cmd.getArg(0) == "mathspace") {
MathData ar;
if (createInsetMath_fromDialogStr(cmd.argument(), ar)) {
*this = *ar[0].nucleus()->asSpaceInset();
break;
}
}
cur.undispatched();
break;
case LFUN_INSET_DIALOG_UPDATE:
cur.bv().updateDialog("mathspace", createDialogStr());
break;
case LFUN_MOUSE_RELEASE:
if (cmd.button() == mouse_button::button1) {
string const data = createDialogStr();
cur.bv().showDialog("mathspace", data, this);
break;
}
cur.undispatched();
break;
case LFUN_MOUSE_PRESS:
case LFUN_MOUSE_MOTION:
// eat other mouse commands
break;
default:
InsetMath::doDispatch(cur, cmd);
break;
}
}
bool InsetMathSpace::isNegative() const
{
if (space_info[space_].custom)
return length_.value() < 0;
return space_info[space_].negative;
}
} // namespace lyx } // namespace lyx

View File

@ -13,6 +13,7 @@
#define MATH_SPACEINSET_H #define MATH_SPACEINSET_H
#include "InsetMath.h" #include "InsetMath.h"
#include "Length.h"
namespace lyx { namespace lyx {
@ -22,9 +23,13 @@ namespace lyx {
class InsetMathSpace : public InsetMath { class InsetMathSpace : public InsetMath {
public: public:
/// ///
explicit InsetMathSpace(int sp); explicit InsetMathSpace();
/// ///
explicit InsetMathSpace(docstring const & name); explicit InsetMathSpace(std::string const & name, std::string const & length);
///
explicit InsetMathSpace(Length const & length);
///
~InsetMathSpace();
/// ///
InsetMathSpace const * asSpaceInset() const { return this; } InsetMathSpace const * asSpaceInset() const { return this; }
/// ///
@ -48,12 +53,25 @@ public:
void octave(OctaveStream &) const; void octave(OctaveStream &) const;
/// ///
void write(WriteStream & os) const; void write(WriteStream & os) const;
/// generate something that will be understood by the Dialogs.
std::string const createDialogStr() const;
///
EDITABLE editable() const { return IS_EDITABLE; }
///
docstring contextMenu(BufferView const &, int, int) const;
///
bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
protected:
///
virtual void doDispatch(Cursor & cur, FuncRequest & cmd);
private: private:
virtual Inset * clone() const; virtual Inset * clone() const;
/// ///
int space_; bool isNegative() const;
/// ///
Dimension dim_; int space_;
/// amount of space for \\hspace
Length length_;
}; };

View File

@ -52,6 +52,7 @@
#include "MathSupport.h" #include "MathSupport.h"
#include "insets/InsetCommand.h" #include "insets/InsetCommand.h"
#include "insets/InsetSpace.h"
#include "support/debug.h" #include "support/debug.h"
#include "support/docstream.h" #include "support/docstream.h"
@ -61,7 +62,9 @@
#include "frontends/FontLoader.h" #include "frontends/FontLoader.h"
#include "Encoding.h"
#include "LyX.h" // use_gui #include "LyX.h" // use_gui
#include "OutputParams.h"
using namespace std; using namespace std;
using namespace lyx::support; using namespace lyx::support;
@ -317,7 +320,7 @@ MathAtom createInsetMath(docstring const & s)
if (inset == "decoration") if (inset == "decoration")
return MathAtom(new InsetMathDecoration(l)); return MathAtom(new InsetMathDecoration(l));
if (inset == "space") if (inset == "space")
return MathAtom(new InsetMathSpace(l->name)); return MathAtom(new InsetMathSpace(to_ascii(l->name), ""));
if (inset == "dots") if (inset == "dots")
return MathAtom(new InsetMathDots(l)); return MathAtom(new InsetMathDots(l));
if (inset == "mbox") if (inset == "mbox")
@ -477,13 +480,28 @@ bool createInsetMath_fromDialogStr(docstring const & str, MathData & ar)
docstring name; docstring name;
docstring body = split(str, name, ' '); docstring body = split(str, name, ' ');
if (name != "ref" ) if (name == "ref") {
InsetCommandParams icp(REF_CODE);
// FIXME UNICODE
InsetCommand::string2params("ref", to_utf8(str), icp);
mathed_parse_cell(ar, icp.getCommand());
} else if (name == "mathspace") {
InsetSpaceParams isp(true);
InsetSpace::string2params(to_utf8(str), isp);
InsetSpace is(isp);
odocstringstream os;
Encoding const * const ascii = encodings.fromLyXName("ascii");
OutputParams op(ascii);
is.latex(os, op);
mathed_parse_cell(ar, os.str());
if (ar.size() == 2) {
// remove "{}"
if (ar[1].nucleus()->asBraceInset())
ar.pop_back();
}
} else
return false; return false;
InsetCommandParams icp(REF_CODE);
// FIXME UNICODE
InsetCommand::string2params("ref", to_utf8(str), icp);
mathed_parse_cell(ar, icp.getCommand());
if (ar.size() != 1) if (ar.size() != 1)
return false; return false;

View File

@ -54,6 +54,7 @@ following hack as starting point to write some macros:
#include "InsetMathRef.h" #include "InsetMathRef.h"
#include "InsetMathRoot.h" #include "InsetMathRoot.h"
#include "InsetMathScript.h" #include "InsetMathScript.h"
#include "InsetMathSpace.h"
#include "InsetMathSplit.h" #include "InsetMathSplit.h"
#include "InsetMathSqrt.h" #include "InsetMathSqrt.h"
#include "InsetMathTabular.h" #include "InsetMathTabular.h"
@ -671,7 +672,7 @@ docstring Parser::parse_verbatim_option()
putback(); putback();
res += '{' + parse_verbatim_item() + '}'; res += '{' + parse_verbatim_item() + '}';
} else } else
res += t.asString(); res += t.asInput();
} }
} }
return res; return res;
@ -690,7 +691,7 @@ docstring Parser::parse_verbatim_item()
res += '{' + parse_verbatim_item() + '}'; res += '{' + parse_verbatim_item() + '}';
} }
else else
res += t.asString(); res += t.asInput();
} }
} }
return res; return res;
@ -1594,6 +1595,22 @@ bool Parser::parse1(InsetMathGrid & grid, unsigned flags,
parse(cell->back().nucleus()->cell(0), FLAG_ITEM, InsetMath::TEXT_MODE); parse(cell->back().nucleus()->cell(0), FLAG_ITEM, InsetMath::TEXT_MODE);
} }
else if (t.cs() == "hspace" && nextToken().character() != '*') {
docstring const name = t.cs();
docstring const arg = parse_verbatim_item();
Length length;
if (isValidLength(to_utf8(arg), &length))
cell->push_back(MathAtom(new InsetMathSpace(length)));
else {
// Since the Length class cannot use length variables
// we must not create an InsetMathSpace.
cell->push_back(MathAtom(new MathMacro(name)));
MathData ar;
mathed_parse_cell(ar, '{' + arg + '}');
cell->append(ar);
}
}
#if 0 #if 0
else if (t.cs() == "infer") { else if (t.cs() == "infer") {
MathData ar; MathData ar;