Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make multi-select Copy/Paste behaviour as same as column edit's one #14338

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions PowerEditor/src/NppBigSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2276,6 +2276,13 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
return TRUE;
}

case NPPM_INTERNAL_CHECKUNDOREDOSTATE:
{
checkClipboard();
checkUndoState();
return TRUE;
}

case WM_QUERYENDSESSION:
{
// app should return TRUE or FALSE immediately upon receiving this message,
Expand Down
15 changes: 13 additions & 2 deletions PowerEditor/src/NppCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,8 @@ void Notepad_plus::command(int id)
GlobalUnlock(hglbLenCopy);

// Place the handle on the clipboard.
UINT f = RegisterClipboardFormat(CF_NPPTEXTLEN);
SetClipboardData(f, hglbLenCopy);
UINT cf_nppTextLen = RegisterClipboardFormat(CF_NPPTEXTLEN);
SetClipboardData(cf_nppTextLen, hglbLenCopy);

CloseClipboard();

Expand All @@ -442,6 +442,17 @@ void Notepad_plus::command(int id)
case IDM_EDIT_PASTE:
{
std::lock_guard<std::mutex> lock(command_mutex);

size_t numSelections = _pEditView->execute(SCI_GETSELECTIONS);
Buffer* buf = getCurrentBuffer();
bool isRO = buf->isReadOnly();
if (numSelections > 1 && !isRO)
{
bool isPasteDone = _pEditView->pasteToMultiSelection();
if (isPasteDone)
return;
}

intptr_t eolMode = _pEditView->execute(SCI_GETEOLMODE);
_pEditView->execute(SCI_PASTE);
_pEditView->execute(SCI_CONVERTEOLS, eolMode);
Expand Down
79 changes: 78 additions & 1 deletion PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,16 @@ LRESULT ScintillaEditView::scintillaNew_Proc(HWND hwnd, UINT Message, WPARAM wPa
::SendMessage(_hParent, WM_NOTIFY, LINKTRIGGERED, reinterpret_cast<LPARAM>(&notification));

}
else if (wParam == 'V')
{
if (_isMultiPasteActive)
{
Buffer* buf = getCurrentBuffer();
buf->setUserReadOnly(false);
_isMultiPasteActive = false;
::SendMessage(_hParent, NPPM_INTERNAL_CHECKUNDOREDOSTATE, 0, 0);
}
}
break;
}

Expand Down Expand Up @@ -570,6 +580,30 @@ LRESULT ScintillaEditView::scintillaNew_Proc(HWND hwnd, UINT Message, WPARAM wPa
}
}
break;

case 'V':
{
SHORT ctrl = GetKeyState(VK_CONTROL);
SHORT alt = GetKeyState(VK_MENU);
SHORT shift = GetKeyState(VK_SHIFT);
if ((ctrl & 0x8000) && !(alt & 0x8000) && !(shift & 0x8000))
{
Buffer* buf = getCurrentBuffer();
bool isRO = buf->isReadOnly();
size_t numSelections = execute(SCI_GETSELECTIONS);
if (numSelections > 1 && !isRO)
{
if (pasteToMultiSelection())
{
// Hack for preventing the char "SYN" (0x16) from being adding into edit zone
buf->setUserReadOnly(true);

_isMultiPasteActive = true; // It will be set false with WM_KEYUP message
}
}
}
}
break;
}
}
break;
Expand Down Expand Up @@ -4106,7 +4140,7 @@ void ScintillaEditView::changeTextDirection(bool isRTL)
}
}

generic_string ScintillaEditView::getEOLString()
generic_string ScintillaEditView::getEOLString() const
{
intptr_t eol_mode = execute(SCI_GETEOLMODE);
if (eol_mode == SC_EOL_CRLF)
Expand Down Expand Up @@ -4394,3 +4428,46 @@ void ScintillaEditView::removeAnyDuplicateLines()
}
}
}

bool ScintillaEditView::pasteToMultiSelection() const
{
size_t numSelections = execute(SCI_GETSELECTIONS);
if (numSelections <= 1)
return false;

// "MSDEVColumnSelect" is column format from Scintilla
CLIPFORMAT cfColumnSelect = static_cast<CLIPFORMAT>(::RegisterClipboardFormat(TEXT("MSDEVColumnSelect")));
if (IsClipboardFormatAvailable(cfColumnSelect) && OpenClipboard(NULL))
{
HANDLE clipboardData = ::GetClipboardData(CF_UNICODETEXT);
::GlobalSize(clipboardData);
LPVOID clipboardDataPtr = ::GlobalLock(clipboardData);
if (clipboardDataPtr)
{
wstring clipboardStr = (const TCHAR*)clipboardDataPtr;
::GlobalUnlock(clipboardData);
::CloseClipboard();

vector<wstring> stringArray;
stringSplit(clipboardStr, getEOLString(), stringArray);
stringArray.erase(stringArray.cend() - 1); // remove the last empty string

if (numSelections == stringArray.size())
{
execute(SCI_BEGINUNDOACTION);
for (size_t i = 0; i < numSelections; ++i)
{
LRESULT posStart = execute(SCI_GETSELECTIONNSTART, i);
LRESULT posEnd = execute(SCI_GETSELECTIONNEND, i);
replaceTarget(stringArray[i].c_str(), posStart, posEnd);
posStart += stringArray[i].length();
execute(SCI_SETSELECTIONNSTART, i, posStart);
execute(SCI_SETSELECTIONNEND, i, posStart);
}
execute(SCI_ENDUNDOACTION);
return true;
}
}
}
return false;
}
5 changes: 3 additions & 2 deletions PowerEditor/src/ScintillaComponent/ScintillaEditView.h
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ friend class Finder;
(_codepage == CP_JAPANESE) || (_codepage == CP_KOREAN));
};
void scrollPosToCenter(size_t pos);
generic_string getEOLString();
generic_string getEOLString() const;
void setBorderEdge(bool doWithBorderEdge);
void sortLines(size_t fromLine, size_t toLine, ISorter *pSort);
void changeTextDirection(bool isRTL);
Expand All @@ -777,6 +777,7 @@ friend class Finder;
void markedTextToClipboard(int indiStyle, bool doAll = false);
void removeAnyDuplicateLines();
bool expandWordSelection();
bool pasteToMultiSelection() const;

protected:
static bool _SciInit;
Expand Down Expand Up @@ -811,8 +812,8 @@ friend class Finder;
BufferStyleMap _hotspotStyles;

intptr_t _beginSelectPosition = -1;

static std::string _defaultCharList;
bool _isMultiPasteActive = false;

//Lexers and Styling
void restyleBuffer();
Expand Down
1 change: 1 addition & 0 deletions PowerEditor/src/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@
#define NPPM_INTERNAL_NPCLAUNCHSTYLECONF (NOTEPADPLUS_USER_INTERNAL + 74)
#define NPPM_INTERNAL_CLOSEDOC (NOTEPADPLUS_USER_INTERNAL + 75)
#define NPPM_INTERNAL_EXTERNALLEXERBUFFER (NOTEPADPLUS_USER_INTERNAL + 76)
#define NPPM_INTERNAL_CHECKUNDOREDOSTATE (NOTEPADPLUS_USER_INTERNAL + 77)

// See Notepad_plus_msgs.h
//#define NOTEPADPLUS_USER (WM_USER + 1000)
Expand Down
4 changes: 2 additions & 2 deletions scintilla/src/Editor.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4337,15 +4337,15 @@ void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
std::sort(rangesInOrder.begin(), rangesInOrder.end());
for (const SelectionRange &current : rangesInOrder) {
text.append(RangeText(current.Start().Position(), current.End().Position()));
if (sel.selType == Selection::SelTypes::rectangle) {
if (rangesInOrder.size() > 1) {
if (pdoc->eolMode != EndOfLine::Lf)
text.push_back('\r');
if (pdoc->eolMode != EndOfLine::Cr)
text.push_back('\n');
}
}
ss->Copy(text, pdoc->dbcsCodePage,
vs.styles[StyleDefault].characterSet, sel.IsRectangular(), sel.selType == Selection::SelTypes::lines);
vs.styles[StyleDefault].characterSet, rangesInOrder.size() > 1, sel.selType == Selection::SelTypes::lines);
}
}

Expand Down