lyx_mirror/src/insets/InsetLine.cpp
Richard Heck ecef54500d Introduce max_length parameter for plaintext() output routines,
so we can write a limited amount when using this for TOC and
tooltip output.

This should solve the problem with slowness that Kornel noticed,
which was caused by our trying to write an entire plaintext
bibliography every time we updated the TOC. We did that because
he had a bibliography inside a branch, and we use plaintext for
creating the tooltip that goes with the branch list.

Other related bugs were fixed along the way. E.g., it turns out
that, if someone had an InsetInclude inside a branch, then we would
have been writing a *plaintext file* for that inset every time we
updated the TOC. I wonder if some of the other reports of slowness
we have received might be due to this kind of issue?
2013-03-08 15:12:58 -05:00

211 lines
4.8 KiB
C++

/**
* \file InsetLine.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Abdelrazak Younes
* \author André Pönitz
* \author Uwe Stöhr
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "InsetLine.h"
#include "Buffer.h"
#include "Cursor.h"
#include "Dimension.h"
#include "DispatchResult.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LaTeXFeatures.h"
#include "Length.h"
#include "MetricsInfo.h"
#include "OutputParams.h"
#include "output_xhtml.h"
#include "Text.h"
#include "frontends/FontMetrics.h"
#include "frontends/Painter.h"
#include "support/debug.h"
#include "support/docstream.h"
#include "support/gettext.h"
#include "support/lstrings.h"
#include <cstdlib>
using namespace std;
namespace lyx {
using frontend::Painter;
InsetLine::InsetLine(Buffer * buf, InsetCommandParams const & p)
: InsetCommand(buf, p)
{}
ParamInfo const & InsetLine::findInfo(string const & /* cmdName */)
{
static ParamInfo param_info_;
if (param_info_.empty()) {
param_info_.add("offset", ParamInfo::LYX_INTERNAL);
param_info_.add("width", ParamInfo::LYX_INTERNAL);
param_info_.add("height", ParamInfo::LYX_INTERNAL);
}
return param_info_;
}
docstring InsetLine::screenLabel() const
{
return _("Horizontal line");
}
void InsetLine::doDispatch(Cursor & cur, FuncRequest & cmd)
{
switch (cmd.action()) {
case LFUN_INSET_MODIFY: {
InsetCommandParams p(LINE_CODE);
// FIXME UNICODE
InsetCommand::string2params(to_utf8(cmd.argument()), p);
if (p.getCmdName().empty()) {
cur.noScreenUpdate();
break;
}
cur.recordUndo();
setParams(p);
break;
}
default:
InsetCommand::doDispatch(cur, cmd);
break;
}
}
bool InsetLine::getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & status) const
{
switch (cmd.action()) {
case LFUN_INSET_DIALOG_UPDATE:
case LFUN_INSET_MODIFY:
status.setEnabled(true);
return true;
default:
return InsetCommand::getStatus(cur, cmd, status);
}
}
void InsetLine::metrics(MetricsInfo & mi, Dimension & dim) const
{
frontend::FontMetrics const & fm = theFontMetrics(mi.base.font);
int const max_width = mi.base.textwidth;
Length const width(to_ascii(getParam("width")));
dim.wid = width.inPixels(max_width, fm.width(char_type('M')));
// assure that the line inset is not outside of the window
// check that it doesn't exceed the outer boundary
if (dim.wid > max_width)
dim.wid = max_width;
// set a minimal width
int const minw = (dim.wid < 0) ? 24 : 4;
dim.wid = max(minw, abs(dim.wid));
Length height = Length(to_ascii(getParam("height")));
height_ = height.inPixels(max_width, fm.width(char_type('M')));
// get the length of the parameters in pixels
Length offset = Length(to_ascii(getParam("offset")));
offset_ = offset.inPixels(max_width, fm.width(char_type('M')));
dim.asc = max(fm.maxAscent(), offset_ + height_);
dim.des = max(fm.maxDescent(), - offset_);
// Cache the inset dimension
setDimCache(mi, dim);
}
Dimension const InsetLine::dimension(BufferView const & bv) const
{
// We cannot use InsetCommand::dimension() as this returns the dimension
// of the button, which is not used here.
return Inset::dimension(bv);
}
void InsetLine::draw(PainterInfo & pi, int x, int y) const
{
Dimension const dim = dimension(*pi.base.bv);
// get the surrounding text color
Color Line_color = pi.base.font.realColor();
// the offset is a vertical one
// the horizontal dimension must be corrected with the heigth because
// of left and right border of the painted line for big heigth.
pi.pain.line(x + height_/2 + 1,
y - offset_ - height_/2,
x + dim.wid - height_/2 - 2,
y - offset_ - height_/2,
Line_color, Painter::line_solid, float(height_));
}
void InsetLine::latex(otexstream & os, OutputParams const &) const
{
bool have_offset = true;
Length offset_len = Length(to_ascii(getParam("offset")));
if (offset_len.value() == 0)
have_offset = false;
string const offset =
Length(to_ascii(getParam("offset"))).asLatexString();
string const width =
Length(to_ascii(getParam("width"))).asLatexString();
string const height =
Length(to_ascii(getParam("height"))).asLatexString();
os << "\\rule";
// only output the optional parameter if the offset is not 0
if (have_offset)
os << "[" << from_ascii(offset) << "]";
os << "{" << from_ascii(width) << "}{" << from_ascii(height) << '}';
}
int InsetLine::plaintext(odocstringstream & os,
OutputParams const &, size_t) const
{
os << "\n-------------------------------------------\n";
return PLAINTEXT_NEWLINE;
}
int InsetLine::docbook(odocstream & os, OutputParams const &) const
{
os << '\n';
return 0;
}
docstring InsetLine::xhtml(XHTMLStream & xs, OutputParams const &) const
{
xs << html::CompTag("hr") << html::CR();
return docstring();
}
} // namespace lyx