diff --git a/src/Text3.cpp b/src/Text3.cpp index 1dead38685..f54e8f4b5a 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -73,6 +73,7 @@ #include "support/lstrings.h" #include "support/lyxtime.h" #include "support/os.h" +#include "support/regex.h" #include "mathed/InsetMathHull.h" #include "mathed/MathMacroTemplate.h" @@ -1668,15 +1669,46 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd) } case LFUN_HREF_INSERT: { - InsetCommandParams p(HYPERLINK_CODE); - docstring content; + // FIXME If we're actually given an argument, shouldn't + // we use it, whether or not we have a selection? + docstring content = cmd.argument(); if (cur.selection()) { content = cur.selectionAsString(false); cutSelection(cur, true, false); } - p["target"] = (cmd.argument().empty()) ? - content : cmd.argument(); + + InsetCommandParams p(HYPERLINK_CODE); + if (!content.empty()){ + // if it looks like a link, we'll put it as target, + // otherwise as name (bug #8792). + + // We can't do: + // regex_match(to_utf8(content), matches, link_re) + // because smatch stores pointers to the substrings rather + // than making copies of them. And those pointers become + // invalid after regex_match returns, since it is then + // being given a temporary object. (Thanks to Georg for + // figuring that out.) + regex const link_re("^([a-zA-Z]+):.*"); + smatch matches; + string const c = to_utf8(content); + + if (content.substr(0,7) == "mailto:") { + p["target"] = content; + p["type"] = from_ascii("mailto:"); + } else if (regex_match(c, matches, link_re)) { + p["target"] = content; + string protocol = matches.str(1); + if (protocol == "file") + p["type"] = from_ascii("file:"); + } else + p["name"] = content; + } string const data = InsetCommand::params2string(p); + + // we need to have a target. if we already have one, then + // that gets used at the default for the name, too, which + // is probably what is wanted. if (p["target"].empty()) { bv->showDialog("href", data); } else { diff --git a/src/frontends/qt4/GuiHyperlink.cpp b/src/frontends/qt4/GuiHyperlink.cpp index 7cb9cc61d4..6cd9262798 100644 --- a/src/frontends/qt4/GuiHyperlink.cpp +++ b/src/frontends/qt4/GuiHyperlink.cpp @@ -68,6 +68,23 @@ void GuiHyperlink::paramsToDialog(Inset const * inset) } +bool GuiHyperlink::initialiseParams(std::string const & data) +{ + InsetCommandParams params(insetCode()); + if (!InsetCommand::string2params(data, params)) + return false; + targetED->setText(toqstr(params["target"])); + nameED->setText(toqstr(params["name"])); + if (params["type"] == from_utf8("mailto:")) + emailRB->setChecked(true); + else if (params["type"] == from_utf8("file:")) + fileRB->setChecked(true); + else + webRB->setChecked(true); + return true; +} + + docstring GuiHyperlink::dialogToParams() const { InsetCommandParams params(insetCode()); @@ -75,11 +92,11 @@ docstring GuiHyperlink::dialogToParams() const params["target"] = qstring_to_ucs4(targetED->text()); params["name"] = qstring_to_ucs4(nameED->text()); if (webRB->isChecked()) - params["type"] = qstring_to_ucs4(""); + params["type"] = from_utf8(""); else if (emailRB->isChecked()) - params["type"] = qstring_to_ucs4("mailto:"); + params["type"] = from_utf8("mailto:"); else if (fileRB->isChecked()) - params["type"] = qstring_to_ucs4("file:"); + params["type"] = from_utf8("file:"); params.setCmdName("href"); return from_utf8(InsetHyperlink::params2string(params)); } diff --git a/src/frontends/qt4/GuiHyperlink.h b/src/frontends/qt4/GuiHyperlink.h index 2134ca8a19..d2dd0ee0fb 100644 --- a/src/frontends/qt4/GuiHyperlink.h +++ b/src/frontends/qt4/GuiHyperlink.h @@ -35,6 +35,7 @@ private: void paramsToDialog(Inset const *); docstring dialogToParams() const; bool checkWidgets() const; + bool initialiseParams(std::string const & data); //@} }; diff --git a/src/support/lstrings.cpp b/src/support/lstrings.cpp index dbf629cafa..2d483e6744 100644 --- a/src/support/lstrings.cpp +++ b/src/support/lstrings.cpp @@ -481,6 +481,14 @@ docstring const lowercase(docstring const & a) } +string const lowercase(string const & a) +{ + string tmp(a); + transform(tmp.begin(), tmp.end(), tmp.begin(), local_lowercase()); + return tmp; +} + + docstring const uppercase(docstring const & a) { docstring tmp(a); diff --git a/src/support/lstrings.h b/src/support/lstrings.h index 2606546fa0..89450c706f 100644 --- a/src/support/lstrings.h +++ b/src/support/lstrings.h @@ -96,6 +96,7 @@ docstring const ascii_lowercase(docstring const &); /// Changes the case of \p s to lowercase. /// Does not depend on the locale. +std::string const lowercase(std::string const & s); docstring const lowercase(docstring const & s); /// Changes the case of \p s to uppercase.