*** File Format Change: UI and enhancement for InsetSpace ***

* src/insets/InsetSpace.{cpp,h}:
	- merge in HFill inset, add support for dotfill, hrulefill,
	  hspace and hspace*
* src/insets/InsetHFill.{cpp,h}:
	- remove

* src/frontends/qt4/GuiHSpace.{cpp,h}:
* src/frontends/qt4/ui/HSpaceUi.ui:
* src/frontends/qt4/GuiView:
	- new GUI for Space insets.

* src/insets/Inset.{cpp,h}:
* src/insets/InsetCode.h:
* src/insets/InsetCollapsable.cpp:
* src/insets/InsetCommandParams.cpp:
	- remove HFILL_CODE and LFUN_HFILL_INSERT, add SPACE_CODE where necessary,
	  new Inset member isStretchableSpace() to indicate HFill and friends.

* Buffer.cpp: 
	- increase format to 319
* lib/lyx2lyx/LyX.py:
* lib/lyx2lyx/lyx_1_6.py:
	- conversion/reversion routines
* development/FORMAT:
	- document file format change

* src/Makefile.am:
* src/frontends/qt4/Makefile.am:
* development/scons/scons_manifest.py:
	- deal with UI changes.

* src/LyXAction.cpp:
	- remove LFUN_HFILL_INSERT

* src/LyXFunc.cpp:
	- handle space dialog.

* src/factory.cpp:
* src/Paragraph.cpp (isHFill):
* src/Text.cpp:
* src/Text3.cpp:
* src/TextMetrics.cpp:
	- adapt to changes

* lib/ui/classic.ui:
* lib/ui/stdmenus.ui:
	- add HSpace dialog, remove HFill.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23787 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Spitzmüller 2008-03-17 09:23:43 +00:00
parent e921847e12
commit f2e8cd3cd9
29 changed files with 1223 additions and 325 deletions

View File

@ -1,6 +1,9 @@
LyX file-format changes
-----------------------
2008-03-10 Jürgen Spitzmüller <j.spitzmueller@gmx.de>
* Format incremented to 319: hspace and extended hfill support.
2008-03-09 Bo Peng <ben.bob@gmail.com>
* Format incremented to 318: add \extra_embedded_files to buffer params

View File

@ -736,6 +736,7 @@ src_frontends_qt4_header_files = Split('''
GuiFontLoader.h
GuiGraphics.h
GuiGraphicsUi.h
GuiHSpace.h
GuiHyperlink.h
GuiIdListModel.h
GuiImage.h
@ -824,6 +825,7 @@ src_frontends_qt4_files = Split('''
GuiFontLoader.cpp
GuiFontMetrics.cpp
GuiGraphics.cpp
GuiHSpace.cpp
GuiHyperlink.cpp
GuiIdListModel.cpp
GuiImage.cpp
@ -907,6 +909,7 @@ src_frontends_qt4_ui_files = Split('''
FloatUi.ui
FontUi.ui
GraphicsUi.ui
HSpaceUi.ui
HyperlinkUi.ui
IncludeUi.ui
LabelUi.ui
@ -993,7 +996,6 @@ src_insets_header_files = Split('''
InsetFootlike.h
InsetGraphics.h
InsetGraphicsParams.h
InsetHFill.h
InsetHyperlink.h
InsetInclude.h
InsetIndex.h
@ -1050,7 +1052,6 @@ src_insets_files = Split('''
InsetFootlike.cpp
InsetGraphics.cpp
InsetGraphicsParams.cpp
InsetHFill.cpp
InsetHyperlink.cpp
InsetInclude.cpp
InsetIndex.cpp

View File

@ -80,7 +80,7 @@ format_relation = [("0_06", [200], minor_versions("0.6" , 4)),
("1_3", [221], minor_versions("1.3" , 7)),
("1_4", range(222,246), minor_versions("1.4" , 5)),
("1_5", range(246,277), minor_versions("1.5" , 2)),
("1_6", range(277,319), minor_versions("1.6" , 0))]
("1_6", range(277,320), minor_versions("1.6" , 0))]
def formats_list():

View File

@ -1363,7 +1363,7 @@ def revert_subfig(document):
def revert_wrapplacement(document):
"Revert placement options wrap floats (wrapfig)."
" Revert placement options wrap floats (wrapfig). "
i = 0
while True:
i = find_token(document.body, "lines", i)
@ -1381,13 +1381,86 @@ def revert_wrapplacement(document):
def remove_extra_embedded_files(document):
"Remove \extra_embedded_files from buffer params"
" Remove \extra_embedded_files from buffer params "
i = find_token(document.header, '\\extra_embedded_files', 0)
if i == -1:
document.warning("Malformed lyx document: Missing '\\extra_embedded_files'.")
return
document.header.pop(i)
def convert_spaceinset(document):
" Convert '\\InsetSpace foo' to '\\begin_inset Space foo\n\\end_inset' "
i = 0
while True:
i = find_token(document.body, "\\InsetSpace", i)
if i == -1:
return
document.body[i] = document.body[i].replace('\\InsetSpace', '\\begin_inset Space')
document.body[i] = document.body[i] + "\n\\end_inset"
def revert_spaceinset(document):
" Revert '\\begin_inset Space foo\n\\end_inset' to '\\InsetSpace foo' "
i = 0
while True:
i = find_token(document.body, "\\begin_inset Space", i)
if i == -1:
return
j = find_end_of_inset(document.body, i)
if j == -1:
document.warning("Malformed LyX document: Could not find end of space inset.")
continue
document.body[i] = document.body[i].replace('\\begin_inset Space', '\\InsetSpace')
del document.body[j]
def convert_hfill(document):
" Convert hfill to space inset "
i = 0
while True:
i = find_token(document.body, "\\hfill", i)
if i == -1:
return
document.body[i] = document.body[i].replace('\\hfill', '\n\\begin_inset Space \\hfill{}\n\\end_inset')
def revert_hfills(document):
' Revert \\hfill commands '
for i in range(len(document.body)):
document.body[i] = document.body[i].replace('\\InsetSpace \\hfill{}', '\\hfill')
document.body[i] = document.body[i].replace('\\InsetSpace \\dotfill{}', \
'\\begin_inset ERT\nstatus collapsed\n\n' \
'\\begin_layout Standard\n\n\n\\backslash\n' \
'dotfill{}\n\\end_layout\n\n\\end_inset\n\n')
document.body[i] = document.body[i].replace('\\InsetSpace \\hrulefill{}', \
'\\begin_inset ERT\nstatus collapsed\n\n' \
'\\begin_layout Standard\n\n\n\\backslash\n' \
'hrulefill{}\n\\end_layout\n\n\\end_inset\n\n')
def revert_hspace(document):
' Revert \\InsetSpace \\hspace{} to ERT '
i = 0
while True:
i = find_token(document.body, "\\InsetSpace \\hspace", i)
if i == -1:
return
length = get_value(document.body, '\\length', i+1)
if length == '':
document.warning("Malformed lyx document: Missing '\\length' in Space inset.")
return
del document.body[i+1]
document.body[i] = document.body[i].replace('\\InsetSpace \\hspace*{}', \
'\\begin_inset ERT\nstatus collapsed\n\n' \
'\\begin_layout Standard\n\n\n\\backslash\n' \
'hspace*{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
document.body[i] = document.body[i].replace('\\InsetSpace \\hspace{}', \
'\\begin_inset ERT\nstatus collapsed\n\n' \
'\\begin_layout Standard\n\n\n\\backslash\n' \
'hspace{' + length + '}\n\\end_layout\n\n\\end_inset\n\n')
##
# Conversion hub
#
@ -1435,9 +1508,11 @@ convert = [[277, [fix_wrong_tables]],
[316, [convert_subfig]],
[317, []],
[318, []],
[319, [convert_spaceinset, convert_hfill]]
]
revert = [[317, [remove_extra_embedded_files]],
revert = [[318, [revert_spaceinset, revert_hfills, revert_hspace]],
[317, [remove_extra_embedded_files]],
[316, [revert_wrapplacement]],
[315, [revert_subfig]],
[314, [revert_colsep]],

View File

@ -241,13 +241,13 @@ Menuset
Item "Symbols...|b" "dialog-show symbols"
Item "Superscript|S" "command-sequence math-mode on; math-superscript; math-insert \text;"
Item "Subscript|u" "command-sequence math-mode on; math-subscript; math-insert \text;"
Item "Horizontal Fill|H" "hfill-insert"
Item "Hyphenation Point|P" "hyphenation-point-insert"
Item "Protected Hyphen|y" "specialchar-insert nobreakdash"
Item "Ligature Break|k" "specialchar-insert ligature-break"
Item "Protected Space|r" "space-insert protected"
Item "Inter-word Space|w" "space-insert normal"
Item "Thin Space|T" "space-insert thin"
Item "Horizontal Space...|o" "dialog-show-new-inset space"
Item "Vertical Space..." "dialog-show-new-inset vspace"
Item "Line Break|L" "break-line"
Item "Ellipsis|i" "specialchar-insert dots"

View File

@ -366,7 +366,7 @@ Menuset
Item "Protected Space|P" "space-insert protected"
Item "Inter-word Space|w" "space-insert normal"
Item "Thin Space|T" "space-insert thin"
Item "Horizontal Fill|F" "hfill-insert"
Item "Horizontal Space...|o" "dialog-show-new-inset space"
Item "Horizontal Line|L" "line-insert"
Item "Vertical Space...|V" "dialog-show-new-inset vspace"
Separator

View File

@ -116,7 +116,7 @@ namespace os = support::os;
namespace {
int const LYX_FORMAT = 318;
int const LYX_FORMAT = 319;
typedef map<string, bool> DepClean;
typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;

View File

@ -273,13 +273,6 @@ void LyXAction::init()
{ LFUN_FLOAT_INSERT, "float-insert", Noop, Edit },
{ LFUN_FLOAT_WIDE_INSERT, "float-wide-insert", Noop, Edit },
{ LFUN_WRAP_INSERT, "wrap-insert", Noop, Edit },
/*!
* \var lyx::FuncCode lyx::LFUN_HFILL_INSERT
* \li Action: Inserts an hfill inset.
* \li Syntax: hfill-insert
* \endvar
*/
{ LFUN_HFILL_INSERT, "hfill-insert", Noop, Edit },
/*!
* \var lyx::FuncCode lyx::LFUN_OPTIONAL_INSERT
* \li Action: Inserts an optional-argument (short title) inset.

View File

@ -66,6 +66,7 @@
#include "insets/InsetGraphics.h"
#include "insets/InsetInclude.h"
#include "insets/InsetNote.h"
#include "insets/InsetSpace.h"
#include "insets/InsetTabular.h"
#include "insets/InsetVSpace.h"
#include "insets/InsetWrap.h"
@ -1235,6 +1236,11 @@ void LyXFunc::dispatch(FuncRequest const & cmd)
data = InsetNoteMailer::params2string(p);
break;
}
case SPACE_CODE: {
InsetSpaceParams p;
data = InsetSpaceMailer::params2string(p);
break;
}
case VSPACE_CODE: {
VSpace space;
data = InsetVSpaceMailer::params2string(space);

View File

@ -503,7 +503,6 @@ SOURCEFILESINSETS = \
insets/InsetFootlike.cpp \
insets/InsetGraphicsParams.cpp \
insets/InsetGraphics.cpp \
insets/InsetHFill.cpp \
insets/InsetHyperlink.cpp \
insets/InsetInclude.cpp \
insets/InsetIndex.cpp \
@ -559,7 +558,6 @@ HEADERFILESINSETS = \
insets/InsetFootlike.h \
insets/InsetGraphicsParams.h \
insets/InsetGraphics.h \
insets/InsetHFill.h \
insets/InsetHyperlink.h \
insets/InsetInclude.h \
insets/InsetIndex.h \

View File

@ -2239,7 +2239,8 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
bool Paragraph::isHfill(pos_type pos) const
{
Inset const * inset = getInset(pos);
return inset && inset->lyxCode() == HFILL_CODE;
return inset && (inset->lyxCode() == SPACE_CODE &&
inset->isStretchableSpace());
}

View File

@ -52,7 +52,6 @@
#include "insets/InsetText.h"
#include "insets/InsetBibitem.h"
#include "insets/InsetCaption.h"
#include "insets/InsetHFill.h"
#include "insets/InsetLine.h"
#include "insets/InsetNewline.h"
#include "insets/InsetNewpage.h"
@ -199,33 +198,12 @@ void readParToken(Buffer const & buf, Paragraph & par, Lexer & lex,
} else if (token == "\\color") {
lex.next();
setLyXColor(lex.getString(), font.fontInfo());
} else if (token == "\\InsetSpace" || token == "\\SpecialChar") {
// Insets don't make sense in a free-spacing context! ---Kayvan
if (par.isFreeSpacing()) {
if (token == "\\InsetSpace")
par.appendChar(' ', font, change);
else if (lex.isOK()) {
lex.next();
string const next_token = lex.getString();
if (next_token == "\\-")
par.appendChar('-', font, change);
else {
lex.printError("Token `$$Token' "
"is in free space "
"paragraph layout!");
}
}
} else {
} else if (token == "\\SpecialChar") {
auto_ptr<Inset> inset;
if (token == "\\SpecialChar" )
inset.reset(new InsetSpecialChar);
else
inset.reset(new InsetSpace);
inset.reset(new InsetSpecialChar);
inset->read(lex);
par.insertInset(par.size(), inset.release(),
font, change);
}
} else if (token == "\\backslash") {
par.appendChar('\\', font, change);
} else if (token == "\\linebreak") {
@ -240,8 +218,6 @@ void readParToken(Buffer const & buf, Paragraph & par, Lexer & lex,
auto_ptr<Inset> inset(new InsetTabular(buf));
inset->read(lex);
par.insertInset(par.size(), inset.release(), font, change);
} else if (token == "\\hfill") {
par.insertInset(par.size(), new InsetHFill, font, change);
} else if (token == "\\lyxline") {
par.insertInset(par.size(), new InsetLine, font, change);
} else if (token == "\\newpage") {

View File

@ -1408,7 +1408,6 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
case LFUN_INDEX_PRINT:
case LFUN_NOMENCL_PRINT:
case LFUN_TOC_INSERT:
case LFUN_HFILL_INSERT:
case LFUN_LINE_INSERT:
case LFUN_NEWPAGE_INSERT:
case LFUN_PAGEBREAK_INSERT:
@ -1864,6 +1863,8 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
code = NOTE_CODE;
else if (cmd.argument() == "ref")
code = REF_CODE;
else if (cmd.argument() == "space")
code = SPACE_CODE;
else if (cmd.argument() == "toc")
code = TOC_CODE;
else if (cmd.argument() == "vspace")
@ -1966,7 +1967,6 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
// always allow this, since we will inset a raw quote
// if an inset is not allowed.
break;
case LFUN_HFILL_INSERT:
case LFUN_SPECIALCHAR_INSERT:
code = SPECIALCHAR_CODE;
break;

View File

@ -626,7 +626,8 @@ void TextMetrics::computeRowMetrics(pit_type const pit,
InsetList::const_iterator iend = par.insetList().end();
for ( ; ii != iend; ++ii) {
if (ii->pos >= endpos || ii->pos < row.pos()
|| ii->inset->lyxCode() != HFILL_CODE)
|| (ii->inset->lyxCode() != SPACE_CODE ||
!ii->inset->isStretchableSpace()))
continue;
Dimension dim = row.dimension();
if (pm.hfillExpansion(row, ii->pos))

View File

@ -33,7 +33,6 @@
#include "insets/InsetFloatList.h"
#include "insets/InsetFoot.h"
#include "insets/InsetGraphics.h"
#include "insets/InsetHFill.h"
#include "insets/InsetInclude.h"
#include "insets/InsetIndex.h"
#include "insets/InsetInfo.h"
@ -82,8 +81,6 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
try {
switch (cmd.action) {
case LFUN_HFILL_INSERT:
return new InsetHFill;
case LFUN_LINE_INSERT:
return new InsetLine;
@ -298,6 +295,12 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
InsetCommandMailer::string2params(name, to_utf8(cmd.argument()), icp);
return new InsetRef(buf, icp);
}
case SPACE_CODE: {
InsetSpaceParams isp;
InsetSpaceMailer::string2params(to_utf8(cmd.argument()), isp);
return new InsetSpace(isp);
}
case TOC_CODE: {
InsetCommandParams icp(code);
@ -320,27 +323,58 @@ Inset * createInsetHelper(Buffer & buf, FuncRequest const & cmd)
} //end LFUN_INSET_INSERT
case LFUN_SPACE_INSERT: {
string const name = to_utf8(cmd.argument());
string const name = cmd.getArg(0);
string const len = cmd.getArg(1);
if (name.empty()) {
lyxerr << "LyX function 'space-insert' needs an argument." << endl;
break;
}
InsetSpaceParams isp;
if (name == "normal")
return new InsetSpace(InsetSpace::NORMAL);
if (name == "protected")
return new InsetSpace(InsetSpace::PROTECTED);
if (name == "thin")
return new InsetSpace(InsetSpace::THIN);
if (name == "quad")
return new InsetSpace(InsetSpace::QUAD);
if (name == "qquad")
return new InsetSpace(InsetSpace::QQUAD);
if (name == "enspace")
return new InsetSpace(InsetSpace::ENSPACE);
if (name == "enskip")
return new InsetSpace(InsetSpace::ENSKIP);
if (name == "negthinspace")
return new InsetSpace(InsetSpace::NEGTHIN);
if (name.empty())
lyxerr << "LyX function 'space' needs an argument." << endl;
else
lyxerr << "Wrong argument for LyX function 'space'." << endl;
isp.kind = InsetSpaceParams::NORMAL;
else if (name == "protected")
isp.kind = InsetSpaceParams::PROTECTED;
else if (name == "thin")
isp.kind = InsetSpaceParams::THIN;
else if (name == "quad")
isp.kind = InsetSpaceParams::QUAD;
else if (name == "qquad")
isp.kind = InsetSpaceParams::QQUAD;
else if (name == "enspace")
isp.kind = InsetSpaceParams::ENSPACE;
else if (name == "enskip")
isp.kind = InsetSpaceParams::ENSKIP;
else if (name == "negthinspace")
isp.kind = InsetSpaceParams::NEGTHIN;
else if (name == "hfill")
isp.kind = InsetSpaceParams::HFILL;
else if (name == "dotfill")
isp.kind = InsetSpaceParams::DOTFILL;
else if (name == "hrulefill")
isp.kind = InsetSpaceParams::HRULEFILL;
else if (name == "hspace") {
if (len.empty() || !isValidLength(len)) {
lyxerr << "LyX function 'space-insert hspace' "
<< "needs a valid length argument." << endl;
break;
}
isp.kind = InsetSpaceParams::CUSTOM;
isp.length = Length(len);
}
else if (name == "hspace*") {
if (len.empty() || !isValidLength(len)) {
lyxerr << "LyX function 'space-insert hspace*' "
<< "needs a valid length argument." << endl;
break;
}
isp.kind = InsetSpaceParams::CUSTOM_PROTECTED;
isp.length = Length(len);
}
else {
lyxerr << "Wrong argument for LyX function 'space-insert'." << endl;
break;
}
return new InsetSpace(isp);
}
break;
@ -487,7 +521,7 @@ Inset * readInset(Lexer & lex, Buffer const & buf)
inset.reset(new InsetERT(buf));
} else if (tmptok == "listings") {
inset.reset(new InsetListings(buf));
} else if (tmptok == "InsetSpace") {
} else if (tmptok == "Space") {
inset.reset(new InsetSpace);
} else if (tmptok == "Tabular") {
inset.reset(new InsetTabular(buf));

View File

@ -0,0 +1,268 @@
/**
* \file GuiHSpace.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Jürgen Spitzmüller
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "GuiHSpace.h"
#include "LengthCombo.h"
#include "qt_helpers.h"
#include "Validator.h"
#include "LyXRC.h"
#include "Spacing.h"
#include "FuncRequest.h"
#include "insets/InsetSpace.h"
#include "support/gettext.h"
#include "support/lstrings.h"
#include <QCheckBox>
#include <QLineEdit>
#include <QPushButton>
#include <QValidator>
using namespace std;
namespace lyx {
namespace frontend {
GuiHSpace::GuiHSpace(GuiView & lv)
: GuiDialog(lv, "space", qt_("Horizontal Space Settings"))
{
setupUi(this);
connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
connect(spacingCO, SIGNAL(highlighted(QString)),
this, SLOT(change_adaptor()));
connect(valueLE, SIGNAL(textChanged(QString)),
this, SLOT(change_adaptor()));
connect(spacingCO, SIGNAL(activated(int)),
this, SLOT(enableWidgets(int)));
connect(keepCB, SIGNAL(clicked()),
this, SLOT(change_adaptor()));
connect(unitCO, SIGNAL(selectionChanged(lyx::Length::UNIT)),
this, SLOT(change_adaptor()));
connect(fillPatternCO, SIGNAL(activated(int)),
this, SLOT(change_adaptor()));
valueLE->setValidator(unsignedLengthValidator(valueLE));
// Manage the ok, apply, restore and cancel/close buttons
bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy);
bc().setOK(okPB);
bc().setApply(applyPB);
bc().setCancel(closePB);
// disable for read-only documents
bc().addReadOnly(spacingCO);
bc().addReadOnly(valueLE);
bc().addReadOnly(unitCO);
bc().addReadOnly(keepCB);
bc().addReadOnly(fillPatternCO);
// initialize the length validator
bc().addCheckedLineEdit(valueLE, valueL);
// remove the %-items from the unit choice
unitCO->noPercents();
}
void GuiHSpace::change_adaptor()
{
changed();
}
void GuiHSpace::enableWidgets(int selection)
{
valueLE->setEnabled(selection == 7);
unitCO->setEnabled(selection == 7);
fillPatternCO->setEnabled(selection == 6);
bool const enable_keep =
selection == 0 || selection == 3 || selection == 7;
keepCB->setEnabled(enable_keep);
changed();
}
static void setWidgetsFromHSpace(InsetSpaceParams const & params,
QComboBox * spacing,
QLineEdit * value,
LengthCombo * unit,
QCheckBox * keep,
QComboBox * fillPattern)
{
int item = 0;
int pattern = 0;
bool protect = false;
switch (params.kind) {
case InsetSpaceParams::NORMAL:
item = 0;
break;
case InsetSpaceParams::PROTECTED:
item = 0;
protect = true;
break;
case InsetSpaceParams::THIN:
item = 1;
break;
case InsetSpaceParams::NEGTHIN:
item = 2;
break;
case InsetSpaceParams::ENSKIP:
item = 3;
break;
case InsetSpaceParams::ENSPACE:
item = 3;
protect = true;
break;
case InsetSpaceParams::QUAD:
item = 4;
break;
case InsetSpaceParams::QQUAD:
item = 5;
break;
case InsetSpaceParams::HFILL:
item = 6;
break;
case InsetSpaceParams::DOTFILL:
item = 6;
pattern = 1;
break;
case InsetSpaceParams::HRULEFILL:
item = 6;
pattern = 2;
break;
case InsetSpaceParams::CUSTOM:
item = 7;
break;
case InsetSpaceParams::CUSTOM_PROTECTED:
item = 7;
protect = true;
break;
}
spacing->setCurrentIndex(item);
fillPattern->setCurrentIndex(pattern);
keep->setChecked(protect);
Length::UNIT default_unit =
(lyxrc.default_papersize > 3) ? Length::CM : Length::IN;
if (item == 7)
lengthToWidgets(value, unit, params.length, default_unit);
else
lengthToWidgets(value, unit, "", default_unit);
}
static InsetSpaceParams setHSpaceFromWidgets(int spacing,
QLineEdit * value, LengthCombo * unit, bool keep, int fill)
{
InsetSpaceParams params;
switch (spacing) {
case 0:
if (keep)
params.kind = InsetSpaceParams::PROTECTED;
else
params.kind = InsetSpaceParams::NORMAL;
break;
case 1:
params.kind = InsetSpaceParams::THIN;
break;
case 2:
params.kind = InsetSpaceParams::NEGTHIN;
break;
case 3:
if (keep)
params.kind = InsetSpaceParams::ENSPACE;
else
params.kind = InsetSpaceParams::ENSKIP;
break;
case 4:
params.kind = InsetSpaceParams::QUAD;
break;
case 5:
params.kind = InsetSpaceParams::QQUAD;
break;
case 6:
if (fill == 1)
params.kind = InsetSpaceParams::DOTFILL;
else if (fill == 2)
params.kind = InsetSpaceParams::HRULEFILL;
else
params.kind = InsetSpaceParams::HFILL;
break;
case 7:
if (keep)
params.kind = InsetSpaceParams::CUSTOM_PROTECTED;
else
params.kind = InsetSpaceParams::CUSTOM;
params.length = Length(widgetsToLength(value, unit));
break;
}
return params;
}
void GuiHSpace::applyView()
{
params_ = setHSpaceFromWidgets(spacingCO->currentIndex(),
valueLE, unitCO, keepCB->isChecked(),
fillPatternCO->currentIndex());
}
void GuiHSpace::updateContents()
{
setWidgetsFromHSpace(params_, spacingCO, valueLE, unitCO, keepCB,
fillPatternCO);
enableWidgets(spacingCO->currentIndex());
}
bool GuiHSpace::initialiseParams(string const & data)
{
InsetSpaceMailer::string2params(data, params_);
setButtonsValid(true);
return true;
}
void GuiHSpace::clearParams()
{
params_ = InsetSpaceParams();
}
void GuiHSpace::dispatchParams()
{
dispatch(FuncRequest(getLfun(), InsetSpaceMailer::params2string(params_)));
}
bool GuiHSpace::isValid()
{
return (spacingCO->currentIndex() != 7 || !valueLE->text().isEmpty());
}
Dialog * createGuiHSpace(GuiView & lv) { return new GuiHSpace(lv); }
} // namespace frontend
} // namespace lyx
#include "GuiHSpace_moc.cpp"

View File

@ -0,0 +1,60 @@
// -*- C++ -*-
/**
* \file GuiHSpace.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Jürgen Spitzmüller
*
* Full author contact details are available in file CREDITS.
*/
#ifndef GUIHSPACE_H
#define GUIHSPACE_H
#include "GuiDialog.h"
#include "ui_HSpaceUi.h"
#include "insets/InsetSpace.h"
namespace lyx {
namespace frontend {
class GuiHSpace : public GuiDialog, public Ui::HSpaceUi
{
Q_OBJECT
public:
GuiHSpace(GuiView & lv);
private Q_SLOTS:
///
void change_adaptor();
///
void enableWidgets(int);
private:
/// Apply from dialog
void applyView();
/// Update the dialog
void updateContents();
///
bool isValid();
///
bool initialiseParams(std::string const & data);
/// clean-up on hide.
void clearParams();
/// clean-up on hide.
void dispatchParams();
///
bool isBufferDependent() const { return true; }
///
bool inInset() const;
///
InsetSpaceParams params_;
};
} // namespace frontend
} // namespace lyx
#endif // GUIHSPACE_H

View File

@ -2015,7 +2015,7 @@ char const * const dialognames[] = {
"citation", "document", "embedding", "errorlist", "ert", "external", "file",
"findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log",
"mathdelimiter", "mathmatrix", "note", "paragraph", "prefs", "print",
"ref", "sendto", "spellchecker", "symbols", "tabular", "tabularcreate",
"ref", "sendto", "space", "spellchecker", "symbols", "tabular", "tabularcreate",
#ifdef HAVE_LIBAIKSAURUS
"thesaurus",
@ -2219,6 +2219,7 @@ Dialog * createGuiERT(GuiView & lv);
Dialog * createGuiExternal(GuiView & lv);
Dialog * createGuiFloat(GuiView & lv);
Dialog * createGuiGraphics(GuiView & lv);
Dialog * createGuiHSpace(GuiView & lv);
Dialog * createGuiInclude(GuiView & lv);
Dialog * createGuiLabel(GuiView & lv);
Dialog * createGuiListings(GuiView & lv);
@ -2308,6 +2309,8 @@ Dialog * GuiView::build(string const & name)
return createGuiRef(*this);
if (name == "sendto")
return createGuiSendTo(*this);
if (name == "space")
return createGuiHSpace(*this);
if (name == "spellchecker")
return createGuiSpellchecker(*this);
if (name == "symbols")

View File

@ -84,6 +84,7 @@ SOURCEFILES = \
GuiFontLoader.cpp \
GuiFontMetrics.cpp \
GuiGraphics.cpp \
GuiHSpace.cpp \
GuiHyperlink.cpp \
GuiIdListModel.cpp \
GuiImage.cpp \
@ -179,6 +180,7 @@ MOCHEADER = \
GuiExternal.h \
GuiFloat.h \
GuiGraphics.h \
GuiHSpace.h \
GuiHyperlink.h \
GuiInclude.h \
GuiLabel.h \
@ -244,6 +246,7 @@ UIFILES = \
FloatUi.ui \
FontUi.ui \
GraphicsUi.ui \
HSpaceUi.ui \
HyperlinkUi.ui \
IncludeUi.ui \
LabelUi.ui \

View File

@ -0,0 +1,287 @@
<ui version="4.0" >
<class>HSpaceUi</class>
<widget class="QDialog" name="HSpaceUi" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>263</width>
<height>198</height>
</rect>
</property>
<property name="windowTitle" >
<string/>
</property>
<property name="sizeGripEnabled" >
<bool>true</bool>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item row="3" column="1" >
<widget class="QCheckBox" name="keepCB" >
<property name="toolTip" >
<string>Insert the spacing even after a line break</string>
</property>
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="fillPatternL" >
<property name="text" >
<string>&amp;Fill Pattern:</string>
</property>
<property name="buddy" >
<cstring>fillPatternCO</cstring>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QComboBox" name="fillPatternCO" >
<property name="toolTip" >
<string>Select a fill pattern style for HFills</string>
</property>
<item>
<property name="text" >
<string>None</string>
</property>
</item>
<item>
<property name="text" >
<string>...............</string>
</property>
</item>
<item>
<property name="text" >
<string>________</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0" >
<widget class="QLabel" name="spacingL" >
<property name="text" >
<string>&amp;Spacing:</string>
</property>
<property name="buddy" >
<cstring>spacingCO</cstring>
</property>
</widget>
</item>
<item row="2" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="keepL" >
<property name="toolTip" >
<string/>
</property>
<property name="text" >
<string>&amp;Protect:</string>
</property>
<property name="buddy" >
<cstring>keepCB</cstring>
</property>
</widget>
</item>
<item row="3" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="0" colspan="3" >
<layout class="QHBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QPushButton" name="okPB" >
<property name="text" >
<string>&amp;OK</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
<property name="default" >
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="applyPB" >
<property name="text" >
<string>&amp;Apply</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closePB" >
<property name="text" >
<string>&amp;Close</string>
</property>
<property name="autoDefault" >
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2" >
<widget class="LengthCombo" native="1" name="unitCO" />
</item>
<item row="0" column="1" >
<widget class="QComboBox" name="spacingCO" >
<property name="toolTip" >
<string>Supported spacing types</string>
</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>Enspace (0.5 em)</string>
</property>
</item>
<item>
<property name="text" >
<string>Quad (1 em)</string>
</property>
</item>
<item>
<property name="text" >
<string>QQuad (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>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="valueLE" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="toolTip" >
<string>Custom value. Needs spacing type "Custom".</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="valueL" >
<property name="text" >
<string>&amp;Value:</string>
</property>
<property name="buddy" >
<cstring>valueLE</cstring>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LengthCombo</class>
<extends>QWidget</extends>
<header>LengthCombo.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>spacingCO</tabstop>
<tabstop>valueLE</tabstop>
<tabstop>unitCO</tabstop>
<tabstop>okPB</tabstop>
<tabstop>applyPB</tabstop>
<tabstop>closePB</tabstop>
<tabstop>keepCB</tabstop>
</tabstops>
<includes>
<include location="local" >qt_helpers.h</include>
</includes>
<resources/>
<connections/>
</ui>

View File

@ -93,12 +93,12 @@ static TranslatorMap const build_translator()
InsetName("nomencl_print", NOMENCL_PRINT_CODE),
InsetName("optarg", OPTARG_CODE),
InsetName("environment", ENVIRONMENT_CODE),
InsetName("hfill", HFILL_CODE),
InsetName("newline", NEWLINE_CODE),
InsetName("line", LINE_CODE),
InsetName("branch", BRANCH_CODE),
InsetName("box", BOX_CODE),
InsetName("flex", FLEX_CODE),
InsetName("space", SPACE_CODE),
InsetName("vspace", VSPACE_CODE),
InsetName("mathmacroarg", MATHMACROARG_CODE),
InsetName("listings", LISTINGS_CODE),

View File

@ -383,6 +383,8 @@ public:
/// is this equivalent to a space (which is BTW different from
/// a line separator)?
virtual bool isSpace() const { return false; }
/// is this an expandible space (rubber length)?
virtual bool isStretchableSpace() const { return false; }
enum DisplayType {
Inline = 0,

View File

@ -87,11 +87,9 @@ enum InsetCode {
///
ENVIRONMENT_CODE,
///
HFILL_CODE,
NEWLINE_CODE,
///
NEWLINE_CODE, // 35
///
LINE_CODE,
LINE_CODE, // 35
///
BRANCH_CODE,
///
@ -99,9 +97,9 @@ enum InsetCode {
///
FLEX_CODE,
///
VSPACE_CODE, // 40
VSPACE_CODE,
///
MATHMACROARG_CODE,
MATHMACROARG_CODE, // 40
///
NOMENCL_CODE,
///
@ -109,9 +107,9 @@ enum InsetCode {
///
NEWPAGE_CODE,
///
LISTINGS_CODE, // 45
LISTINGS_CODE,
///
INFO_CODE,
INFO_CODE, // 45
///
COLLAPSABLE_CODE,
#if 0

View File

@ -704,7 +704,6 @@ bool InsetCollapsable::getStatus(Cursor & cur, FuncRequest const & cmd,
case LFUN_FONT_STATE:
case LFUN_FONT_UNDERLINE:
case LFUN_FOOTNOTE_INSERT:
case LFUN_HFILL_INSERT:
case LFUN_HYPERLINK_INSERT:
case LFUN_INDEX_INSERT:
case LFUN_INDEX_PRINT:

View File

@ -18,7 +18,6 @@
#include "InsetBibtex.h"
#include "InsetCitation.h"
#include "InsetFloatList.h"
#include "InsetHFill.h"
#include "InsetHyperlink.h"
#include "InsetInclude.h"
#include "InsetIndex.h"
@ -149,8 +148,6 @@ ParamInfo const & InsetCommandParams::findInfo(
return InsetCitation::findInfo(cmdName);
case FLOAT_LIST_CODE:
return InsetFloatList::findInfo(cmdName);
case HFILL_CODE:
return InsetHFill::findInfo(cmdName);
case HYPERLINK_CODE:
return InsetHyperlink::findInfo(cmdName);
case INCLUDE_CODE:
@ -191,8 +188,6 @@ string InsetCommandParams::getDefaultCmd(InsetCode code) {
return InsetCitation::defaultCommand();
case FLOAT_LIST_CODE:
return InsetFloatList::defaultCommand();
case HFILL_CODE:
return InsetHFill::defaultCommand();
case HYPERLINK_CODE:
return InsetHyperlink::defaultCommand();
case INCLUDE_CODE:
@ -228,8 +223,6 @@ bool InsetCommandParams::isCompatibleCommand(
return InsetCitation::isCompatibleCommand(s);
case FLOAT_LIST_CODE:
return InsetFloatList::isCompatibleCommand(s);
case HFILL_CODE:
return InsetHFill::isCompatibleCommand(s);
case HYPERLINK_CODE:
return InsetHyperlink::isCompatibleCommand(s);
case INCLUDE_CODE:

View File

@ -1,95 +0,0 @@
/**
* \file InsetHFill.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author André Pönitz
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "InsetHFill.h"
#include "MetricsInfo.h"
#include "frontends/Painter.h"
#include "support/gettext.h"
#include <ostream>
using namespace std;
namespace lyx {
InsetHFill::InsetHFill()
: InsetCommand(InsetCommandParams(HFILL_CODE), string())
{}
ParamInfo const & InsetHFill::findInfo(string const & /* cmdName */)
{
static ParamInfo param_info_;
return param_info_;
}
void InsetHFill::metrics(MetricsInfo &, Dimension & dim) const
{
// The metrics for this inset are calculated externally in
// \c TextMetrics::computeRowMetrics. Those are dummy value:
dim = Dimension(10, 10, 10);
}
void InsetHFill::draw(PainterInfo & pi, int x, int y) const
{
Dimension const dim = Inset::dimension(*pi.base.bv);
int const x0 = x + 1;
int const x1 = x + dim.wid - 2;
int const y0 = y + dim.des - 1;
int const y1 = y - dim.asc + 1;
pi.pain.line(x0, y1, x0, y0, Color_added_space);
pi.pain.line(x0, y, x1, y, Color_added_space,
frontend::Painter::line_onoffdash);
pi.pain.line(x1, y1, x1, y0, Color_added_space);
}
docstring InsetHFill::screenLabel() const
{
return _("Horizontal Fill");
}
int InsetHFill::plaintext(odocstream & os, OutputParams const &) const
{
os << " ";
return 5;
}
int InsetHFill::docbook(odocstream & os, OutputParams const &) const
{
os << '\n';
return 0;
}
void InsetHFill::write(ostream & os) const
{
os << "\n\\hfill\n";
}
bool InsetHFill::isSpace() const
{
return true;
}
} // namespace lyx

View File

@ -1,59 +0,0 @@
// -*- C++ -*-
/**
* \file InsetHFill.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author André Pönitz
*
* Full author contact details are available in file CREDITS.
*/
#ifndef INSET_HFILL_H
#define INSET_HFILL_H
#include "InsetCommand.h"
namespace lyx {
class InsetHFill : public InsetCommand {
public:
///
InsetHFill();
///
void metrics(MetricsInfo &, Dimension &) const;
///
void draw(PainterInfo & pi, int x, int y) const;
///
docstring screenLabel() const;
///
InsetCode lyxCode() const { return HFILL_CODE; }
///
int plaintext(odocstream &, OutputParams const &) const;
///
int docbook(odocstream &, OutputParams const &) const;
///
void write(std::ostream & os) const;
/// We don't need \begin_inset and \end_inset
bool directWrite() const { return true; }
/// is this equivalent to a space (which is BTW different from
// a line separator)?
bool isSpace() const;
///
static ParamInfo const & findInfo(std::string const &);
///
static std::string defaultCommand() { return "hfill"; };
///
static bool isCompatibleCommand(std::string const & s)
{ return s == "hfill"; }
private:
///
Inset * clone() const { return new InsetHFill(*this); }
};
} // namespace lyx
#endif

View File

@ -15,7 +15,10 @@
#include "InsetSpace.h"
#include "Cursor.h"
#include "Dimension.h"
#include "FuncRequest.h"
#include "Length.h"
#include "Lexer.h"
#include "MetricsInfo.h"
#include "OutputParams.h"
@ -25,6 +28,8 @@
#include "support/debug.h"
#include "support/docstream.h"
#include "support/gettext.h"
#include "support/lstrings.h"
using namespace std;
@ -35,44 +40,150 @@ InsetSpace::InsetSpace()
{}
InsetSpace::InsetSpace(Kind k)
: kind_(k)
{}
InsetSpace::Kind InsetSpace::kind() const
InsetSpace::InsetSpace(InsetSpaceParams par)
{
return kind_;
params_.kind = par.kind;
params_.length = par.length;
}
InsetSpaceParams::Kind InsetSpace::kind() const
{
return params_.kind;
}
Length InsetSpace::length() const
{
return params_.length;
}
InsetSpace::~InsetSpace()
{
InsetSpaceMailer(*this).hideDialog();
}
docstring InsetSpace::toolTip(BufferView const &, int, int) const
{
docstring message;
switch (params_.kind) {
case InsetSpaceParams::NORMAL:
message = _("Interword Space");
break;
case InsetSpaceParams::PROTECTED:
message = _("Protected Space");
break;
case InsetSpaceParams::THIN:
message = _("Thin Space");
break;
case InsetSpaceParams::QUAD:
message = _("Quad Space");
break;
case InsetSpaceParams::QQUAD:
message = _("QQuad Space");
break;
case InsetSpaceParams::ENSPACE:
message = _("Enspace");
break;
case InsetSpaceParams::ENSKIP:
message = _("Enskip");
break;
case InsetSpaceParams::NEGTHIN:
message = _("Negative Thin Space");
break;
case InsetSpaceParams::HFILL:
message = _("Horizontal Fill");
break;
case InsetSpaceParams::DOTFILL:
message = _("Horizontal Fill (Dots)");
break;
case InsetSpaceParams::HRULEFILL:
message = _("Horizontal Fill (Rule)");
break;
case InsetSpaceParams::CUSTOM:
message = support::bformat(_("Horizontal Space (%1$s)"),
params_.length.asDocstring());
break;
case InsetSpaceParams::CUSTOM_PROTECTED:
message = support::bformat(_("Protected Horizontal Space (%1$s)"),
params_.length.asDocstring());
break;
}
return message;
}
void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd)
{
switch (cmd.action) {
case LFUN_INSET_MODIFY: {
InsetSpaceParams params;
InsetSpaceMailer::string2params(to_utf8(cmd.argument()), params);
params_.kind = params.kind;
params_.length = params.length;
break;
}
case LFUN_MOUSE_RELEASE:
if (!cur.selection())
InsetSpaceMailer(*this).showDialog(&cur.bv());
break;
default:
Inset::doDispatch(cur, cmd);
break;
}
}
void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
{
if (params_.kind == InsetSpaceParams::HFILL ||
params_.kind == InsetSpaceParams::DOTFILL ||
params_.kind == InsetSpaceParams::HRULEFILL) {
// The metrics for this kinds are calculated externally in
// \c TextMetrics::computeRowMetrics. Those are dummy value:
dim = Dimension(10, 10, 10);
return;
}
frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
dim.asc = fm.maxAscent();
dim.des = fm.maxDescent();
switch (kind_) {
case THIN:
case NEGTHIN:
dim.wid = fm.width(char_type('M')) / 6;
switch (params_.kind) {
case InsetSpaceParams::THIN:
case InsetSpaceParams::NEGTHIN:
dim.wid = fm.width(char_type('M')) / 6;
break;
case PROTECTED:
case NORMAL:
dim.wid = fm.width(char_type(' '));
case InsetSpaceParams::PROTECTED:
case InsetSpaceParams::NORMAL:
dim.wid = fm.width(char_type(' '));
break;
case QUAD:
case InsetSpaceParams::QUAD:
dim.wid = fm.width(char_type('M'));
break;
case QQUAD:
case InsetSpaceParams::QQUAD:
dim.wid = 2 * fm.width(char_type('M'));
break;
case ENSPACE:
case ENSKIP:
case InsetSpaceParams::ENSPACE:
case InsetSpaceParams::ENSKIP:
dim.wid = int(0.5 * fm.width(char_type('M')));
break;
case InsetSpaceParams::CUSTOM:
case InsetSpaceParams::CUSTOM_PROTECTED:
dim.wid = params_.length.inBP();
break;
case InsetSpaceParams::HFILL:
case InsetSpaceParams::DOTFILL:
case InsetSpaceParams::HRULEFILL:
// shut up compiler
break;
}
// Cache the inset dimension.
// Cache the inset dimension.
setDimCache(mi, dim);
}
@ -80,14 +191,44 @@ void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const
void InsetSpace::draw(PainterInfo & pi, int x, int y) const
{
Dimension const dim = dimension(*pi.base.bv);
if (params_.kind == InsetSpaceParams::HFILL ||
params_.kind == InsetSpaceParams::DOTFILL ||
params_.kind == InsetSpaceParams::HRULEFILL) {
int const asc = theFontMetrics(pi.base.font).ascent('M');
int const desc = theFontMetrics(pi.base.font).descent('M');
int const x0 = x + 1;
int const x1 = x + dim.wid - 2;
int const y0 = y + desc;
int const y1 = y - asc;
int const y2 = y - asc / 2;
if (params_.kind == InsetSpaceParams::HFILL) {
pi.pain.line(x0, y1, x0, y0, Color_added_space);
pi.pain.line(x0, y2 , x1, y2, Color_added_space,
frontend::Painter::line_onoffdash);
pi.pain.line(x1, y1, x1, y0, Color_added_space);
} else if (params_.kind == InsetSpaceParams::DOTFILL) {
pi.pain.line(x0, y1, x0, y0, Color_special);
pi.pain.line(x0, y, x1, y, Color_special,
frontend::Painter::line_onoffdash);
pi.pain.line(x1, y1, x1, y0, Color_special);
} if (params_.kind == InsetSpaceParams::HRULEFILL) {
pi.pain.line(x0, y1, x0, y0, Color_special);
pi.pain.line(x0, y, x1, y, Color_special);
pi.pain.line(x1, y1, x1, y0, Color_special);
}
return;
}
int const w = dim.wid;
int const h = theFontMetrics(pi.base.font)
.ascent('x');
int const h = theFontMetrics(pi.base.font).ascent('x');
int xp[4], yp[4];
xp[0] = x;
yp[0] = y - max(h / 4, 1);
if (kind_ == NORMAL || kind_ == PROTECTED) {
if (params_.kind == InsetSpaceParams::NORMAL ||
params_.kind == InsetSpaceParams::PROTECTED) {
xp[1] = x; yp[1] = y;
xp[2] = x + w; yp[2] = y;
} else {
@ -97,99 +238,179 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const
xp[3] = x + w;
yp[3] = y - max(h / 4, 1);
if (kind_ == PROTECTED || kind_ == ENSPACE || kind_ == NEGTHIN)
if (params_.kind == InsetSpaceParams::PROTECTED ||
params_.kind == InsetSpaceParams::ENSPACE ||
params_.kind == InsetSpaceParams::NEGTHIN ||
params_.kind == InsetSpaceParams::CUSTOM_PROTECTED)
pi.pain.lines(xp, yp, 4, Color_latex);
else
pi.pain.lines(xp, yp, 4, Color_special);
}
void InsetSpace::write(ostream & os) const
void InsetSpaceParams::write(ostream & os) const
{
string command;
switch (kind_) {
case NORMAL:
command = "\\space{}";
switch (kind) {
case InsetSpaceParams::NORMAL:
os << "\\space{}";
break;
case PROTECTED:
command = "~";
case InsetSpaceParams::PROTECTED:
os << "~";
break;
case THIN:
command = "\\thinspace{}";
case InsetSpaceParams::THIN:
os << "\\thinspace{}";
break;
case QUAD:
command = "\\quad{}";
case InsetSpaceParams::QUAD:
os << "\\quad{}";
break;
case QQUAD:
command = "\\qquad{}";
case InsetSpaceParams::QQUAD:
os << "\\qquad{}";
break;
case ENSPACE:
command = "\\enspace{}";
case InsetSpaceParams::ENSPACE:
os << "\\enspace{}";
break;
case ENSKIP:
command = "\\enskip{}";
case InsetSpaceParams::ENSKIP:
os << "\\enskip{}";
break;
case NEGTHIN:
command = "\\negthinspace{}";
case InsetSpaceParams::NEGTHIN:
os << "\\negthinspace{}";
break;
case InsetSpaceParams::HFILL:
os << "\\hfill{}";
break;
case InsetSpaceParams::DOTFILL:
os << "\\dotfill{}";
break;
case InsetSpaceParams::HRULEFILL:
os << "\\hrulefill{}";
break;
case InsetSpaceParams::CUSTOM:
os << "\\hspace{}";
break;
case InsetSpaceParams::CUSTOM_PROTECTED:
os << "\\hspace*{}";
break;
}
os << "\\InsetSpace " << command << "\n";
if (!length.empty())
os << "\n\\length " << length.asString();
}
void InsetSpace::read(Lexer & lex)
void InsetSpaceParams::read(Lexer & lex)
{
lex.next();
string const command = lex.getString();
if (command == "\\space{}")
kind_ = NORMAL;
kind = InsetSpaceParams::NORMAL;
else if (command == "~")
kind_ = PROTECTED;
kind = InsetSpaceParams::PROTECTED;
else if (command == "\\thinspace{}")
kind_ = THIN;
kind = InsetSpaceParams::THIN;
else if (command == "\\quad{}")
kind_ = QUAD;
kind = InsetSpaceParams::QUAD;
else if (command == "\\qquad{}")
kind_ = QQUAD;
kind = InsetSpaceParams::QQUAD;
else if (command == "\\enspace{}")
kind_ = ENSPACE;
kind = InsetSpaceParams::ENSPACE;
else if (command == "\\enskip{}")
kind_ = ENSKIP;
kind = InsetSpaceParams::ENSKIP;
else if (command == "\\negthinspace{}")
kind_ = NEGTHIN;
kind = InsetSpaceParams::NEGTHIN;
else if (command == "\\hfill{}")
kind = InsetSpaceParams::HFILL;
else if (command == "\\dotfill{}")
kind = InsetSpaceParams::DOTFILL;
else if (command == "\\hrulefill{}")
kind = InsetSpaceParams::HRULEFILL;
else if (command == "\\hspace{}")
kind = InsetSpaceParams::CUSTOM;
else if (command == "\\hspace*{}")
kind = InsetSpaceParams::CUSTOM_PROTECTED;
else
lex.printError("InsetSpace: Unknown kind: `$$Token'");
string token;
lex >> token;
if (token == "\\length") {
lex.next();
string const len = lex.getString();
length = Length(len);
lex.next();
token = lex.getString();
}
if (!lex)
return;
if (token != "\\end_inset")
lex.printError("Missing \\end_inset at this point. "
"Read: `$$Token'");
}
void InsetSpace::write(ostream & os) const
{
os << "Space ";
params_.write(os);
}
void InsetSpace::read(Lexer & lex)
{
params_.read(lex);
}
int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const
{
switch (kind_) {
case NORMAL:
switch (params_.kind) {
case InsetSpaceParams::NORMAL:
os << (runparams.free_spacing ? " " : "\\ ");
break;
case PROTECTED:
case InsetSpaceParams::PROTECTED:
os << (runparams.free_spacing ? ' ' : '~');
break;
case THIN:
case InsetSpaceParams::THIN:
os << (runparams.free_spacing ? " " : "\\,");
break;
case QUAD:
case InsetSpaceParams::QUAD:
os << (runparams.free_spacing ? " " : "\\quad{}");
break;
case QQUAD:
case InsetSpaceParams::QQUAD:
os << (runparams.free_spacing ? " " : "\\qquad{}");
break;
case ENSPACE:
case InsetSpaceParams::ENSPACE:
os << (runparams.free_spacing ? " " : "\\enspace{}");
break;
case ENSKIP:
case InsetSpaceParams::ENSKIP:
os << (runparams.free_spacing ? " " : "\\enskip{}");
break;
case NEGTHIN:
case InsetSpaceParams::NEGTHIN:
os << (runparams.free_spacing ? " " : "\\negthinspace{}");
break;
case InsetSpaceParams::HFILL:
os << (runparams.free_spacing ? " " : "\\hfill{}");
break;
case InsetSpaceParams::DOTFILL:
os << (runparams.free_spacing ? " " : "\\dotfill{}");
break;
case InsetSpaceParams::HRULEFILL:
os << (runparams.free_spacing ? " " : "\\hrulefill{}");
break;
case InsetSpaceParams::CUSTOM:
if (runparams.free_spacing)
os << " ";
else
os << "\\hspace{" << from_ascii(params_.length.asLatexString()) << "}";
break;
case InsetSpaceParams::CUSTOM_PROTECTED:
if (runparams.free_spacing)
os << " ";
else
os << "\\hspace*{" << from_ascii(params_.length.asLatexString()) << "}";
break;
}
return 0;
}
@ -197,26 +418,50 @@ int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const
int InsetSpace::plaintext(odocstream & os, OutputParams const &) const
{
os << ' ';
return 1;
switch (params_.kind) {
case InsetSpaceParams::HFILL:
os << " ";
return 5;
case InsetSpaceParams::DOTFILL:
os << ".....";
return 5;
case InsetSpaceParams::HRULEFILL:
os << "_____";
return 5;
default:
os << ' ';
return 1;
}
}
int InsetSpace::docbook(odocstream & os, OutputParams const &) const
{
switch (kind_) {
case NORMAL:
case QUAD:
case QQUAD:
case ENSKIP:
switch (params_.kind) {
case InsetSpaceParams::NORMAL:
case InsetSpaceParams::QUAD:
case InsetSpaceParams::QQUAD:
case InsetSpaceParams::ENSKIP:
os << " ";
break;
case PROTECTED:
case ENSPACE:
case THIN:
case NEGTHIN:
case InsetSpaceParams::PROTECTED:
case InsetSpaceParams::ENSPACE:
case InsetSpaceParams::THIN:
case InsetSpaceParams::NEGTHIN:
os << "&nbsp;";
break;
case InsetSpaceParams::HFILL:
os << '\n';
case InsetSpaceParams::DOTFILL:
// FIXME
os << '\n';
case InsetSpaceParams::HRULEFILL:
// FIXME
os << '\n';
case InsetSpaceParams::CUSTOM:
case InsetSpaceParams::CUSTOM_PROTECTED:
// FIXME
os << '\n';
}
return 0;
}
@ -228,4 +473,54 @@ void InsetSpace::textString(odocstream & os) const
}
bool InsetSpace::isStretchableSpace() const
{
return (params_.kind == InsetSpaceParams::HFILL ||
params_.kind == InsetSpaceParams::DOTFILL ||
params_.kind == InsetSpaceParams::HRULEFILL);
}
string const InsetSpaceMailer::name_ = "space";
InsetSpaceMailer::InsetSpaceMailer(InsetSpace & inset)
: inset_(inset)
{}
string const InsetSpaceMailer::inset2string(Buffer const &) const
{
return params2string(inset_.params());
}
void InsetSpaceMailer::string2params(string const & in, InsetSpaceParams & params)
{
params = InsetSpaceParams();
if (in.empty())
return;
istringstream data(in);
Lexer lex(0,0);
lex.setStream(data);
string name;
lex >> name;
if (!lex || name != name_)
return print_mailer_error("InsetSpaceMailer", in, 1, name_);
params.read(lex);
}
string const InsetSpaceMailer::params2string(InsetSpaceParams const & params)
{
ostringstream data;
data << name_ << ' ';
params.write(data);
return data.str();
}
} // namespace lyx

View File

@ -17,16 +17,16 @@
#include "Inset.h"
#include "Length.h"
#include "MailInset.h"
namespace lyx {
class LaTeXFeatures;
/// Used to insert different kinds of spaces
class InsetSpace : public Inset {
class InsetSpaceParams {
public:
/// The different kinds of spaces we support
enum Kind {
/// Normal space ('\ ')
@ -44,17 +44,49 @@ public:
/// \enspace (0.5em breakable)
ENSKIP,
/// Negative thin space ('\negthinspace')
NEGTHIN
NEGTHIN,
/// rubber length
HFILL,
/// rubber length, filled with dots
DOTFILL,
/// rubber length, filled with a rule
HRULEFILL,
/// \hspace{length}
CUSTOM,
/// \hspace*{length}
CUSTOM_PROTECTED
};
///
InsetSpaceParams() : kind(NORMAL), length(Length()) {}
///
void write(std::ostream & os) const;
///
void read(Lexer & lex);
///
Kind kind;
///
Length length;
};
/// Used to insert different kinds of spaces
class InsetSpace : public Inset {
public:
///
InsetSpace();
///
~InsetSpace();
///
explicit
InsetSpace(Kind k);
InsetSpace(InsetSpaceParams par);
///
Kind kind() const;
InsetSpaceParams params() const { return params_; }
///
InsetSpaceParams::Kind kind() const;
///
Length length() const;
///
docstring toolTip(BufferView const & bv, int x, int y) const;
///
void metrics(MetricsInfo &, Dimension &) const;
///
@ -73,8 +105,8 @@ public:
void textString(odocstream &) const;
///
InsetCode lyxCode() const { return SPACE_CODE; }
/// We don't need \begin_inset and \end_inset
bool directWrite() const { return true; }
/// is this an expandible space (rubber length)?
bool isStretchableSpace() const;
// should this inset be handled like a normal charater
bool isChar() const { return true; }
@ -85,9 +117,33 @@ public:
bool isSpace() const { return true; }
private:
virtual Inset * clone() const { return new InsetSpace(*this); }
///
void doDispatch(Cursor & cur, FuncRequest & cmd);
/// And which kind is this?
Kind kind_;
///
InsetSpaceParams params_;
};
class InsetSpaceMailer : public MailInset {
public:
///
InsetSpaceMailer(InsetSpace & inset);
///
virtual Inset & inset() const { return inset_; }
///
virtual std::string const & name() const { return name_; }
///
virtual std::string const inset2string(Buffer const &) const;
///
static void string2params(std::string const &, InsetSpaceParams &);
///
static std::string const params2string(InsetSpaceParams const &);
private:
///
static std::string const name_;
///
InsetSpace & inset_;
};