How to replace some characters from selected text of QPlainTextEdit
-
wrote on 27 Oct 2021, 08:17 last edited by
I want to remove
--
characters from selected text and keep the remaining text as selected. So far I've been able to insert--
in selection BUT couldn't select the first--
after insertion: Here is how it is now:First, initially the cursor was blinking. As soon as I insert text in
QDropEvent
:void CodeEditor::dropEvent(QDropEvent *event) { QFile file (event->mimeData()->text().remove("file:///")); file.open(QIODevice::ReadOnly); QTextStream in(&file); insertPlainText(in.readAll()); file.close(); setFocus(); }
it stops blinking. How to make that blink again. Second, the document I've inserted has single tab BUT the single
\t
becomes\t\t
automatically.Third, when I select some lines/word and click comment/uncomment button, it inserts
--
but doesn't select the first--
. Here's what I've so far for comment/uncomment:void QueryView::commentUncomment() { auto cursor = editor->textCursor(); if(!cursor.hasSelection()) return; if(cursor.selectedText().contains("--")){ //uncomment / replace -- with "" } // will be in else block int start = cursor.selectionStart(); int end = cursor.selectionEnd(); cursor.setPosition(start); int startLine = cursor.blockNumber(); cursor.setPosition(end); int endLine = cursor.blockNumber(); int numberOfLines = endLine - startLine + 1; cursor.setPosition(start); //cursor.setKeepPositionOnInsert(true); for(int i = 0; i < numberOfLines; ++i) { cursor.insertText("--"); cursor.movePosition(QTextCursor::NextBlock); } //cursor.setPosition(start - 2, QTextCursor::KeepAnchor); }
Last, I want to remove those
--
, if there's any in the selection. -
@Gojir4, tried that BUT doesn't work.
wrote on 27 Oct 2021, 13:52 last edited by@Emon-Haque Here is what I have for a code editor, similar to what you are doing. It works well on my side:
#ifndef QT_NO_DRAGANDDROP void MainWindow::dragEnterEvent(QDragEnterEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ for(const QUrl &url : e->mimeData()->urls()){ if(url.isLocalFile()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ e->acceptProposedAction(); return; } } } } } void MainWindow::dropEvent(QDropEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ e->acceptProposedAction(); QStringList files; for(const QUrl &url : e->mimeData()->urls()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ files << fi.absoluteFilePath(); } } if(!files.isEmpty()){ // Open files m_wCodeEditorMdi->openJsFiles(files); } } } void MainWindow::dragMoveEvent(QDragMoveEvent *e) { e->acceptProposedAction(); } void MainWindow::dragLeaveEvent(QDragLeaveEvent *e) { e->accept(); } #endif
Hope this helps
-
I want to remove
--
characters from selected text and keep the remaining text as selected. So far I've been able to insert--
in selection BUT couldn't select the first--
after insertion: Here is how it is now:First, initially the cursor was blinking. As soon as I insert text in
QDropEvent
:void CodeEditor::dropEvent(QDropEvent *event) { QFile file (event->mimeData()->text().remove("file:///")); file.open(QIODevice::ReadOnly); QTextStream in(&file); insertPlainText(in.readAll()); file.close(); setFocus(); }
it stops blinking. How to make that blink again. Second, the document I've inserted has single tab BUT the single
\t
becomes\t\t
automatically.Third, when I select some lines/word and click comment/uncomment button, it inserts
--
but doesn't select the first--
. Here's what I've so far for comment/uncomment:void QueryView::commentUncomment() { auto cursor = editor->textCursor(); if(!cursor.hasSelection()) return; if(cursor.selectedText().contains("--")){ //uncomment / replace -- with "" } // will be in else block int start = cursor.selectionStart(); int end = cursor.selectionEnd(); cursor.setPosition(start); int startLine = cursor.blockNumber(); cursor.setPosition(end); int endLine = cursor.blockNumber(); int numberOfLines = endLine - startLine + 1; cursor.setPosition(start); //cursor.setKeepPositionOnInsert(true); for(int i = 0; i < numberOfLines; ++i) { cursor.insertText("--"); cursor.movePosition(QTextCursor::NextBlock); } //cursor.setPosition(start - 2, QTextCursor::KeepAnchor); }
Last, I want to remove those
--
, if there's any in the selection.wrote on 27 Oct 2021, 08:36 last edited by@Emon-Haque said in How to replace some characters from selected text of QPlainTextEdit:
BUT couldn't select the first -- after insertion
I would change the code like this:
auto &cursor = editor->textCursor(); ... cursor.setPosition(start - 2, QTextCursor::MoveAnchor); cursor.setPosition(end, QTextCursor::KeepAnchor); cursor.select(QTextCursor::BlockUnderCursor);
-
@Emon-Haque said in How to replace some characters from selected text of QPlainTextEdit:
BUT couldn't select the first -- after insertion
I would change the code like this:
auto &cursor = editor->textCursor(); ... cursor.setPosition(start - 2, QTextCursor::MoveAnchor); cursor.setPosition(end, QTextCursor::KeepAnchor); cursor.select(QTextCursor::BlockUnderCursor);
wrote on 27 Oct 2021, 08:43 last edited by deleted385@KroMignon, I've added last 3 line at the end of the function BUT it still doesn't select the first
--
. Also, triedcursor.clearSelection()
before those 3 line, doesn't work. -
@KroMignon, I've added last 3 line at the end of the function BUT it still doesn't select the first
--
. Also, triedcursor.clearSelection()
before those 3 line, doesn't work.wrote on 27 Oct 2021, 09:03 last edited by KroMignon@Emon-Haque said in How to replace some characters from selected text of QPlainTextEdit:
I've added last 3 line at the end of the function BUT it still doesn't select the first --
Hmm strange, you could try to use
movePosition()
:cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
EDIT: I am stupid, sorry, but you use a copy constructor to get the cursor:
auto cursor = editor->textCursor();
Do you have change it to get a reference?
auto &cursor = editor->textCursor();
Or update the cursor of the editor at the end:
auto cursor = editor->textCursor(); ... cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); edit->setTextCursor(cursor);
-
@KroMignon, I've added last 3 line at the end of the function BUT it still doesn't select the first
--
. Also, triedcursor.clearSelection()
before those 3 line, doesn't work.wrote on 27 Oct 2021, 09:09 last edited by@Emon-Haque Note that you need to call
editor->setTextCursor(cursor)
to make changes effective on the text edit. -
@Emon-Haque said in How to replace some characters from selected text of QPlainTextEdit:
I've added last 3 line at the end of the function BUT it still doesn't select the first --
Hmm strange, you could try to use
movePosition()
:cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2);
EDIT: I am stupid, sorry, but you use a copy constructor to get the cursor:
auto cursor = editor->textCursor();
Do you have change it to get a reference?
auto &cursor = editor->textCursor();
Or update the cursor of the editor at the end:
auto cursor = editor->textCursor(); ... cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); edit->setTextCursor(cursor);
wrote on 27 Oct 2021, 10:40 last edited by deleted385@KroMignon, if I do
auto &cursor = editor->textCursor();
I get thiserror: non-const lvalue reference to type 'QTextCursor' cannot bind to a temporary of type 'QTextCursor'.
instead of those 3 lines if I add these 2 lines at the end:
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); edit->setTextCursor(cursor);
it removes the selection and moves cursor to left from the end of selection. The following works:
cursor.setPosition(start); if(numberOfLines > 1){ for(int i = 0; i < numberOfLines; ++i) { cursor.insertText("--"); cursor.movePosition(QTextCursor::NextBlock); } cursor.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor, numberOfLines); } else { cursor.insertText("--"); cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, len + 2); // len = cursor.selectedText().length() } editor->setTextCursor(cursor);
don't know whether there's any better approach.
For the cursor blinking I've to add
QPlainTextEdit::dropEvent(event);
in drop event BUT if I add that, It inserts file name in the editor. -
@Emon-Haque Note that you need to call
editor->setTextCursor(cursor)
to make changes effective on the text edit.wrote on 27 Oct 2021, 10:44 last edited by@Gojir4, that's necessary, thanks.
-
@KroMignon, if I do
auto &cursor = editor->textCursor();
I get thiserror: non-const lvalue reference to type 'QTextCursor' cannot bind to a temporary of type 'QTextCursor'.
instead of those 3 lines if I add these 2 lines at the end:
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); edit->setTextCursor(cursor);
it removes the selection and moves cursor to left from the end of selection. The following works:
cursor.setPosition(start); if(numberOfLines > 1){ for(int i = 0; i < numberOfLines; ++i) { cursor.insertText("--"); cursor.movePosition(QTextCursor::NextBlock); } cursor.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor, numberOfLines); } else { cursor.insertText("--"); cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, len + 2); // len = cursor.selectedText().length() } editor->setTextCursor(cursor);
don't know whether there's any better approach.
For the cursor blinking I've to add
QPlainTextEdit::dropEvent(event);
in drop event BUT if I add that, It inserts file name in the editor.wrote on 27 Oct 2021, 12:29 last edited byFor the cursor blinking I've to add QPlainTextEdit::dropEvent(event); in drop event BUT if I add that, It inserts file name in the editor.
I think you need to call
event->acceptProposedAction()
when you accept the drop action. But I'm not sure this is related to you issue. -
wrote on 27 Oct 2021, 13:43 last edited by deleted385
With a lot of Left, Right, Up, Down, Anchor etc., so far I've achieved this:
so I can comment in and out an inline selection whole day BUT for multiline, still couldn't figure out why does it keep selecting the next line! Here's what I have right now:
void QueryView::commentLines() { auto cursor = editor->textCursor(); if(!cursor.hasSelection()) return; auto text = cursor.selectedText(); int start = cursor.selectionStart(); int end = cursor.selectionEnd(); cursor.setPosition(start); int startLine = cursor.blockNumber(); cursor.setPosition(end); int endLine = cursor.blockNumber(); int numberOfLines = endLine - startLine + 1; cursor.setPosition(start); if(text.startsWith("--")){ if(numberOfLines > 1){ for(int i = 0; i < numberOfLines; ++i){ while (cursor.position() < end) { cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); if(cursor.selectedText().contains("--")) cursor.insertText(cursor.selectedText().replace("--", "")); } cursor.movePosition(QTextCursor::NextBlock); } cursor.setPosition(start, QTextCursor::MoveAnchor); cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, numberOfLines); } else{ int count = 0; while (cursor.position() < end) { cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); if(cursor.selectedText().contains("--")) { cursor.insertText(cursor.selectedText().replace("--", "")); count += 2; } } cursor.setPosition(start, QTextCursor::MoveAnchor); cursor.setPosition(end - count, QTextCursor::KeepAnchor); } } else{ if(numberOfLines > 1){ for(int i = 0; i < numberOfLines; ++i) { cursor.insertText("--"); cursor.movePosition(QTextCursor::NextBlock); } cursor.movePosition(QTextCursor::Up, QTextCursor::KeepAnchor, numberOfLines); } else { cursor.insertText("--"); cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 2); cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, text.length() + 2); } } editor->setTextCursor(cursor); }
The file name is at the top because of calling
QPlainTextEdit::dropEvent(event);
indropEvent
. -
For the cursor blinking I've to add QPlainTextEdit::dropEvent(event); in drop event BUT if I add that, It inserts file name in the editor.
I think you need to call
event->acceptProposedAction()
when you accept the drop action. But I'm not sure this is related to you issue.wrote on 27 Oct 2021, 13:45 last edited by@Gojir4, tried that BUT doesn't work.
-
@Gojir4, tried that BUT doesn't work.
wrote on 27 Oct 2021, 13:52 last edited by@Emon-Haque Here is what I have for a code editor, similar to what you are doing. It works well on my side:
#ifndef QT_NO_DRAGANDDROP void MainWindow::dragEnterEvent(QDragEnterEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ for(const QUrl &url : e->mimeData()->urls()){ if(url.isLocalFile()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ e->acceptProposedAction(); return; } } } } } void MainWindow::dropEvent(QDropEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ e->acceptProposedAction(); QStringList files; for(const QUrl &url : e->mimeData()->urls()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ files << fi.absoluteFilePath(); } } if(!files.isEmpty()){ // Open files m_wCodeEditorMdi->openJsFiles(files); } } } void MainWindow::dragMoveEvent(QDragMoveEvent *e) { e->acceptProposedAction(); } void MainWindow::dragLeaveEvent(QDragLeaveEvent *e) { e->accept(); } #endif
Hope this helps
-
@Emon-Haque Here is what I have for a code editor, similar to what you are doing. It works well on my side:
#ifndef QT_NO_DRAGANDDROP void MainWindow::dragEnterEvent(QDragEnterEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ for(const QUrl &url : e->mimeData()->urls()){ if(url.isLocalFile()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ e->acceptProposedAction(); return; } } } } } void MainWindow::dropEvent(QDropEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ e->acceptProposedAction(); QStringList files; for(const QUrl &url : e->mimeData()->urls()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ files << fi.absoluteFilePath(); } } if(!files.isEmpty()){ // Open files m_wCodeEditorMdi->openJsFiles(files); } } } void MainWindow::dragMoveEvent(QDragMoveEvent *e) { e->acceptProposedAction(); } void MainWindow::dragLeaveEvent(QDragLeaveEvent *e) { e->accept(); } #endif
Hope this helps
wrote on 27 Oct 2021, 14:03 last edited by deleted385@Gojir4, I've these:
void CodeEditor::dragEnterEvent(QDragEnterEvent *event) { if(event->mimeData()->text().contains('\n')){ event->ignore(); return; } event->acceptProposedAction(); //QPlainTextEdit::dragEnterEvent(event); } void CodeEditor::dropEvent(QDropEvent *event) { event->acceptProposedAction(); //QPlainTextEdit::dropEvent(event); QFile file (event->mimeData()->text().remove("file:///")); file.open(QIODevice::ReadOnly); QTextStream in(&file); insertPlainText(in.readAll()); file.close(); }
if i don't uncomment
QPlainTextEdit::dropEvent(event);
insidedropEvent
, cursor doesn't blink and stuck at the end. If I click somewhere else cursor doesn't apparently move BUT I can type where I clicked. -
@Gojir4, I've these:
void CodeEditor::dragEnterEvent(QDragEnterEvent *event) { if(event->mimeData()->text().contains('\n')){ event->ignore(); return; } event->acceptProposedAction(); //QPlainTextEdit::dragEnterEvent(event); } void CodeEditor::dropEvent(QDropEvent *event) { event->acceptProposedAction(); //QPlainTextEdit::dropEvent(event); QFile file (event->mimeData()->text().remove("file:///")); file.open(QIODevice::ReadOnly); QTextStream in(&file); insertPlainText(in.readAll()); file.close(); }
if i don't uncomment
QPlainTextEdit::dropEvent(event);
insidedropEvent
, cursor doesn't blink and stuck at the end. If I click somewhere else cursor doesn't apparently move BUT I can type where I clicked.wrote on 27 Oct 2021, 14:14 last edited by@Emon-Haque I suspect that the drag&drop event is in a unfinished state and the cursor stop blinking. calling e->accept() in dragLeaveEvent should terminate the drag&drop action and restore the cursor blinking
-
@Emon-Haque I suspect that the drag&drop event is in a unfinished state and the cursor stop blinking. calling e->accept() in dragLeaveEvent should terminate the drag&drop action and restore the cursor blinking
wrote on 27 Oct 2021, 14:18 last edited by@Gojir4, exactly, now with
dragMove
anddragleave
with your content. it blinks. Thanks. For frag and drop, I always have to implement all 4 of those? -
@Gojir4, exactly, now with
dragMove
anddragleave
with your content. it blinks. Thanks. For frag and drop, I always have to implement all 4 of those?wrote on 27 Oct 2021, 14:24 last edited by@Emon-Haque Honestly I don't know. I started recently using drag and drop. the doc says
For more sophisticated applications, reimplementing dragMoveEvent() and dragLeaveEvent() will let you make certain parts of your widgets sensitive to drop events, and give you more control over drag and drop in your application.
I'm not really understanding what it means. But yeah maybe my solution is over-complicated
-
wrote on 27 Oct 2021, 14:31 last edited by deleted385
Here's a hacky solution. In the multiline uncomment section if I do this I can comment / uncomment whole day:
if(numberOfLines > 1){ for(int i = 0; i < numberOfLines; ++i){ while (cursor.position() < end) { cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor); if(cursor.selectedText().contains("--")) cursor.insertText(cursor.selectedText().replace("--", "")); } cursor.movePosition(QTextCursor::NextBlock); } cursor.setPosition(start, QTextCursor::MoveAnchor); cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, numberOfLines - 2); cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor); }
For now I'll move forward with that as I'm new to Qt Widget app and, hopefully, will keep exploring more.
-
@Emon-Haque Here is what I have for a code editor, similar to what you are doing. It works well on my side:
#ifndef QT_NO_DRAGANDDROP void MainWindow::dragEnterEvent(QDragEnterEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ for(const QUrl &url : e->mimeData()->urls()){ if(url.isLocalFile()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ e->acceptProposedAction(); return; } } } } } void MainWindow::dropEvent(QDropEvent *e) { if(e->mimeData()->hasUrls() && e->mimeData()->hasFormat("text/uri-list")){ e->acceptProposedAction(); QStringList files; for(const QUrl &url : e->mimeData()->urls()){ QFileInfo fi(url.toLocalFile()); if(fi.exists() && (fi.suffix().startsWith("js"))){ files << fi.absoluteFilePath(); } } if(!files.isEmpty()){ // Open files m_wCodeEditorMdi->openJsFiles(files); } } } void MainWindow::dragMoveEvent(QDragMoveEvent *e) { e->acceptProposedAction(); } void MainWindow::dragLeaveEvent(QDragLeaveEvent *e) { e->accept(); } #endif
Hope this helps
wrote on 27 Oct 2021, 14:35 last edited by deleted385@Gojir4, I wanted to accept this as answer, BUT wrongly I've selected mine. How to remove the currently accepted and set yours as accepted?
-
@Gojir4, I wanted to accept this as answer, BUT wrongly I've selected mine. How to remove the currently accepted and set yours as accepted?
wrote on 27 Oct 2021, 14:41 last edited by JonB@Emon-Haque I think you just do so from the vertical "..." at the right-hand side of the new answer you want to accept.
1/18