From d155f0326a1bb098d7df3eebfb04e00391e4c8e9 Mon Sep 17 00:00:00 2001 From: Udo Hoffmann Date: Sat, 14 Nov 2020 19:52:35 +0100 Subject: [PATCH] Add context menu with "Copy link" ability Close #2435, close #9154 --- PowerEditor/installer/nativeLang/english.xml | 1 + .../nativeLang/english_customizable.xml | 1 + PowerEditor/src/NppBigSwitch.cpp | 3 ++- PowerEditor/src/NppCommands.cpp | 13 ++++++++++++ PowerEditor/src/NppNotification.cpp | 8 +++---- .../src/ScitillaComponent/ScintillaEditView.h | 15 +++++++++++++ .../WinControls/ContextMenu/ContextMenu.cpp | 21 ++++++++++++++++++- .../src/WinControls/ContextMenu/ContextMenu.h | 2 +- PowerEditor/src/menuCmdID.h | 1 + 9 files changed, 57 insertions(+), 8 deletions(-) diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index 08bdd7f1..38d05980 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -160,6 +160,7 @@ The comments are here for explanation, it's not necessary to translate them. + diff --git a/PowerEditor/installer/nativeLang/english_customizable.xml b/PowerEditor/installer/nativeLang/english_customizable.xml index 5f232458..80d21548 100644 --- a/PowerEditor/installer/nativeLang/english_customizable.xml +++ b/PowerEditor/installer/nativeLang/english_customizable.xml @@ -153,6 +153,7 @@ + diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index d2d18fb1..edf44927 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -1516,7 +1516,8 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa ::GetCursorPos(&p); ContextMenu scintillaContextmenu; std::vector& tmp = nppParam.getContextMenuItems(); - scintillaContextmenu.create(hwnd, tmp, _mainMenuHandle); + bool copyLink = (_pEditView->getSelectedTextCount() == 0) && _pEditView->getIndicatorRange(URL_INDIC); + scintillaContextmenu.create(hwnd, tmp, _mainMenuHandle, copyLink); scintillaContextmenu.display(p); return TRUE; } diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index e3f5bf12..7554b937 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -305,6 +305,19 @@ void Notepad_plus::command(int id) checkClipboard(); break; + case IDM_EDIT_COPY_LINK: + { + int startPos = 0, endPos = 0, curPos = 0; + if (_pEditView->getIndicatorRange(URL_INDIC, &startPos, &endPos, &curPos)) + { + _pEditView->execute(SCI_SETSEL, startPos, endPos); + _pEditView->execute(WM_COPY); + checkClipboard(); + _pEditView->execute(SCI_SETSEL, curPos, curPos); + break; + } + } + case IDM_EDIT_COPY_BINARY: case IDM_EDIT_CUT_BINARY: { diff --git a/PowerEditor/src/NppNotification.cpp b/PowerEditor/src/NppNotification.cpp index 412a62df..66ae39c4 100644 --- a/PowerEditor/src/NppNotification.cpp +++ b/PowerEditor/src/NppNotification.cpp @@ -820,11 +820,9 @@ BOOL Notepad_plus::notify(SCNotification *notification) else { // Double click with no modifiers // Check wether cursor is within URL - auto indicMsk = notifyView->execute(SCI_INDICATORALLONFOR, notification->position); - if (!(indicMsk & (1 << URL_INDIC))) break; - auto startPos = notifyView->execute(SCI_INDICATORSTART, URL_INDIC, notification->position); - auto endPos = notifyView->execute(SCI_INDICATOREND, URL_INDIC, notification->position); - if ((notification->position < startPos) || (notification->position > endPos)) break; + int startPos = 0, endPos = 0; + if (!notifyView->getIndicatorRange(URL_INDIC, &startPos, &endPos)) + break; // WM_LBUTTONUP goes to opening browser instead of Scintilla here, because the mouse is not captured. // The missing message causes mouse cursor flicker as soon as the mouse cursor is moved to a position outside the text editing area. diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h index 1c203574..a6c515a5 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h @@ -560,6 +560,21 @@ public: execute(SCI_INDICATORCLEARRANGE, docStart, docEnd-docStart); }; + bool getIndicatorRange(int indicatorNumber, int *from = NULL, int *to = NULL, int *cur = NULL) { + int curPos = static_cast(execute(SCI_GETCURRENTPOS)); + int indicMsk = static_cast(execute(SCI_INDICATORALLONFOR, curPos)); + if (!(indicMsk & (1 << indicatorNumber))) + return false; + int startPos = static_cast(execute(SCI_INDICATORSTART, indicatorNumber, curPos)); + int endPos = static_cast(execute(SCI_INDICATOREND, indicatorNumber, curPos)); + if ((curPos < startPos) || (curPos > endPos)) + return false; + if (from) *from = startPos; + if (to) *to = endPos; + if (cur) *cur = curPos; + return true; + }; + static LanguageName langNames[L_EXTERNAL+1]; void bufferUpdated(Buffer * buffer, int mask); diff --git a/PowerEditor/src/WinControls/ContextMenu/ContextMenu.cpp b/PowerEditor/src/WinControls/ContextMenu/ContextMenu.cpp index 1232b7d8..22e5de2c 100644 --- a/PowerEditor/src/WinControls/ContextMenu/ContextMenu.cpp +++ b/PowerEditor/src/WinControls/ContextMenu/ContextMenu.cpp @@ -27,6 +27,9 @@ #include "ContextMenu.h" +#include "menuCmdID.h" +#include "Parameters.h" +#include "localization.h" MenuItemUnit::MenuItemUnit(unsigned long cmdID, const TCHAR *itemName, const TCHAR *parentFolderName) : _cmdID(cmdID) { @@ -53,7 +56,7 @@ ContextMenu::~ContextMenu() } -void ContextMenu::create(HWND hParent, const std::vector & menuItemArray, const HMENU mainMenuHandle) +void ContextMenu::create(HWND hParent, const std::vector & menuItemArray, const HMENU mainMenuHandle, bool copyLink) { _hParent = hParent; _hMenu = ::CreatePopupMenu(); @@ -127,5 +130,21 @@ void ContextMenu::create(HWND hParent, const std::vector & menuIte GetMenuItemInfo(mainMenuHandle, item._cmdID, FALSE, &mii); SetMenuItemInfo(_hMenu, item._cmdID, FALSE, &mii); } + + if (copyLink && (item._cmdID == IDM_EDIT_COPY)) + { + NativeLangSpeaker* nativeLangSpeaker = NppParameters::getInstance().getNativeLangSpeaker(); + generic_string localized = nativeLangSpeaker->getNativeLangMenuString(IDM_EDIT_COPY_LINK); + if (localized.length() == 0) + localized = L"Copy link"; + memset(&mii, 0, sizeof(mii)); + mii.cbSize = sizeof(MENUITEMINFO); + mii.fMask = MIIM_ID | MIIM_STRING | MIIM_STATE; + mii.wID = IDM_EDIT_COPY_LINK; + mii.dwTypeData = (TCHAR*) localized.c_str(); + mii.fState = MFS_ENABLED; + int c = GetMenuItemCount(_hMenu); + SetMenuItemInfo(_hMenu, c - 1, TRUE, & mii); + } } } diff --git a/PowerEditor/src/WinControls/ContextMenu/ContextMenu.h b/PowerEditor/src/WinControls/ContextMenu/ContextMenu.h index 6adad783..cbb217a8 100644 --- a/PowerEditor/src/WinControls/ContextMenu/ContextMenu.h +++ b/PowerEditor/src/WinControls/ContextMenu/ContextMenu.h @@ -47,7 +47,7 @@ class ContextMenu final public: ~ContextMenu(); - void create(HWND hParent, const std::vector & menuItemArray, const HMENU mainMenuHandle = NULL); + void create(HWND hParent, const std::vector & menuItemArray, const HMENU mainMenuHandle = NULL, bool copyLink = false); bool isCreated() const {return _hMenu != NULL;} void display(const POINT & p) const { diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index fa797bc0..9ed0d692 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -174,6 +174,7 @@ #define IDM_EDIT_REMOVE_ANY_DUP_LINES (IDM_EDIT + 79) #define IDM_EDIT_SORTLINES_LEXICO_CASE_INSENS_ASCENDING (IDM_EDIT + 80) #define IDM_EDIT_SORTLINES_LEXICO_CASE_INSENS_DESCENDING (IDM_EDIT + 81) + #define IDM_EDIT_COPY_LINK (IDM_EDIT + 82) #define IDM_EDIT_AUTOCOMPLETE (50000 + 0) #define IDM_EDIT_AUTOCOMPLETE_CURRENTFILE (50000 + 1)