X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInsetSpace.cpp;h=c9156d4e51136255c9ceabaac876277baf66806f;hb=4a1be58591ea5a7431d9426abb27d8b946c634cb;hp=2c3c97d99269dd62a3e46253f816b5dea9cfd8cd;hpb=48778460a04e0ef2cf16eb01eff7373a7335ec26;p=lyx.git diff --git a/src/insets/InsetSpace.cpp b/src/insets/InsetSpace.cpp index 2c3c97d992..c9156d4e51 100644 --- a/src/insets/InsetSpace.cpp +++ b/src/insets/InsetSpace.cpp @@ -15,38 +15,35 @@ #include "InsetSpace.h" +#include "BufferView.h" #include "Cursor.h" #include "Dimension.h" #include "FuncRequest.h" +#include "FuncStatus.h" #include "Length.h" #include "Lexer.h" #include "MetricsInfo.h" #include "OutputParams.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 "frontends/Application.h" +#include "frontends/FontMetrics.h" +#include "frontends/Painter.h" + using namespace std; namespace lyx { -InsetSpace::InsetSpace() +InsetSpace::InsetSpace(InsetSpaceParams const & params) + : params_(params) {} -InsetSpace::InsetSpace(InsetSpaceParams par) -{ - params_.kind = par.kind; - params_.length = par.length; -} - - InsetSpaceParams::Kind InsetSpace::kind() const { return params_.kind; @@ -61,7 +58,7 @@ Length InsetSpace::length() const InsetSpace::~InsetSpace() { - InsetSpaceMailer(*this).hideDialog(); + hideDialogs("space", this); } @@ -105,6 +102,18 @@ docstring InsetSpace::toolTip(BufferView const &, int, int) const case InsetSpaceParams::HRULEFILL: message = _("Horizontal Fill (Rule)"); break; + case InsetSpaceParams::LEFTARROWFILL: + message = _("Horizontal Fill (Left Arrow)"); + break; + case InsetSpaceParams::RIGHTARROWFILL: + message = _("Horizontal Fill (Right Arrow)"); + break; + case InsetSpaceParams::UPBRACEFILL: + message = _("Horizontal Fill (Up Brace)"); + break; + case InsetSpaceParams::DOWNBRACEFILL: + message = _("Horizontal Fill (Down Brace)"); + break; case InsetSpaceParams::CUSTOM: message = support::bformat(_("Horizontal Space (%1$s)"), params_.length.asDocstring()); @@ -123,16 +132,13 @@ 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; + string2params(to_utf8(cmd.argument()), params_); break; } case LFUN_MOUSE_RELEASE: - if (!cur.selection()) - InsetSpaceMailer(*this).showDialog(&cur.bv()); + if (!cur.selection() && cmd.button() == mouse_button::button1) + cur.bv().showDialog("space", params2string(params()), this); break; default: @@ -142,9 +148,28 @@ void InsetSpace::doDispatch(Cursor & cur, FuncRequest & cmd) } +bool InsetSpace::getStatus(Cursor & cur, FuncRequest const & cmd, + FuncStatus & status) const +{ + switch (cmd.action) { + // we handle these + case LFUN_INSET_MODIFY: + if (cmd.getArg(0) == "space") { + InsetSpaceParams params; + string2params(to_utf8(cmd.argument()), params); + status.setOnOff(params_.kind == params.kind); + } + status.setEnabled(true); + return true; + default: + return Inset::getStatus(cur, cmd, status); + } +} + + void InsetSpace::edit(Cursor & cur, bool, EntryDirection) { - InsetSpaceMailer(*this).showDialog(&cur.bv()); + cur.bv().showDialog("space", params2string(params()), this); } @@ -188,6 +213,10 @@ void InsetSpace::metrics(MetricsInfo & mi, Dimension & dim) const case InsetSpaceParams::HFILL_PROTECTED: case InsetSpaceParams::DOTFILL: case InsetSpaceParams::HRULEFILL: + case InsetSpaceParams::LEFTARROWFILL: + case InsetSpaceParams::RIGHTARROWFILL: + case InsetSpaceParams::UPBRACEFILL: + case InsetSpaceParams::DOWNBRACEFILL: // shut up compiler break; } @@ -203,11 +232,30 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const if (isStretchableSpace()) { int const asc = theFontMetrics(pi.base.font).ascent('M'); int const desc = theFontMetrics(pi.base.font).descent('M'); + //Pixel height divisible by 2 for prettier fill graphics: + int const oddheight = (asc ^ desc) & 1; 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; + int const y0 = y + desc - 1; + int const y1 = y - asc + oddheight - 1; + int const y2 = (y0 + y1) / 2; + int xoffset = (y0 - y1) / 2; + + //Two tests for very narrow insets + if (xoffset > x1 - x0 + && (params_.kind == InsetSpaceParams::LEFTARROWFILL + || params_.kind == InsetSpaceParams::RIGHTARROWFILL)) + xoffset = x1 - x0; + if (xoffset * 6 > (x1 - x0) + && (params_.kind == InsetSpaceParams::UPBRACEFILL + || params_.kind == InsetSpaceParams::DOWNBRACEFILL)) + xoffset = (x1 - x0) / 6; + + int const x2 = x0 + xoffset; + int const x3 = x1 - xoffset; + int const xm = (x0 + x1) / 2; + int const xml = xm - xoffset; + int const xmr = xm + xoffset; if (params_.kind == InsetSpaceParams::HFILL) { pi.pain.line(x0, y1, x0, y0, Color_added_space); @@ -221,13 +269,35 @@ void InsetSpace::draw(PainterInfo & pi, int x, int y) const pi.pain.line(x1, y1, x1, y0, Color_latex); } else if (params_.kind == InsetSpaceParams::DOTFILL) { pi.pain.line(x0, y1, x0, y0, Color_special); - pi.pain.line(x0, y, x1, y, Color_special, + pi.pain.line(x0, y0, x1, y0, Color_special, frontend::Painter::line_onoffdash); pi.pain.line(x1, y1, x1, y0, Color_special); - } if (params_.kind == InsetSpaceParams::HRULEFILL) { + } else 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(x0, y0, x1, y0, Color_special); pi.pain.line(x1, y1, x1, y0, Color_special); + } else if (params_.kind == InsetSpaceParams::LEFTARROWFILL) { + pi.pain.line(x2, y1 + 1 , x0 + 1, y2, Color_special); + pi.pain.line(x0 + 1, y2 + 1 , x2, y0, Color_special); + pi.pain.line(x0, y2 , x1, y2, Color_special); + } else if (params_.kind == InsetSpaceParams::RIGHTARROWFILL) { + pi.pain.line(x3 + 1, y1 + 1 , x1, y2, Color_special); + pi.pain.line(x1, y2 + 1 , x3 + 1, y0, Color_special); + pi.pain.line(x0, y2 , x1, y2, Color_special); + } else if (params_.kind == InsetSpaceParams::UPBRACEFILL) { + pi.pain.line(x0 + 1, y1 + 1 , x2, y2, Color_special); + pi.pain.line(x2, y2 , xml, y2, Color_special); + pi.pain.line(xml + 1, y2 + 1 , xm, y0, Color_special); + pi.pain.line(xm + 1, y0 , xmr, y2 + 1, Color_special); + pi.pain.line(xmr, y2 , x3, y2, Color_special); + pi.pain.line(x3 + 1, y2 , x1, y1 + 1, Color_special); + } else if (params_.kind == InsetSpaceParams::DOWNBRACEFILL) { + pi.pain.line(x0 + 1, y0 , x2, y2 + 1, Color_special); + pi.pain.line(x2, y2 , xml, y2, Color_special); + pi.pain.line(xml + 1, y2 , xm, y1 + 1, Color_special); + pi.pain.line(xm + 1, y1 + 1 , xmr, y2, Color_special); + pi.pain.line(xmr, y2 , x3, y2, Color_special); + pi.pain.line(x3 + 1, y2 + 1 , x1, y0, Color_special); } return; } @@ -299,6 +369,18 @@ void InsetSpaceParams::write(ostream & os) const case InsetSpaceParams::HRULEFILL: os << "\\hrulefill{}"; break; + case InsetSpaceParams::LEFTARROWFILL: + os << "\\leftarrowfill{}"; + break; + case InsetSpaceParams::RIGHTARROWFILL: + os << "\\rightarrowfill{}"; + break; + case InsetSpaceParams::UPBRACEFILL: + os << "\\upbracefill{}"; + break; + case InsetSpaceParams::DOWNBRACEFILL: + os << "\\downbracefill{}"; + break; case InsetSpaceParams::CUSTOM: os << "\\hspace{}"; break; @@ -314,8 +396,9 @@ void InsetSpaceParams::write(ostream & os) const void InsetSpaceParams::read(Lexer & lex) { - lex.next(); - string const command = lex.getString(); + lex.setContext("InsetSpaceParams::read"); + string command; + lex >> command; if (command == "\\space{}") kind = InsetSpaceParams::NORMAL; @@ -343,32 +426,27 @@ void InsetSpaceParams::read(Lexer & lex) kind = InsetSpaceParams::HRULEFILL; else if (command == "\\hspace{}") kind = InsetSpaceParams::CUSTOM; + else if (command == "\\leftarrowfill{}") + kind = InsetSpaceParams::LEFTARROWFILL; + else if (command == "\\rightarrowfill{}") + kind = InsetSpaceParams::RIGHTARROWFILL; + else if (command == "\\upbracefill{}") + kind = InsetSpaceParams::UPBRACEFILL; + else if (command == "\\downbracefill{}") + kind = InsetSpaceParams::DOWNBRACEFILL; 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'"); + if (lex.checkFor("\\length")) + lex >> length; } void InsetSpace::write(ostream & os) const { - os << "Space "; + os << "space "; params_.write(os); } @@ -376,6 +454,7 @@ void InsetSpace::write(ostream & os) const void InsetSpace::read(Lexer & lex) { params_.read(lex); + lex >> "\\end_inset"; } @@ -418,6 +497,18 @@ int InsetSpace::latex(odocstream & os, OutputParams const & runparams) const case InsetSpaceParams::HRULEFILL: os << (runparams.free_spacing ? " " : "\\hrulefill{}"); break; + case InsetSpaceParams::LEFTARROWFILL: + os << (runparams.free_spacing ? " " : "\\leftarrowfill{}"); + break; + case InsetSpaceParams::RIGHTARROWFILL: + os << (runparams.free_spacing ? " " : "\\rightarrowfill{}"); + break; + case InsetSpaceParams::UPBRACEFILL: + os << (runparams.free_spacing ? " " : "\\upbracefill{}"); + break; + case InsetSpaceParams::DOWNBRACEFILL: + os << (runparams.free_spacing ? " " : "\\downbracefill{}"); + break; case InsetSpaceParams::CUSTOM: if (runparams.free_spacing) os << " "; @@ -448,6 +539,18 @@ int InsetSpace::plaintext(odocstream & os, OutputParams const &) const case InsetSpaceParams::HRULEFILL: os << "_____"; return 5; + case InsetSpaceParams::LEFTARROWFILL: + os << "<----"; + return 5; + case InsetSpaceParams::RIGHTARROWFILL: + os << "---->"; + return 5; + case InsetSpaceParams::UPBRACEFILL: + os << "\\-v-/"; + return 5; + case InsetSpaceParams::DOWNBRACEFILL: + os << "/-^-\\"; + return 5; default: os << ' '; return 1; @@ -479,6 +582,10 @@ int InsetSpace::docbook(odocstream & os, OutputParams const &) const case InsetSpaceParams::HRULEFILL: // FIXME os << '\n'; + case InsetSpaceParams::LEFTARROWFILL: + case InsetSpaceParams::RIGHTARROWFILL: + case InsetSpaceParams::UPBRACEFILL: + case InsetSpaceParams::DOWNBRACEFILL: case InsetSpaceParams::CUSTOM: case InsetSpaceParams::CUSTOM_PROTECTED: // FIXME @@ -496,10 +603,14 @@ void InsetSpace::textString(odocstream & os) const bool InsetSpace::isStretchableSpace() const { - return (params_.kind == InsetSpaceParams::HFILL || - params_.kind == InsetSpaceParams::HFILL_PROTECTED || - params_.kind == InsetSpaceParams::DOTFILL || - params_.kind == InsetSpaceParams::HRULEFILL); + return params_.kind == InsetSpaceParams::HFILL + || params_.kind == InsetSpaceParams::HFILL_PROTECTED + || params_.kind == InsetSpaceParams::DOTFILL + || params_.kind == InsetSpaceParams::HRULEFILL + || params_.kind == InsetSpaceParams::LEFTARROWFILL + || params_.kind == InsetSpaceParams::RIGHTARROWFILL + || params_.kind == InsetSpaceParams::UPBRACEFILL + || params_.kind == InsetSpaceParams::DOWNBRACEFILL; } @@ -509,43 +620,30 @@ docstring InsetSpace::contextMenu(BufferView const &, int, int) const } -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) +void InsetSpace::string2params(string const & in, InsetSpaceParams & params) { params = InsetSpaceParams(); if (in.empty()) return; istringstream data(in); - Lexer lex(0,0); + Lexer lex; lex.setStream(data); - - string name; - lex >> name; - if (!lex || name != name_) - return print_mailer_error("InsetSpaceMailer", in, 1, name_); - - params.read(lex); + lex.setContext("InsetSpace::string2params"); + lex >> "space"; + + // There are cases, such as when we are called via getStatus() from + // Dialog::canApply(), where we are just called with "space" rather + // than a full "space \type{}\n\\end_inset". + if (lex.isOK()) + params.read(lex); } -string const InsetSpaceMailer::params2string(InsetSpaceParams const & params) +string InsetSpace::params2string(InsetSpaceParams const & params) { ostringstream data; - data << name_ << ' '; + data << "space" << ' '; params.write(data); return data.str(); }