How to replace some characters from selected text of QPlainTextEdit
-
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. -
@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 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);
-
@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. -
@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);
-
@Emon-Haque Note that you need to call
editor->setTextCursor(cursor)
to make changes effective on the text edit. -
@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. -
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. -
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
. -
@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
-
@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. -
@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 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
-
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 I think you just do so from the vertical "..." at the right-hand side of the new answer you want to accept.