Skip to content

Commit

Permalink
Fix read-only problem & menu paste not working issue
Browse files Browse the repository at this point in the history
  • Loading branch information
donho committed Nov 10, 2023
1 parent 1eafbe8 commit 3d8fceb
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 39 deletions.
11 changes: 11 additions & 0 deletions PowerEditor/src/NppCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
91 changes: 53 additions & 38 deletions PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,45 +588,17 @@ LRESULT ScintillaEditView::scintillaNew_Proc(HWND hwnd, UINT Message, WPARAM wPa
SHORT shift = GetKeyState(VK_SHIFT);
if ((ctrl & 0x8000) && !(alt & 0x8000) && !(shift & 0x8000))
{
// "MSDEVColumnSelect" is column format from Scintilla
CLIPFORMAT cfColumnSelect = static_cast<CLIPFORMAT>(::RegisterClipboardFormat(TEXT("MSDEVColumnSelect")));
if (IsClipboardFormatAvailable(cfColumnSelect) && OpenClipboard(NULL))
Buffer* buf = getCurrentBuffer();
bool isRO = buf->isReadOnly();
size_t numSelections = execute(SCI_GETSELECTIONS);
if (numSelections > 1 && !isRO)
{
HANDLE clipboardData = ::GetClipboardData(CF_UNICODETEXT);
::GlobalSize(clipboardData);
LPVOID clipboardDataPtr = ::GlobalLock(clipboardData);
if (clipboardDataPtr)
if (pasteToMultiSelection())
{
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

size_t numSelections = execute(SCI_GETSELECTIONS);
if (numSelections > 1 && 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);

// Hack for preventing the char "SYN" (0x16) from being adding into edit zone
Buffer* buf = getCurrentBuffer();
buf->setUserReadOnly(true);

_isMultiPasteActive = true; // It will be set false with WM_KEYUP message
return TRUE;
}
// 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
}
}
}
Expand Down Expand Up @@ -4168,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 @@ -4456,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;
}
3 changes: 2 additions & 1 deletion 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

0 comments on commit 3d8fceb

Please sign in to comment.