[PATCH] Parse html links in the Notes section.
Dirk Hohndel
dirk at hohndel.org
Tue Oct 13 07:32:49 PDT 2015
On Mon, Oct 12, 2015 at 10:08:35PM -0700, K. "pestophagous" Heller wrote:
> In the spirit of "Do the simplest thing that could
> possibly work": capture Ctrl+leftclick mouse events
> in the Notes area. If the string under the clicked
> position is a valid url, then launch it.
>
> Many common URI schemes will work. Typing a url that
> starts with https:// will work. So will mailto: and
> file://
>
> See #733
Neat. I have a few concerns with the code, but the idea itself is a cool
addition. Obviously post-4.5 :-)
> diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
> index e97812c..35cda6e 100644
> --- a/qt-ui/maintab.cpp
> +++ b/qt-ui/maintab.cpp
> @@ -202,6 +202,11 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
> connect(ui.diveNotesMessage, &KMessageWidget::showAnimationFinished,
> ui.location, &DiveLocationLineEdit::fixPopupPosition);
>
> + //if (true). // to make URL clickability optional, simply branch here based on a preference.
So why would this be optional? In general I aim for fewer options, not
more, but maybe I'm missing something?
> diff --git a/qt-ui/simplewidgets.cpp b/qt-ui/simplewidgets.cpp
> index 57fc56b..e16d05f 100644
> --- a/qt-ui/simplewidgets.cpp
> +++ b/qt-ui/simplewidgets.cpp
> @@ -735,3 +737,137 @@ void MultiFilter::closeFilter()
> MultiFilterSortModel::instance()->clearFilter();
> hide();
> }
> +
> +TextHyperlinkEventFilter::TextHyperlinkEventFilter(QTextEdit *txtEdit) : QObject(txtEdit),
> + textEdit(txtEdit),
> + scrollView(textEdit->viewport())
That's not our typical indentation scheme (admittedly we aren't super
consistent about it, but still...)
> +{
> + // lesson learned. install filter on viewport:
> + // http://stackoverflow.com/questions/31581453/qplaintextedit-double-click-event
This comment is very much about your process of writing code... I haven't
followed the link, but could you instead summarize WHY this is the way to
go in the comment?
> + const bool isCtrlClick = evt->type() == QEvent::MouseButtonPress &&
> + static_cast<QMouseEvent *>(evt)->modifiers() & Qt::ControlModifier &&
> + static_cast<QMouseEvent *>(evt)->button() == Qt::LeftButton;
Silly question - how does this translate on the Mac? Is it actually the
key labled "Ctrl" on all platforms or is this the command key on the Mac?
> + return false; // (slight lie). indicate that we didn't do anything with the event.
Why?
> +void TextHyperlinkEventFilter::handleUrlClick(const QString &urlStr)
> +{
> + if (!urlStr.isEmpty()) {
> + QUrl url(urlStr, QUrl::StrictMode);
> + QDesktopServices::openUrl(url);
Are there any security implications to keep in mind here? I haven't
studied what openURL() is capable of doing, just asking.
> +void TextHyperlinkEventFilter::handleUrlTooltip(const QString &urlStr, const QPoint &pos)
> +{
> + if (urlStr.isEmpty()) {
> + QToolTip::hideText();
> + } else {
> + QToolTip::showText(pos, tr("Ctrl+click to visit %1").arg(urlStr));
And this is why I asked about "Ctrl" above - is this tooltip correct on
the Mac?
> +QString TextHyperlinkEventFilter::fromCursorTilWhitespace(QTextCursor *cursor, const bool searchBackwards)
Ok, first function where I'm not quite sure what it does and why it does
it. Could you add a brief comment?
> +{
> + QString result;
> + QString grownText;
> + QString noSpaces;
> + bool movedOk = false;
> +
> + do {
> + result = grownText; // this is a no-op on the first visit.
> +
> + if (searchBackwards) {
> + movedOk = cursor->movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
> + } else {
> + movedOk = cursor->movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
> + }
> +
> + grownText = cursor->selectedText();
> + noSpaces = grownText.simplified().replace(" ", "");
> + } while (grownText == noSpaces && movedOk);
> +
> + // while growing the selection forwards, we have an extra step to do:
> + if (!searchBackwards) {
> + /*
> + The cursor keeps jumping to the start of the next word.
> + (for example) in the string "mn.abcd.edu is the spot" you land at
> + m,a,e,i (the 'i' in 'is). if we stop at e, then we only capture
> + "mn.abcd." for the url (wrong). So we have to go to 'i', to
> + capture "mn.abcd.edu " (with trailing space), and then clean it up.
> + */
This looks whitespace damaged
> + QStringList list = grownText.split(QRegExp("\\s"), QString::SkipEmptyParts);
> + if (!list.isEmpty()) {
> + result = list[0];
> + }
> + }
> +
> + return result;
> +}
> +
> +QString TextHyperlinkEventFilter::tryToFormulateUrl(QTextCursor *cursor)
> +{
> + // If instead of (or in addition to) QTextCursor::WordUnderCursor we could
> + // also have some Qt feature like 'unbroken-string-of-nonwhitespace-under-cursor',
> + // then the following logic would not be necessary to do.
> + // http://stackoverflow.com/questions/19262064/pyqt-qtextcursor-wordundercursor-not-working-as-expected
Again, this is a comment that makes total sense when you write it, but is
less useful when someone else is trying to read it / understand the code.
> +
> + cursor->select(QTextCursor::WordUnderCursor);
> + QString maybeUrlStr = cursor->selectedText();
> +
> + const bool soFarSoGood = !maybeUrlStr.simplified().replace(" ", "").isEmpty();
> +
> + if (soFarSoGood && !stringMeetsOurUrlRequirements(maybeUrlStr)) {
> + // If we don't yet have a full url, try to expand til we get one. Note:
> + // after requesting WordUnderCursor, empirically (all platforms, in
> + // Qt5), the 'anchor' is just past the end of the word.
> +
> + QTextCursor cursor2(*cursor);
> + QString left = fromCursorTilWhitespace(cursor, true /*searchBackwards*/);
> + QString right = fromCursorTilWhitespace(&cursor2, false);
> + maybeUrlStr = left + right;
> + }
OK, I think I now know what the function above is needed for - it still
deserves a bit more commentary
Overall a really good contribution. As you can tell, most of my comments
are nit-picks and small stuff - I don't think there's anything
fundamentally wrong here. But it's enough that I would like to ask you to
resubmit this.
Thanks
/D
More information about the subsurface
mailing list