mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 18:08:10 +00:00
Consistency of ellipses across the UI
Use the function support:truncateWithEllipsis() to shorten a docstring with ... at the end. Actually we use U+2026 HORIZONTAL ELLIPSIS instead of "..." when automatically shortening strings. This is to be consistent with Qt's own truncation and is much nicer on the screen. This includes the bugs #9575 and #9572 regarding broken text elision in the outliner. Known issues (non-regressions): * TocBackend::updateItem() should be rewritten to update all TOCs. (#8386) * "..." should be replaced with … everywhere else on the interface (including translation strings). * We should prefer to rely on QFontMetrics::elidedText() to truncate strings with an ellipsis whenever possible, or an equivalent for the buffer view dependent on the font metrics. See the warning in src/support/lstrings.h.
This commit is contained in:
parent
f6c6416f28
commit
bb344452c8
@ -756,8 +756,7 @@ docstring BibTeXInfo::getValueForKey(string const & oldkey, Buffer const & buf,
|
|||||||
ret = html::cleanAttr(ret);
|
ret = html::cleanAttr(ret);
|
||||||
|
|
||||||
// make sure it is not too big
|
// make sure it is not too big
|
||||||
if (ret.size() > maxsize)
|
support::truncateWithEllipsis(ret, maxsize);
|
||||||
ret = ret.substr(0, maxsize - 3) + from_ascii("...");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,14 +927,9 @@ docstring const BiblioInfo::getLabel(vector<docstring> keys,
|
|||||||
before, after, dialog, key + 1 != ken);
|
before, after, dialog, key + 1 != ken);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret.size() > max_size) {
|
if (too_many_keys)
|
||||||
ret.resize(max_size - 3);
|
ret.push_back(0x2026);//HORIZONTAL ELLIPSIS
|
||||||
ret += "...";
|
support::truncateWithEllipsis(ret, max_size);
|
||||||
} else if (too_many_keys) {
|
|
||||||
if (ret.size() > max_size - 3)
|
|
||||||
ret.resize(max_size - 3);
|
|
||||||
ret += "...";
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,22 +811,20 @@ vector<docstring> availableSelections(Buffer const * buf)
|
|||||||
// we do not use cit-> here because gcc 2.9x does not
|
// we do not use cit-> here because gcc 2.9x does not
|
||||||
// like it (JMarc)
|
// like it (JMarc)
|
||||||
ParagraphList const & pars = (*cit).first;
|
ParagraphList const & pars = (*cit).first;
|
||||||
docstring asciiSel;
|
docstring textSel;
|
||||||
ParagraphList::const_iterator pit = pars.begin();
|
ParagraphList::const_iterator pit = pars.begin();
|
||||||
ParagraphList::const_iterator pend = pars.end();
|
ParagraphList::const_iterator pend = pars.end();
|
||||||
for (; pit != pend; ++pit) {
|
for (; pit != pend; ++pit) {
|
||||||
Paragraph par(*pit, 0, 26);
|
Paragraph par(*pit, 0, 46);
|
||||||
// adapt paragraph to current buffer.
|
// adapt paragraph to current buffer.
|
||||||
par.setBuffer(const_cast<Buffer &>(*buf));
|
par.setBuffer(const_cast<Buffer &>(*buf));
|
||||||
asciiSel += par.asString(AS_STR_INSETS);
|
textSel += par.asString(AS_STR_INSETS);
|
||||||
if (asciiSel.size() > 25) {
|
if (textSel.size() > 45) {
|
||||||
asciiSel.replace(22, docstring::npos,
|
support::truncateWithEllipsis(textSel,45);
|
||||||
from_ascii("..."));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
selList.push_back(textSel);
|
||||||
selList.push_back(asciiSel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return selList;
|
return selList;
|
||||||
|
@ -3257,11 +3257,13 @@ docstring Paragraph::asString(pos_type beg, pos_type end, int options, const Out
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Paragraph::forOutliner(docstring & os, size_t maxlen) const
|
void Paragraph::forOutliner(docstring & os, size_t const maxlen,
|
||||||
|
bool const shorten) const
|
||||||
{
|
{
|
||||||
|
size_t tmplen = shorten ? maxlen + 1 : maxlen;
|
||||||
if (!d->params_.labelString().empty())
|
if (!d->params_.labelString().empty())
|
||||||
os += d->params_.labelString() + ' ';
|
os += d->params_.labelString() + ' ';
|
||||||
for (pos_type i = 0; i < size() && os.length() < maxlen; ++i) {
|
for (pos_type i = 0; i < size() && os.length() < tmplen; ++i) {
|
||||||
if (isDeleted(i))
|
if (isDeleted(i))
|
||||||
continue;
|
continue;
|
||||||
char_type const c = d->text_[i];
|
char_type const c = d->text_[i];
|
||||||
@ -3270,8 +3272,10 @@ void Paragraph::forOutliner(docstring & os, size_t maxlen) const
|
|||||||
else if (c == '\t' || c == '\n')
|
else if (c == '\t' || c == '\n')
|
||||||
os += ' ';
|
os += ' ';
|
||||||
else if (c == META_INSET)
|
else if (c == META_INSET)
|
||||||
getInset(i)->forOutliner(os, maxlen);
|
getInset(i)->forOutliner(os, tmplen, false);
|
||||||
}
|
}
|
||||||
|
if (shorten)
|
||||||
|
Text::shortenForOutliner(os, maxlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,7 +181,8 @@ public:
|
|||||||
int options = AS_STR_NONE,
|
int options = AS_STR_NONE,
|
||||||
const OutputParams *runparams = 0) const;
|
const OutputParams *runparams = 0) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t maxlen) const;
|
void forOutliner(docstring &, size_t const maxlen,
|
||||||
|
bool const shorten = true) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
void write(std::ostream &, BufferParams const &,
|
void write(std::ostream &, BufferParams const &,
|
||||||
|
24
src/Text.cpp
24
src/Text.cpp
@ -2043,13 +2043,25 @@ docstring Text::asString(pit_type beg, pit_type end, int options) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Text::forOutliner(docstring & os, size_t maxlen, bool shorten) const
|
void Text::shortenForOutliner(docstring & str, size_t const maxlen)
|
||||||
{
|
{
|
||||||
LASSERT(maxlen >= 8, maxlen = TOC_ENTRY_LENGTH);
|
support::truncateWithEllipsis(str, maxlen);
|
||||||
for (size_t i = 0; i != pars_.size() && os.length() < maxlen; ++i)
|
docstring::iterator it = str.begin();
|
||||||
pars_[i].forOutliner(os, maxlen);
|
docstring::iterator end = str.end();
|
||||||
if (shorten && os.length() >= maxlen)
|
for (; it != end; ++it)
|
||||||
os = os.substr(0, maxlen - 3) + from_ascii("...");
|
if ((*it) == L'\n' || (*it) == L'\t')
|
||||||
|
(*it) = L' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Text::forOutliner(docstring & os, size_t const maxlen,
|
||||||
|
bool const shorten) const
|
||||||
|
{
|
||||||
|
size_t tmplen = shorten ? maxlen + 1 : maxlen;
|
||||||
|
for (size_t i = 0; i != pars_.size() && os.length() < tmplen; ++i)
|
||||||
|
pars_[i].forOutliner(os, tmplen, false);
|
||||||
|
if (shorten)
|
||||||
|
shortenForOutliner(os, maxlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
18
src/Text.h
18
src/Text.h
@ -123,14 +123,16 @@ public:
|
|||||||
///
|
///
|
||||||
docstring asString(pit_type beg, pit_type end,
|
docstring asString(pit_type beg, pit_type end,
|
||||||
int options = AS_STR_NONE) const;
|
int options = AS_STR_NONE) const;
|
||||||
/// Appends a possibly abbreviated representation of our text
|
|
||||||
/// to \param os, where \param maxlen defines the maximum size
|
/// truncates str to maxlenwith an ellipsis and replaces the characters '\n'
|
||||||
/// of \param os. If \param shorten is true, then we will shorten
|
/// and '\t' with spaces
|
||||||
/// \param os to maxlen chars and replace the final three by "...,
|
static void shortenForOutliner(docstring & str, size_t const maxlen);
|
||||||
/// if \param os is longer than maxlen chars.
|
|
||||||
/// if \param maxlen is passed as 0, then it is ignored. (In fact,
|
/// Appends a possibly abbreviated representation of our text to \param os,
|
||||||
/// it is reset to the maximum value for size_t.)
|
/// where \param maxlen defines the maximum size of \param os. If \param
|
||||||
void forOutliner(docstring & os, size_t maxlen, bool shorten = true) const;
|
/// shorten is true, then os is shortened as above
|
||||||
|
void forOutliner(docstring & os, size_t const maxlen,
|
||||||
|
bool const shorten = true) const;
|
||||||
|
|
||||||
/// insert a character at cursor position
|
/// insert a character at cursor position
|
||||||
/// FIXME: replace Cursor with DocIterator.
|
/// FIXME: replace Cursor with DocIterator.
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#include "support/convert.h"
|
#include "support/convert.h"
|
||||||
#include "support/debug.h"
|
#include "support/debug.h"
|
||||||
#include "support/docstream.h"
|
#include "support/docstream.h"
|
||||||
|
|
||||||
#include "support/lassert.h"
|
#include "support/lassert.h"
|
||||||
|
#include "support/lstrings.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -259,6 +259,11 @@ shared_ptr<TocBuilder> TocBackend::builder(string const & type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: This function duplicates functionality from InsetText::iterateForToc.
|
||||||
|
// Both have their own way of computing the TocItem for "tableofcontents". The
|
||||||
|
// TocItem creation and update should be made in a dedicated function and
|
||||||
|
// updateItem should be rewritten to uniformly update the matching items from
|
||||||
|
// all TOCs.
|
||||||
bool TocBackend::updateItem(DocIterator const & dit)
|
bool TocBackend::updateItem(DocIterator const & dit)
|
||||||
{
|
{
|
||||||
if (dit.text()->getTocLevel(dit.pit()) == Layout::NOT_IN_TOC)
|
if (dit.text()->getTocLevel(dit.pit()) == Layout::NOT_IN_TOC)
|
||||||
@ -280,28 +285,30 @@ bool TocBackend::updateItem(DocIterator const & dit)
|
|||||||
|
|
||||||
// For each paragraph, traverse its insets and let them add
|
// For each paragraph, traverse its insets and let them add
|
||||||
// their toc items
|
// their toc items
|
||||||
|
//
|
||||||
|
// FIXME: This is supposed to accomplish the same as the body of
|
||||||
|
// InsetText::iterateForToc(), probably
|
||||||
Paragraph & par = toc_item->dit_.paragraph();
|
Paragraph & par = toc_item->dit_.paragraph();
|
||||||
InsetList::const_iterator it = par.insetList().begin();
|
InsetList::const_iterator it = par.insetList().begin();
|
||||||
InsetList::const_iterator end = par.insetList().end();
|
InsetList::const_iterator end = par.insetList().end();
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
Inset & inset = *it->inset;
|
Inset & inset = *it->inset;
|
||||||
if (inset.lyxCode() == ARG_CODE) {
|
if (inset.lyxCode() == ARG_CODE) {
|
||||||
|
tocstring = par.labelString();
|
||||||
if (!tocstring.empty())
|
if (!tocstring.empty())
|
||||||
break;
|
tocstring += ' ';
|
||||||
Paragraph const & inset_par =
|
inset.asInsetText()->text().forOutliner(tocstring,TOC_ENTRY_LENGTH);
|
||||||
*static_cast<InsetArgument&>(inset).paragraphs().begin();
|
|
||||||
if (!par.labelString().empty())
|
|
||||||
tocstring = par.labelString() + ' ';
|
|
||||||
tocstring += inset_par.asString(AS_STR_INSETS);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int const toclevel = toc_item->dit_.text()->getTocLevel(toc_item->dit_.pit());
|
int const toclevel = toc_item->dit_.text()->
|
||||||
|
getTocLevel(toc_item->dit_.pit());
|
||||||
if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel
|
if (toclevel != Layout::NOT_IN_TOC && toclevel >= min_toclevel
|
||||||
&& tocstring.empty())
|
&& tocstring.empty())
|
||||||
tocstring = par.asString(AS_STR_LABEL | AS_STR_INSETS);
|
par.forOutliner(tocstring, TOC_ENTRY_LENGTH);
|
||||||
|
|
||||||
|
support::truncateWithEllipsis(tocstring, TOC_ENTRY_LENGTH);
|
||||||
const_cast<TocItem &>(*toc_item).str(tocstring);
|
const_cast<TocItem &>(*toc_item).str(tocstring);
|
||||||
|
|
||||||
buffer_->updateTocItem("tableofcontents", dit);
|
buffer_->updateTocItem("tableofcontents", dit);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "support/lassert.h"
|
#include "support/lassert.h"
|
||||||
|
#include "support/lstrings.h"
|
||||||
#include "support/debug.h"
|
#include "support/debug.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@ -394,9 +395,9 @@ void GuiCompleter::updateInline(Cursor const & cur, QString const & completion)
|
|||||||
docstring postfix = qstring_to_ucs4(completion.mid(prefix.length()));
|
docstring postfix = qstring_to_ucs4(completion.mid(prefix.length()));
|
||||||
|
|
||||||
// shorten it if necessary
|
// shorten it if necessary
|
||||||
if (lyxrc.completion_inline_dots != -1
|
if (lyxrc.completion_inline_dots != -1)
|
||||||
&& postfix.size() > unsigned(lyxrc.completion_inline_dots))
|
support::truncateWithEllipsis(postfix,
|
||||||
postfix = postfix.substr(0, lyxrc.completion_inline_dots - 1) + "...";
|
unsigned(lyxrc.completion_inline_dots));
|
||||||
|
|
||||||
// set inline completion at cursor position
|
// set inline completion at cursor position
|
||||||
size_t uniqueTo = max(longestUniqueCompletion().size(), prefix.size());
|
size_t uniqueTo = max(longestUniqueCompletion().size(), prefix.size());
|
||||||
|
@ -1852,7 +1852,7 @@ public:
|
|||||||
|
|
||||||
if (!dotted) {
|
if (!dotted) {
|
||||||
if (dottedPrefix_ && !prefix_.isEmpty())
|
if (dottedPrefix_ && !prefix_.isEmpty())
|
||||||
prefix_ += ".../";
|
prefix_ += ellipsisSlash_;
|
||||||
prefix_ += postfix_.front() + "/";
|
prefix_ += postfix_.front() + "/";
|
||||||
}
|
}
|
||||||
dottedPrefix_ = dotted && !prefix_.isEmpty();
|
dottedPrefix_ = dotted && !prefix_.isEmpty();
|
||||||
@ -1865,7 +1865,7 @@ public:
|
|||||||
return filename_;
|
return filename_;
|
||||||
|
|
||||||
bool dots = dottedPrefix_ || !postfix_.isEmpty();
|
bool dots = dottedPrefix_ || !postfix_.isEmpty();
|
||||||
return prefix_ + (dots ? ".../" : "") + filename_;
|
return prefix_ + (dots ? ellipsisSlash_ : "") + filename_;
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
QString forecastPathString() const
|
QString forecastPathString() const
|
||||||
@ -1874,7 +1874,7 @@ public:
|
|||||||
return displayString();
|
return displayString();
|
||||||
|
|
||||||
return prefix_
|
return prefix_
|
||||||
+ (dottedPrefix_ ? ".../" : "")
|
+ (dottedPrefix_ ? ellipsisSlash_ : "")
|
||||||
+ postfix_.front() + "/";
|
+ postfix_.front() + "/";
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
@ -1883,6 +1883,8 @@ public:
|
|||||||
int tab() const { return tab_; }
|
int tab() const { return tab_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// ".../"
|
||||||
|
static QString const ellipsisSlash_;
|
||||||
///
|
///
|
||||||
QString prefix_;
|
QString prefix_;
|
||||||
///
|
///
|
||||||
@ -1898,6 +1900,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
QString const DisplayPath::ellipsisSlash_ = QString(QChar(0x2026)) + "/";
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
bool operator<(DisplayPath const & a, DisplayPath const & b)
|
bool operator<(DisplayPath const & a, DisplayPath const & b)
|
||||||
{
|
{
|
||||||
|
@ -768,11 +768,9 @@ bool MenuDefinition::searchMenu(FuncRequest const & func, docstring_list & names
|
|||||||
QString limitStringLength(docstring const & str)
|
QString limitStringLength(docstring const & str)
|
||||||
{
|
{
|
||||||
size_t const max_item_length = 45;
|
size_t const max_item_length = 45;
|
||||||
|
docstring ret = str.substr(0, max_item_length + 1);
|
||||||
if (str.size() > max_item_length)
|
support::truncateWithEllipsis(ret, max_item_length);
|
||||||
return toqstr(str.substr(0, max_item_length - 3) + "...");
|
return toqstr(ret);
|
||||||
|
|
||||||
return toqstr(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ docstring Inset::toolTip(BufferView const &, int, int) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Inset::forOutliner(docstring &, size_t) const
|
void Inset::forOutliner(docstring &, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,8 @@ public:
|
|||||||
/// Appends a potentially abbreviated version of the inset to
|
/// Appends a potentially abbreviated version of the inset to
|
||||||
/// \param str. Intended for use by the TOC.
|
/// \param str. Intended for use by the TOC.
|
||||||
virtual void forOutliner(docstring & str,
|
virtual void forOutliner(docstring & str,
|
||||||
size_t maxlen = TOC_ENTRY_LENGTH) const;
|
size_t const maxlen = TOC_ENTRY_LENGTH,
|
||||||
|
bool const shorten = true) const;
|
||||||
|
|
||||||
/// can the contents of the inset be edited on screen ?
|
/// can the contents of the inset be edited on screen ?
|
||||||
// true for InsetCollapsables (not ButtonOnly) (not InsetInfo), InsetText
|
// true for InsetCollapsables (not ButtonOnly) (not InsetInfo), InsetText
|
||||||
|
@ -299,10 +299,11 @@ void InsetBranch::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetBranch::forOutliner(docstring & os, size_t maxlen) const
|
void InsetBranch::forOutliner(docstring & os, size_t const maxlen,
|
||||||
|
bool const shorten) const
|
||||||
{
|
{
|
||||||
if (isBranchSelected())
|
if (isBranchSelected())
|
||||||
InsetCollapsable::forOutliner(os, maxlen);
|
InsetCollapsable::forOutliner(os, maxlen, shorten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ private:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
void validate(LaTeXFeatures &) const;
|
void validate(LaTeXFeatures &) const;
|
||||||
///
|
///
|
||||||
|
@ -40,8 +40,7 @@ docstring InsetCaptionable::floatName(string const & type) const
|
|||||||
BufferParams const & bp = buffer().params();
|
BufferParams const & bp = buffer().params();
|
||||||
FloatList const & floats = bp.documentClass().floats();
|
FloatList const & floats = bp.documentClass().floats();
|
||||||
FloatList::const_iterator it = floats[type];
|
FloatList::const_iterator it = floats[type];
|
||||||
// FIXME UNICODE
|
return (it == floats.end()) ? from_utf8(type) : bp.B_(it->second.name());
|
||||||
return (it == floats.end()) ? from_ascii(type) : bp.B_(it->second.name());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -313,21 +313,13 @@ void InsetCitation::updateBuffer(ParIterator const &, UpdateType)
|
|||||||
{
|
{
|
||||||
if (!cache.recalculate && buffer().citeLabelsValid())
|
if (!cache.recalculate && buffer().citeLabelsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// The label may have changed, so we have to re-create it.
|
// The label may have changed, so we have to re-create it.
|
||||||
docstring const glabel = generateLabel();
|
docstring const glabel = generateLabel();
|
||||||
|
|
||||||
unsigned int const maxLabelChars = 45;
|
|
||||||
|
|
||||||
docstring label = glabel;
|
|
||||||
if (label.size() > maxLabelChars) {
|
|
||||||
label.erase(maxLabelChars - 3);
|
|
||||||
label += "...";
|
|
||||||
}
|
|
||||||
|
|
||||||
cache.recalculate = false;
|
cache.recalculate = false;
|
||||||
cache.generated_label = glabel;
|
cache.generated_label = glabel;
|
||||||
cache.screen_label = label;
|
unsigned int const maxLabelChars = 45;
|
||||||
|
cache.screen_label = glabel.substr(0, maxLabelChars);
|
||||||
|
support::truncateWithEllipsis(cache.screen_label, maxLabelChars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -406,7 +398,7 @@ void InsetCitation::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetCitation::forOutliner(docstring & os, size_t) const
|
void InsetCitation::forOutliner(docstring & os, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
os += screenLabel();
|
os += screenLabel();
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
void validate(LaTeXFeatures &) const {}
|
void validate(LaTeXFeatures &) const {}
|
||||||
///
|
///
|
||||||
|
@ -56,7 +56,7 @@ ParamInfo const & InsetHyperlink::findInfo(string const & /* cmdName */)
|
|||||||
|
|
||||||
docstring InsetHyperlink::screenLabel() const
|
docstring InsetHyperlink::screenLabel() const
|
||||||
{
|
{
|
||||||
docstring const temp = from_ascii("Hyperlink: ");
|
docstring const temp = _("Hyperlink: ");
|
||||||
|
|
||||||
docstring url;
|
docstring url;
|
||||||
|
|
||||||
@ -66,8 +66,9 @@ docstring InsetHyperlink::screenLabel() const
|
|||||||
|
|
||||||
// elide if long
|
// elide if long
|
||||||
if (url.length() > 30) {
|
if (url.length() > 30) {
|
||||||
url = url.substr(0, 10) + "..."
|
docstring end = url.substr(url.length() - 17, url.length());
|
||||||
+ url.substr(url.length() - 17, url.length());
|
support::truncateWithEllipsis(url, 13);
|
||||||
|
url += end;
|
||||||
}
|
}
|
||||||
return temp + url;
|
return temp + url;
|
||||||
}
|
}
|
||||||
@ -257,7 +258,7 @@ void InsetHyperlink::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetHyperlink::forOutliner(docstring & os, size_t) const
|
void InsetHyperlink::forOutliner(docstring & os, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
docstring const & n = getParam("name");
|
docstring const & n = getParam("name");
|
||||||
if (!n.empty()) {
|
if (!n.empty()) {
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
docstring toolTip(BufferView const & bv, int x, int y) const;
|
docstring toolTip(BufferView const & bv, int x, int y) const;
|
||||||
///
|
///
|
||||||
|
@ -596,7 +596,7 @@ void InsetIPAChar::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetIPAChar::forOutliner(docstring & os, size_t) const
|
void InsetIPAChar::forOutliner(docstring & os, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
odocstringstream ods;
|
odocstringstream ods;
|
||||||
plaintext(ods, OutputParams(0));
|
plaintext(ods, OutputParams(0));
|
||||||
|
@ -156,7 +156,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
InsetCode lyxCode() const { return IPACHAR_CODE; }
|
InsetCode lyxCode() const { return IPACHAR_CODE; }
|
||||||
/// We don't need \begin_inset and \end_inset
|
/// We don't need \begin_inset and \end_inset
|
||||||
|
@ -75,12 +75,8 @@ ParamInfo const & InsetNomencl::findInfo(string const & /* cmdName */)
|
|||||||
docstring InsetNomencl::screenLabel() const
|
docstring InsetNomencl::screenLabel() const
|
||||||
{
|
{
|
||||||
size_t const maxLabelChars = 25;
|
size_t const maxLabelChars = 25;
|
||||||
|
|
||||||
docstring label = _("Nom: ") + getParam("symbol");
|
docstring label = _("Nom: ") + getParam("symbol");
|
||||||
if (label.size() > maxLabelChars) {
|
support::truncateWithEllipsis(label, maxLabelChars);
|
||||||
label.erase(maxLabelChars - 3);
|
|
||||||
label += "...";
|
|
||||||
}
|
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,7 +331,7 @@ void InsetQuotes::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetQuotes::forOutliner(docstring & os, size_t) const
|
void InsetQuotes::forOutliner(docstring & os, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
os += displayString();
|
os += displayString();
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t maxlen) const;
|
void forOutliner(docstring &, size_t const maxlen, bool const) const;
|
||||||
|
|
||||||
///
|
///
|
||||||
void validate(LaTeXFeatures &) const;
|
void validate(LaTeXFeatures &) const;
|
||||||
|
@ -260,7 +260,7 @@ void InsetRef::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetRef::forOutliner(docstring & os, size_t) const
|
void InsetRef::forOutliner(docstring & os, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
// There's no need for details in the TOC, and a long label
|
// There's no need for details in the TOC, and a long label
|
||||||
// will just get in the way.
|
// will just get in the way.
|
||||||
@ -288,18 +288,13 @@ void InsetRef::updateBuffer(ParIterator const & it, UpdateType)
|
|||||||
label += getParam("name");
|
label += getParam("name");
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_label_ = label;
|
|
||||||
bool shortened = false;
|
|
||||||
unsigned int const maxLabelChars = 24;
|
unsigned int const maxLabelChars = 24;
|
||||||
if (screen_label_.size() > maxLabelChars) {
|
if (screen_label_.size() > maxLabelChars) {
|
||||||
screen_label_.erase(maxLabelChars - 3);
|
|
||||||
screen_label_ += "...";
|
|
||||||
shortened = true;
|
|
||||||
}
|
|
||||||
if (shortened)
|
|
||||||
tooltip_ = label;
|
tooltip_ = label;
|
||||||
else
|
support::truncateWithEllipsis(label, maxLabelChars);
|
||||||
|
} else
|
||||||
tooltip_ = from_ascii("");
|
tooltip_ = from_ascii("");
|
||||||
|
screen_label_ = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
void validate(LaTeXFeatures & features) const;
|
void validate(LaTeXFeatures & features) const;
|
||||||
///
|
///
|
||||||
|
@ -317,8 +317,7 @@ docstring InsetScript::toolTip(BufferView const &, int, int) const
|
|||||||
InsetText::plaintext(ods, rp, 200);
|
InsetText::plaintext(ods, rp, 200);
|
||||||
docstring content_tip = ods.str();
|
docstring content_tip = ods.str();
|
||||||
// shorten it if necessary
|
// shorten it if necessary
|
||||||
if (content_tip.size() >= 200)
|
support::truncateWithEllipsis(content_tip, 200);
|
||||||
content_tip = content_tip.substr(0, 197) + "...";
|
|
||||||
docstring res = scripttranslator_loc().find(params_.type);
|
docstring res = scripttranslator_loc().find(params_.type);
|
||||||
if (!content_tip.empty())
|
if (!content_tip.empty())
|
||||||
res += from_ascii(": ") + content_tip;
|
res += from_ascii(": ") + content_tip;
|
||||||
|
@ -845,7 +845,7 @@ void InsetSpace::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetSpace::forOutliner(docstring & os, size_t) const
|
void InsetSpace::forOutliner(docstring & os, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
// There's no need to be cute here.
|
// There's no need to be cute here.
|
||||||
os += " ";
|
os += " ";
|
||||||
|
@ -135,7 +135,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
bool hasSettings() const { return true; }
|
bool hasSettings() const { return true; }
|
||||||
///
|
///
|
||||||
|
@ -542,7 +542,8 @@ void InsetSpecialChar::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetSpecialChar::forOutliner(docstring & os, size_t) const
|
void InsetSpecialChar::forOutliner(docstring & os, size_t const,
|
||||||
|
bool const) const
|
||||||
{
|
{
|
||||||
odocstringstream ods;
|
odocstringstream ods;
|
||||||
plaintext(ods, OutputParams(0));
|
plaintext(ods, OutputParams(0));
|
||||||
|
@ -78,7 +78,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
InsetCode lyxCode() const { return SPECIALCHAR_CODE; }
|
InsetCode lyxCode() const { return SPECIALCHAR_CODE; }
|
||||||
/// We don't need \begin_inset and \end_inset
|
/// We don't need \begin_inset and \end_inset
|
||||||
|
@ -789,11 +789,12 @@ void InsetText::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetText::forOutliner(docstring & os, size_t maxlen) const
|
void InsetText::forOutliner(docstring & os, size_t const maxlen,
|
||||||
|
bool const shorten) const
|
||||||
{
|
{
|
||||||
if (!getLayout().isInToc())
|
if (!getLayout().isInToc())
|
||||||
return;
|
return;
|
||||||
text().forOutliner(os, maxlen, false);
|
text().forOutliner(os, maxlen, shorten);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
///
|
///
|
||||||
void addToToc(DocIterator const & di, bool output_active,
|
void addToToc(DocIterator const & di, bool output_active,
|
||||||
UpdateType utype) const;
|
UpdateType utype) const;
|
||||||
|
@ -2381,11 +2381,13 @@ void InsetMathHull::toString(odocstream & os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InsetMathHull::forOutliner(docstring & os, size_t) const
|
void InsetMathHull::forOutliner(docstring & os, size_t const, bool const) const
|
||||||
{
|
{
|
||||||
odocstringstream ods;
|
odocstringstream ods;
|
||||||
OutputParams op(0);
|
OutputParams op(0);
|
||||||
op.for_toc = true;
|
op.for_toc = true;
|
||||||
|
// FIXME: this results in spilling TeX into the LyXHTML output since the
|
||||||
|
// outliner is used to generate the LyXHTML list of figures/etc.
|
||||||
plaintext(ods, op);
|
plaintext(ods, op);
|
||||||
os += ods.str();
|
os += ods.str();
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ public:
|
|||||||
///
|
///
|
||||||
void toString(odocstream &) const;
|
void toString(odocstream &) const;
|
||||||
///
|
///
|
||||||
void forOutliner(docstring &, size_t) const;
|
void forOutliner(docstring &, size_t const, bool const) const;
|
||||||
|
|
||||||
/// get notification when the cursor leaves this inset
|
/// get notification when the cursor leaves this inset
|
||||||
bool notifyCursorLeaves(Cursor const & old, Cursor & cur);
|
bool notifyCursorLeaves(Cursor const & old, Cursor & cur);
|
||||||
|
@ -943,12 +943,10 @@ docstring const makeDisplayPath(string const & path, unsigned int threshold)
|
|||||||
// Yes, filename itself is too long.
|
// Yes, filename itself is too long.
|
||||||
// Pick the start and the end of the filename.
|
// Pick the start and the end of the filename.
|
||||||
dstr = from_utf8(onlyFileName(path));
|
dstr = from_utf8(onlyFileName(path));
|
||||||
docstring const head = dstr.substr(0, threshold / 2 - 3);
|
docstring::size_type const len = dstr.length();
|
||||||
|
if (len >= threshold)
|
||||||
docstring::size_type len = dstr.length();
|
dstr = support::truncateWithEllipsis(dstr, threshold / 2) +
|
||||||
docstring const tail =
|
dstr.substr(len - threshold / 2 - 2, len - 1);
|
||||||
dstr.substr(len - threshold / 2 - 2, len - 1);
|
|
||||||
dstr = head + from_ascii("...") + tail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return from_utf8(os::external_path(prefix + to_utf8(dstr)));
|
return from_utf8(os::external_path(prefix + to_utf8(dstr)));
|
||||||
|
@ -1201,6 +1201,17 @@ docstring const escape(docstring const & lab)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool truncateWithEllipsis(docstring & str, size_t const len)
|
||||||
|
{
|
||||||
|
if (str.size() <= len)
|
||||||
|
return false;
|
||||||
|
str.resize(len);
|
||||||
|
if (len > 0)
|
||||||
|
str[len - 1] = 0x2026;// HORIZONTAL ELLIPSIS
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// this doesn't check whether str is empty, so do that first.
|
// this doesn't check whether str is empty, so do that first.
|
||||||
@ -1224,7 +1235,7 @@ vector<docstring> wrapToVec(docstring const & str, int ind,
|
|||||||
size_t const i = s.find_last_of(' ', width - 1);
|
size_t const i = s.find_last_of(' ', width - 1);
|
||||||
if (i == docstring::npos || i <= size_t(ind)) {
|
if (i == docstring::npos || i <= size_t(ind)) {
|
||||||
// no space found
|
// no space found
|
||||||
s = s.substr(0, width - 3) + "...";
|
truncateWithEllipsis(s, width);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
retval.push_back(s.substr(0, i));
|
retval.push_back(s.substr(0, i));
|
||||||
@ -1253,7 +1264,6 @@ docstring wrap(docstring const & str, int const ind, size_t const width)
|
|||||||
docstring wrapParas(docstring const & str, int const indent,
|
docstring wrapParas(docstring const & str, int const indent,
|
||||||
size_t const width, size_t const maxlines)
|
size_t const width, size_t const maxlines)
|
||||||
{
|
{
|
||||||
docstring const dots = from_ascii("...");
|
|
||||||
if (str.empty())
|
if (str.empty())
|
||||||
return docstring();
|
return docstring();
|
||||||
|
|
||||||
@ -1272,15 +1282,15 @@ docstring wrapParas(docstring const & str, int const indent,
|
|||||||
tmp.resize(maxlines - curlines);
|
tmp.resize(maxlines - curlines);
|
||||||
docstring last = tmp.back();
|
docstring last = tmp.back();
|
||||||
size_t const lsize = last.size();
|
size_t const lsize = last.size();
|
||||||
if (lsize > width - 3) {
|
if (lsize > width - 1) {
|
||||||
size_t const i = last.find_last_of(' ', width - 3);
|
size_t const i = last.find_last_of(' ', width - 1);
|
||||||
if (i == docstring::npos || i <= size_t(indent))
|
if (i == docstring::npos || i <= size_t(indent))
|
||||||
// no space found
|
// no space found
|
||||||
last = last.substr(0, lsize - 3) + dots;
|
truncateWithEllipsis(last, lsize);
|
||||||
else
|
else
|
||||||
last = last.substr(0, i) + dots;
|
truncateWithEllipsis(last, i);
|
||||||
} else
|
} else
|
||||||
last += dots;
|
last.push_back(0x2026);//HORIZONTAL ELLIPSIS
|
||||||
tmp.pop_back();
|
tmp.pop_back();
|
||||||
tmp.push_back(last);
|
tmp.push_back(last);
|
||||||
}
|
}
|
||||||
|
@ -266,6 +266,29 @@ docstring const rsplit(docstring const & a, char_type delim);
|
|||||||
/// problems in latex labels.
|
/// problems in latex labels.
|
||||||
docstring const escape(docstring const & lab);
|
docstring const escape(docstring const & lab);
|
||||||
|
|
||||||
|
/// Truncates a string with an ellipsis at the end. Leaves str unchanged and
|
||||||
|
/// returns false if it is shorter than len. Otherwise resizes str to len, with
|
||||||
|
/// U+2026 HORIZONTAL ELLIPSIS at the end, and returns true.
|
||||||
|
///
|
||||||
|
/// Warning (Unicode): The cases where we want to truncate the text and it does
|
||||||
|
/// not end up converted into a QString for UI display must be really
|
||||||
|
/// rare. Whenever possible, we should prefer calling QFontMetrics::elidedText()
|
||||||
|
/// instead, which takes into account the actual length on the screen and the
|
||||||
|
/// layout direction (RTL or LTR). Or a similar function taking into account the
|
||||||
|
/// font metrics from the buffer view, which still has to be defined. Or set up
|
||||||
|
/// the widgets such that Qt elides the string automatically with the exact
|
||||||
|
/// needed width. Recall that not only graphemes vary greatly in width, but also
|
||||||
|
/// can be made of several code points. See:
|
||||||
|
/// <http://utf8everywhere.org/#myth.strlen>
|
||||||
|
///
|
||||||
|
/// What is acceptable is when we know that the string is probably going to be
|
||||||
|
/// elided by Qt anyway, and len is chosen such that our own ellipsis will only
|
||||||
|
/// be displayed in worst-case scenarios.
|
||||||
|
///
|
||||||
|
/// FIXME: apply those principles in the current code.
|
||||||
|
///
|
||||||
|
bool truncateWithEllipsis(docstring & str, size_t const len);
|
||||||
|
|
||||||
/// Word-wraps the provided docstring, returning a line-broken string
|
/// Word-wraps the provided docstring, returning a line-broken string
|
||||||
/// of width no wider than width, with the string broken at spaces.
|
/// of width no wider than width, with the string broken at spaces.
|
||||||
/// If the string cannot be broken appropriately, it returns something
|
/// If the string cannot be broken appropriately, it returns something
|
||||||
@ -274,6 +297,10 @@ docstring const escape(docstring const & lab);
|
|||||||
/// If indent is positive, then the first line is indented that many
|
/// If indent is positive, then the first line is indented that many
|
||||||
/// spaces. If it is negative, then successive lines are indented, as
|
/// spaces. If it is negative, then successive lines are indented, as
|
||||||
/// if the first line were "outdented".
|
/// if the first line were "outdented".
|
||||||
|
///
|
||||||
|
/// Warning (Unicode): uses truncateWithEllipsis() internally. Therefore it is
|
||||||
|
/// subject to the same warning and FIXME as above.
|
||||||
|
///
|
||||||
docstring wrap(docstring const & str, int const indent = 0,
|
docstring wrap(docstring const & str, int const indent = 0,
|
||||||
size_t const width = 80);
|
size_t const width = 80);
|
||||||
|
|
||||||
@ -281,6 +308,10 @@ docstring wrap(docstring const & str, int const indent = 0,
|
|||||||
/// that may contain embedded newlines.
|
/// that may contain embedded newlines.
|
||||||
/// \param numlines Don't return more than numlines lines. If numlines
|
/// \param numlines Don't return more than numlines lines. If numlines
|
||||||
/// is 0, we return everything.
|
/// is 0, we return everything.
|
||||||
|
///
|
||||||
|
/// Warning (Unicode): uses truncateWithEllipsis() internally. Therefore it is
|
||||||
|
/// subject to the same warning and FIXME as above.
|
||||||
|
///
|
||||||
docstring wrapParas(docstring const & str, int const indent = 0,
|
docstring wrapParas(docstring const & str, int const indent = 0,
|
||||||
size_t const width = 80, size_t const maxlines = 10);
|
size_t const width = 80, size_t const maxlines = 10);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user