diff --git a/NEWS.md b/NEWS.md index 3d8cdbdf..52af3ea2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ Red Panda C++ Version 1.1.0 - enhancement: delete in files view's context menu - change: drag&drop in files view default to move - fix: rename macro doesn't work in project + - fix: can't remove a shortcut + - enhancement: hide all menu actions in the option dialog's shortcut panel Red Panda C++ Version 1.0.10 - fix: modify watch doesn't work diff --git a/RedPandaIDE/cpprefacter.cpp b/RedPandaIDE/cpprefacter.cpp index bfa4e0ff..2b3bc4e6 100644 --- a/RedPandaIDE/cpprefacter.cpp +++ b/RedPandaIDE/cpprefacter.cpp @@ -313,8 +313,18 @@ void CppRefacter::renameSymbolInFile(const QString &filename, const PStatement & Editor * oldEditor = pMainWindow->editorList()->getOpenedEditorByFilename(filename); if (oldEditor) { + BufferCoord oldXY=oldEditor->caretXY(); + int topLine = oldEditor->topLine(); + int leftChar = oldEditor->leftChar(); + oldEditor->beginUndoBlock(); + oldEditor->addLeftTopToUndo(); + oldEditor->addCaretToUndo(); oldEditor->selectAll(); oldEditor->setSelText(newContents.join(oldEditor->lineBreak())); + oldEditor->setTopLine(topLine); + oldEditor->setLeftChar(leftChar); + oldEditor->setCaretXY(oldXY); + oldEditor->endUndoBlock(); } else { QByteArray realEncoding; QFile file(filename); diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index ae7472ce..5b0eb40b 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -4261,9 +4261,14 @@ void Editor::reformat() args, content); #endif + if (newContent.isEmpty()) + return; int oldTopLine = topLine(); BufferCoord mOldCaret = caretXY(); + beginUndoBlock(); + addLeftTopToUndo(); + addCaretToUndo(); selectAll(); SynEditorOptions oldOptions = getOptions(); SynEditorOptions newOptions = oldOptions; @@ -4273,6 +4278,7 @@ void Editor::reformat() setCaretXY(mOldCaret); setTopLine(oldTopLine); setOptions(oldOptions); + endUndoBlock(); reparse(); checkSyntaxInBack(); reparseTodo(); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 4d865a20..837a001a 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -5334,13 +5334,7 @@ void MainWindow::on_actionReformat_Code_triggered() { Editor* e = mEditorList->getEditor(); if (e) { - BufferCoord oldXY=e->caretXY(); - int topLine = e->topLine(); - int leftChar = e->leftChar(); e->reformat(); - e->setTopLine(topLine); - e->setLeftChar(leftChar); - e->setCaretXY(oldXY); e->activate(); } } @@ -6360,13 +6354,8 @@ void MainWindow::on_actionRename_Symbol_triggered() parser->parseFile(editor->filename(), editor->inProject(), false, false); } CppRefacter refactor; - BufferCoord oldXY=editor->caretXY(); - int topLine = editor->topLine(); - int leftChar = editor->leftChar(); + refactor.renameSymbol(editor,oldCaretXY,word,newWord); - editor->setTopLine(topLine); - editor->setLeftChar(leftChar); - editor->setCaretXY(oldXY); editor->reparse(); } diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index 426b218a..a04d15c5 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -858,7 +858,7 @@ QTabWidget::South - 3 + 6 diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index 5befc097..4d033e70 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -454,6 +454,20 @@ void SynEdit::endUndoBlock() mUndoList->EndBlock(); } +void SynEdit::addCaretToUndo() +{ + BufferCoord p=caretXY(); + mUndoList->AddChange(SynChangeReason::crCaret,p,p,"", activeSelectionMode()); +} + +void SynEdit::addLeftTopToUndo() +{ + BufferCoord p; + p.Char = leftChar(); + p.Line = topLine(); + mUndoList->AddChange(SynChangeReason::crLeftTop,p,p,"", activeSelectionMode()); +} + void SynEdit::beginUpdate() { incPaintLock(); @@ -4334,6 +4348,18 @@ void SynEdit::doUndoItem() Item->changeSelMode()); internalSetCaretXY(Item->changeStartPos()); break; + case SynChangeReason::crLeftTop: + BufferCoord p; + p.Char = leftChar(); + p.Line = topLine(); + mRedoList->AddChange( + Item->changeReason(), + p, + p, "", + Item->changeSelMode()); + setLeftChar(Item->changeStartPos().Char); + setTopLine(Item->changeStartPos().Line); + break; case SynChangeReason::crSelection: mRedoList->AddChange( Item->changeReason(), @@ -4609,6 +4635,18 @@ void SynEdit::doRedoItem() mActiveSelectionMode); internalSetCaretXY(Item->changeStartPos()); break; + case SynChangeReason::crLeftTop: + BufferCoord p; + p.Char = leftChar(); + p.Line = topLine(); + mUndoList->AddChange( + Item->changeReason(), + p, + p, "", + Item->changeSelMode()); + setLeftChar(Item->changeStartPos().Char); + setTopLine(Item->changeStartPos().Line); + break; case SynChangeReason::crSelection: mUndoList->AddChange( Item->changeReason(), diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index 31c1a964..c92c7b6e 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -268,6 +268,8 @@ public: void beginUndoBlock(); void endUndoBlock(); + void addCaretToUndo(); + void addLeftTopToUndo(); //Commands virtual void cutToClipboard() { commandProcessor(SynEditorCommand::ecCut);} @@ -277,7 +279,10 @@ public: virtual void redo() { commandProcessor(SynEditorCommand::ecRedo);} virtual void zoomIn() { commandProcessor(SynEditorCommand::ecZoomIn);} virtual void zoomOut() { commandProcessor(SynEditorCommand::ecZoomOut);} - virtual void selectAll() { commandProcessor(SynEditorCommand::ecSelectAll);} + virtual void selectAll() { + mUndoList->AddChange(SynChangeReason::crSelection,mBlockBegin,mBlockEnd,"", activeSelectionMode()); + commandProcessor(SynEditorCommand::ecSelectAll); + } virtual void tab() { commandProcessor(SynEditorCommand::ecTab);} virtual void shifttab() { commandProcessor(SynEditorCommand::ecShiftTab);} virtual void toggleComment() { commandProcessor(SynEditorCommand::ecToggleComment);} diff --git a/RedPandaIDE/qsynedit/TextBuffer.h b/RedPandaIDE/qsynedit/TextBuffer.h index b659260f..b991f395 100644 --- a/RedPandaIDE/qsynedit/TextBuffer.h +++ b/RedPandaIDE/qsynedit/TextBuffer.h @@ -171,6 +171,7 @@ enum class SynChangeReason {crInsert, crPaste, crDragDropInsert, crPasteBegin, crPasteEnd, //for pasting, since it might do a lot of operations crSpecial1Begin, crSpecial1End, crSpecial2Begin, crSpecial2End, + crLeftTop, crCaret, //just restore the Caret, allowing better Undo behavior crSelection, //restore Selection crNothing, diff --git a/RedPandaIDE/settingsdialog/environmentshortcutwidget.cpp b/RedPandaIDE/settingsdialog/environmentshortcutwidget.cpp index c3b65fd8..d9f01f04 100644 --- a/RedPandaIDE/settingsdialog/environmentshortcutwidget.cpp +++ b/RedPandaIDE/settingsdialog/environmentshortcutwidget.cpp @@ -19,6 +19,7 @@ #include "../mainwindow.h" #include "../widgets/shortcutinputedit.h" #include +#include #include EnvironmentShortcutWidget::EnvironmentShortcutWidget(const QString& name, const QString& group, QWidget *parent) : @@ -62,8 +63,8 @@ void EnvironmentShortcutModel::reload() { beginResetModel(); mShortcuts.clear(); - QList actions = pMainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly); QList menus = pMainWindow->menuBar()->findChildren(); + QList actions = pMainWindow->findChildren(QString(), Qt::FindDirectChildrenOnly); foreach( const QMenu* menu, menus) { if (menu->title().isEmpty()) continue; @@ -76,6 +77,7 @@ void EnvironmentShortcutModel::reload() item->fullPath = QString("%1 : %2").arg(tr("action"),action->text()); item->action = action; item->shortcut = action->shortcut().toString().trimmed(); + item->isAction = true; mShortcuts.append(item); } } @@ -120,18 +122,22 @@ bool EnvironmentShortcutModel::setData(const QModelIndex &index, const QVariant PEnvironmentShortcut item = mShortcuts[index.row()]; QString s = value.toString().trimmed(); if (s!=item->shortcut) { - for (int i=0;ishortcut) { - QMessageBox::critical(nullptr, - tr("Error"), - tr("Shortcut \"%1\" is used by \"%2\".") - .arg(s,mShortcuts[i]->fullPath)); - return false; + if (s.isEmpty()) { + item->shortcut=""; + } else { + for (int i=0;ishortcut) { + QMessageBox::critical(nullptr, + tr("Error"), + tr("Shortcut \"%1\" is used by \"%2\".") + .arg(s,mShortcuts[i]->fullPath)); + return false; + } } + item->shortcut = value.toString(); } - item->shortcut = value.toString(); emit shortcutChanged(); } return true; @@ -178,12 +184,13 @@ void EnvironmentShortcutModel::loadShortCutsOfMenu(const QMenu *menu, QList actions = menu->actions(); foreach (QAction* action,actions) { - if (!action->text().isEmpty()) { + if (!action->text().isEmpty() && action->menu()==nullptr) { PEnvironmentShortcut item = std::make_shared(); item->name = action->objectName(); item->fullPath = QString("%1 > %2").arg(menu->title(),action->text()); item->action = action; item->shortcut = action->shortcut().toString().trimmed(); + item->isAction = true; mShortcuts.append(item); } globalActions.removeAll(action); diff --git a/RedPandaIDE/shortcutmanager.cpp b/RedPandaIDE/shortcutmanager.cpp index 40d6f188..2f832eda 100644 --- a/RedPandaIDE/shortcutmanager.cpp +++ b/RedPandaIDE/shortcutmanager.cpp @@ -66,6 +66,10 @@ void ShortcutManager::load() if (shortcut->name.isEmpty()) continue; shortcut->shortcut = object["shortcut"].toString(); + if (object["isAction"].isNull()) + shortcut->isAction = true; + else + shortcut->isAction = object["isAction"].toBool(); mShortcuts.insert(shortcut->name,shortcut); } } @@ -86,6 +90,7 @@ void ShortcutManager::save() QJsonObject object; object["name"]=shortcut->name; object["shortcut"]=shortcut->shortcut; + object["isAction"]=shortcut->isAction; array.append(object); } QJsonDocument doc; @@ -119,7 +124,7 @@ void ShortcutManager::applyTo(QList actions) void ShortcutManager::applyTo(QAction *action) { PEnvironmentShortcut item = mShortcuts.value(action->objectName(), PEnvironmentShortcut()); - if (item) { + if (item && item->isAction) { action->setShortcut(QKeySequence::fromString(item->shortcut)); } } diff --git a/RedPandaIDE/shortcutmanager.h b/RedPandaIDE/shortcutmanager.h index 94480589..d5bc4497 100644 --- a/RedPandaIDE/shortcutmanager.h +++ b/RedPandaIDE/shortcutmanager.h @@ -22,12 +22,15 @@ #include class QAction; +class QToolButton; struct EnvironmentShortcut { QString name; QString fullPath; QString shortcut; QAction* action; + QToolButton* button; + bool isAction; }; using PEnvironmentShortcut = std::shared_ptr;