Skip to content

Commit cb47b60

Browse files
committed
#3695 editor: restore full-link hover and Ctrl+Click
Signed-off-by: Patrizio Bekerle <patrizio@bekerle.com>
1 parent 5493285 commit cb47b60

3 files changed

Lines changed: 36 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# QOwnNotes Changelog
22

3+
## 26.8.7
4+
5+
- The pointer cursor now appears over the entire inline Markdown link and
6+
<kbd>Ctrl</kbd> + click opens it from both its label and URL, while the URL part
7+
remains highlighted on hover
8+
(for [#3695](https://github.com/pbek/QOwnNotes/issues/3695))
9+
310
## 26.8.6
411

512
- Fixed unmatched or malformed Markdown emphasis, underline, and strikeout markers

src/widgets/qownnotesmarkdowntextedit.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,8 @@ QOwnNotesMarkdownTextEdit::QOwnNotesMarkdownTextEdit(QWidget *parent)
634634
refreshFoldingSidebar();
635635
}
636636

637-
bool QOwnNotesMarkdownTextEdit::hoveredMarkdownLink(const QPoint &position,
638-
QTextCursor *linkCursor) {
637+
bool QOwnNotesMarkdownTextEdit::hoveredMarkdownLink(const QPoint &position, QTextCursor *linkCursor,
638+
bool includeLinkLabel) {
639639
QTextCursor cursor = cursorForPosition(position);
640640
const QTextBlock block = cursor.block();
641641
const QString text = block.text();
@@ -646,6 +646,8 @@ bool QOwnNotesMarkdownTextEdit::hoveredMarkdownLink(const QPoint &position,
646646
const QString &parsedText = it.key();
647647
QString hoverText = parsedText;
648648
int hoverOffset = 0;
649+
QString hitText = parsedText;
650+
int hitOffset = 0;
649651

650652
const int destinationSeparator = parsedText.lastIndexOf(QStringLiteral("]("));
651653
const int destinationStart = destinationSeparator >= 0
@@ -654,12 +656,28 @@ bool QOwnNotesMarkdownTextEdit::hoveredMarkdownLink(const QPoint &position,
654656
if (destinationStart >= 0) {
655657
hoverText = it.value();
656658
hoverOffset = destinationStart;
659+
if (includeLinkLabel) {
660+
// Exclude a preceding checkbox that the shared parser may include.
661+
const int labelStart =
662+
parsedText.lastIndexOf(QLatin1Char('['), destinationSeparator);
663+
if (labelStart > 0) {
664+
hitText = parsedText.mid(labelStart);
665+
hitOffset = labelStart;
666+
}
667+
} else {
668+
hitText = hoverText;
669+
hitOffset = hoverOffset;
670+
}
657671
} else if (parsedText.startsWith(QLatin1Char('<')) &&
658672
parsedText.endsWith(QLatin1Char('>'))) {
659673
const int urlStart = parsedText.indexOf(it.value(), 1);
660674
if (urlStart >= 0) {
661675
hoverText = it.value();
662676
hoverOffset = urlStart;
677+
if (!includeLinkLabel) {
678+
hitText = hoverText;
679+
hitOffset = hoverOffset;
680+
}
663681
}
664682
} else {
665683
// The shared parser can include a preceding checkbox in reference
@@ -670,6 +688,8 @@ bool QOwnNotesMarkdownTextEdit::hoveredMarkdownLink(const QPoint &position,
670688
if (labelStart > 0) {
671689
hoverText = parsedText.mid(labelStart);
672690
hoverOffset = labelStart;
691+
hitText = hoverText;
692+
hitOffset = hoverOffset;
673693
}
674694
}
675695
}
@@ -678,7 +698,9 @@ bool QOwnNotesMarkdownTextEdit::hoveredMarkdownLink(const QPoint &position,
678698
while (parsedStart >= 0) {
679699
const int hoverStart = parsedStart + hoverOffset;
680700
const int hoverEnd = hoverStart + hoverText.size();
681-
if (positionInBlock >= hoverStart && positionInBlock < hoverEnd) {
701+
const int hitStart = parsedStart + hitOffset;
702+
const int hitEnd = hitStart + hitText.size();
703+
if (positionInBlock >= hitStart && positionInBlock < hitEnd) {
682704
if (linkCursor != nullptr) {
683705
linkCursor->setPosition(block.position() + hoverStart);
684706
linkCursor->setPosition(block.position() + hoverEnd, QTextCursor::KeepAnchor);
@@ -718,7 +740,7 @@ void QOwnNotesMarkdownTextEdit::mouseMoveEvent(QMouseEvent *event) {
718740

719741
void QOwnNotesMarkdownTextEdit::updateHoveredLink(const QPoint &position, bool enabled) {
720742
QTextCursor linkCursor(document());
721-
const bool isLink = enabled && hoveredMarkdownLink(position, &linkCursor);
743+
const bool isLink = enabled && hoveredMarkdownLink(position, &linkCursor, true);
722744
viewport()->setCursor(isLink ? Qt::PointingHandCursor : Qt::IBeamCursor);
723745

724746
const int start = isLink ? linkCursor.selectionStart() : -1;
@@ -3332,7 +3354,7 @@ bool QOwnNotesMarkdownTextEdit::eventFilter(QObject *obj, QEvent *event) {
33323354
auto *mouseEvent = static_cast<QMouseEvent *>(event);
33333355
if (mouseEvent->button() == Qt::LeftButton &&
33343356
mouseEvent->modifiers().testFlag(Qt::ControlModifier) &&
3335-
!hoveredMarkdownLink(mouseEvent->pos(), nullptr)) {
3357+
!hoveredMarkdownLink(mouseEvent->pos(), nullptr, true)) {
33363358
// Do not let the base parser activate a link from an overly broad
33373359
// Markdown match, such as the checkbox preceding an inline link.
33383360
return QPlainTextEdit::eventFilter(obj, event);

src/widgets/qownnotesmarkdowntextedit.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ class QOwnNotesMarkdownTextEdit : public QMarkdownTextEdit {
232232
void requestMarkdownLspFormatting(bool useSelection);
233233
void paintMarkdownImagePreviews();
234234
void refreshFoldingSidebar();
235-
bool hoveredMarkdownLink(const QPoint &position, QTextCursor *linkCursor);
235+
bool hoveredMarkdownLink(const QPoint &position, QTextCursor *linkCursor,
236+
bool includeLinkLabel = false);
236237
void updateHoveredLink(const QPoint &position, bool enabled);
237238
void clearHoveredLink();
238239
static bool isHeadingBlock(const QTextBlock &block, int *level = nullptr);

0 commit comments

Comments
 (0)