- enhancement: add option "max undo memory usage" in the options / editor / misc page

This commit is contained in:
Roy Qu 2022-10-11 22:33:09 +08:00
parent 975d90c8f1
commit 5f0371cb5b
13 changed files with 1081 additions and 1079 deletions

View File

@ -12,6 +12,7 @@ Red Panda C++ Version 1.5
- enhancement: save project's bookmark in it's own bookmark file - enhancement: save project's bookmark in it's own bookmark file
- enhancement: project and non-project files use different bookmark view (auto switch when switch editors) - enhancement: project and non-project files use different bookmark view (auto switch when switch editors)
- enhancement: auto merge when save bookmarks. - enhancement: auto merge when save bookmarks.
- enhancement: add option "max undo memory usage" in the options / editor / misc page
Red Panda C++ Version 1.4 Red Panda C++ Version 1.4

View File

@ -4554,6 +4554,7 @@ void Editor::applySettings()
} }
this->setUndoLimit(pSettings->editor().undoLimit()); this->setUndoLimit(pSettings->editor().undoLimit());
this->setUndoMemoryUsage(pSettings->editor().undoMemoryUsage());
setMouseWheelScrollSpeed(pSettings->editor().mouseWheelScrollSpeed()); setMouseWheelScrollSpeed(pSettings->editor().mouseWheelScrollSpeed());
setMouseSelectionScrollSpeed(pSettings->editor().mouseSelectionScrollSpeed()); setMouseSelectionScrollSpeed(pSettings->editor().mouseSelectionScrollSpeed());

View File

@ -652,6 +652,16 @@ void Settings::Editor::setUndoLimit(int newUndoLimit)
mUndoLimit = newUndoLimit; mUndoLimit = newUndoLimit;
} }
int Settings::Editor::undoMemoryUsage() const
{
return mUndoMemoryUsage;
}
void Settings::Editor::setUndoMemoryUsage(int newUndoMemoryUsage)
{
mUndoMemoryUsage = newUndoMemoryUsage;
}
bool Settings::Editor::highlightCurrentWord() const bool Settings::Editor::highlightCurrentWord() const
{ {
return mHighlightCurrentWord; return mHighlightCurrentWord;
@ -1231,6 +1241,7 @@ void Settings::Editor::doSave()
saveValue("default_file_cpp",mDefaultFileCpp); saveValue("default_file_cpp",mDefaultFileCpp);
saveValue("auto_detect_file_encoding",mAutoDetectFileEncoding); saveValue("auto_detect_file_encoding",mAutoDetectFileEncoding);
saveValue("undo_limit",mUndoLimit); saveValue("undo_limit",mUndoLimit);
saveValue("undo_memory_usage", mUndoMemoryUsage);
//tooltips //tooltips
saveValue("enable_tooltips",mEnableTooltips); saveValue("enable_tooltips",mEnableTooltips);
@ -1371,7 +1382,8 @@ void Settings::Editor::doLoad()
else else
mDefaultEncoding = value("default_encoding", ENCODING_UTF8).toByteArray(); mDefaultEncoding = value("default_encoding", ENCODING_UTF8).toByteArray();
mAutoDetectFileEncoding = boolValue("auto_detect_file_encoding",true); mAutoDetectFileEncoding = boolValue("auto_detect_file_encoding",true);
mUndoLimit = intValue("undo_limit",0); mUndoLimit = intValue("undo_limit",5000);
mUndoMemoryUsage = intValue("undo_memory_usage", 50);
//tooltips //tooltips
mEnableTooltips = boolValue("enable_tooltips",true); mEnableTooltips = boolValue("enable_tooltips",true);

View File

@ -367,6 +367,9 @@ public:
int undoLimit() const; int undoLimit() const;
void setUndoLimit(int newUndoLimit); void setUndoLimit(int newUndoLimit);
int undoMemoryUsage() const;
void setUndoMemoryUsage(int newUndoMemoryUsage);
private: private:
//General //General
// indents // indents
@ -474,6 +477,7 @@ public:
bool mAutoLoadLastFiles; bool mAutoLoadLastFiles;
bool mDefaultFileCpp; bool mDefaultFileCpp;
int mUndoLimit; int mUndoLimit;
int mUndoMemoryUsage;
//hints tooltip //hints tooltip

View File

@ -65,6 +65,7 @@ void EditorMiscWidget::doLoad()
ui->cbEncodingDetail->setCurrentText(defaultEncoding); ui->cbEncodingDetail->setCurrentText(defaultEncoding);
} }
ui->spinMaxUndo->setValue(pSettings->editor().undoLimit()); ui->spinMaxUndo->setValue(pSettings->editor().undoLimit());
ui->spinMaxUndoMemory->setValue(pSettings->editor().undoMemoryUsage());
} }
void EditorMiscWidget::doSave() void EditorMiscWidget::doSave()
@ -80,6 +81,7 @@ void EditorMiscWidget::doSave()
pSettings->editor().setDefaultEncoding(ui->cbEncoding->currentData().toByteArray()); pSettings->editor().setDefaultEncoding(ui->cbEncoding->currentData().toByteArray());
} }
pSettings->editor().setUndoLimit(ui->spinMaxUndo->value()); pSettings->editor().setUndoLimit(ui->spinMaxUndo->value());
pSettings->editor().setUndoMemoryUsage(ui->spinMaxUndoMemory->value());
pSettings->editor().save(); pSettings->editor().save();
pMainWindow->updateEditorSettings(); pMainWindow->updateEditorSettings();
} }

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>515</width> <width>515</width>
<height>300</height> <height>315</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -89,6 +89,57 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Max Undo Memory Usage</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinMaxUndoMemory">
<property name="suffix">
<string>MB</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">

View File

@ -206,67 +206,67 @@
<name>CharsetInfoManager</name> <name>CharsetInfoManager</name>
<message> <message>
<source>Arabic</source> <source>Arabic</source>
<translation>Árabe</translation> <translation type="vanished">Árabe</translation>
</message> </message>
<message> <message>
<source>Greek</source> <source>Greek</source>
<translation>Grego</translation> <translation type="vanished">Grego</translation>
</message> </message>
<message> <message>
<source>Baltic</source> <source>Baltic</source>
<translation>Báltico</translation> <translation type="vanished">Báltico</translation>
</message> </message>
<message> <message>
<source>Western Europe</source> <source>Western Europe</source>
<translation>Europa Ocidental</translation> <translation type="vanished">Europa Ocidental</translation>
</message> </message>
<message> <message>
<source>Central Europe</source> <source>Central Europe</source>
<translation>Europa Central</translation> <translation type="vanished">Europa Central</translation>
</message> </message>
<message> <message>
<source>Cyrillic</source> <source>Cyrillic</source>
<translation>Cirílico</translation> <translation type="vanished">Cirílico</translation>
</message> </message>
<message> <message>
<source>Turkish</source> <source>Turkish</source>
<translation>Turco</translation> <translation type="vanished">Turco</translation>
</message> </message>
<message> <message>
<source>Northern Europe</source> <source>Northern Europe</source>
<translation>Europa setentrional</translation> <translation type="vanished">Europa setentrional</translation>
</message> </message>
<message> <message>
<source>Hebrew</source> <source>Hebrew</source>
<translation>Hebraico</translation> <translation type="vanished">Hebraico</translation>
</message> </message>
<message> <message>
<source>Thai</source> <source>Thai</source>
<translation>Tailandês</translation> <translation type="vanished">Tailandês</translation>
</message> </message>
<message> <message>
<source>Japanese</source> <source>Japanese</source>
<translation>Japonês</translation> <translation type="vanished">Japonês</translation>
</message> </message>
<message> <message>
<source>Chinese</source> <source>Chinese</source>
<translation>Chinês</translation> <translation type="vanished">Chinês</translation>
</message> </message>
<message> <message>
<source>Korean</source> <source>Korean</source>
<translation>Coreano</translation> <translation type="vanished">Coreano</translation>
</message> </message>
<message> <message>
<source>Vietnamese</source> <source>Vietnamese</source>
<translation>Vietnamês</translation> <translation type="vanished">Vietnamês</translation>
</message> </message>
<message> <message>
<source>Eastern Europe</source> <source>Eastern Europe</source>
<translation>Europa Oriental</translation> <translation type="vanished">Europa Oriental</translation>
</message> </message>
<message> <message>
<source>Celtic</source> <source>Celtic</source>
<translation>Celta</translation> <translation type="vanished">Celta</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1371,6 +1371,14 @@
<source>UTF-8 BOM</source> <source>UTF-8 BOM</source>
<translation>UTF-8 BOM</translation> <translation>UTF-8 BOM</translation>
</message> </message>
<message>
<source>Max Undo Memory Usage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MB</source>
<translation type="unfinished">MB</translation>
</message>
</context> </context>
<context> <context>
<name>EditorSnippetWidget</name> <name>EditorSnippetWidget</name>
@ -5698,15 +5706,15 @@
</message> </message>
<message> <message>
<source>Can&apos;t open file &apos;%1&apos; to write!</source> <source>Can&apos;t open file &apos;%1&apos; to write!</source>
<translation>Impossível gravar no arquivo &apos;%1&apos;!</translation> <translation type="vanished">Impossível gravar no arquivo &apos;%1&apos;!</translation>
</message> </message>
<message> <message>
<source>Failed to write data.</source> <source>Failed to write data.</source>
<translation>Falha ao gravar dados.</translation> <translation type="vanished">Falha ao gravar dados.</translation>
</message> </message>
<message> <message>
<source>Untitled</source> <source>Untitled</source>
<translation>Sem nome</translation> <translation type="vanished">Sem nome</translation>
</message> </message>
<message> <message>
<source>The following %1 directories don&apos;t exist:</source> <source>The following %1 directories don&apos;t exist:</source>
@ -5934,7 +5942,7 @@
</message> </message>
<message> <message>
<source>Index %1 out of range</source> <source>Index %1 out of range</source>
<translation>Índice %1 fora dos limites</translation> <translation type="vanished">Índice %1 fora dos limites</translation>
</message> </message>
<message> <message>
<source>bytes</source> <source>bytes</source>
@ -6474,18 +6482,18 @@
<name>SynDocument</name> <name>SynDocument</name>
<message> <message>
<source>Can&apos;t open file &apos;%1&apos; for read!</source> <source>Can&apos;t open file &apos;%1&apos; for read!</source>
<translation>Impossível ler o arquivo &apos;%1&apos;!</translation> <translation type="vanished">Impossível ler o arquivo &apos;%1&apos;!</translation>
</message> </message>
<message> <message>
<source>Can&apos;t open file &apos;%1&apos; for save!</source> <source>Can&apos;t open file &apos;%1&apos; for save!</source>
<translation>Impossível gravar no arquivo &apos;%1&apos;!</translation> <translation type="vanished">Impossível gravar no arquivo &apos;%1&apos;!</translation>
</message> </message>
</context> </context>
<context> <context>
<name>SynEdit</name> <name>SynEdit</name>
<message> <message>
<source>The highlighter seems to be in an infinite loop</source> <source>The highlighter seems to be in an infinite loop</source>
<translation>A colocação de destaques parece estar em repetição infinita</translation> <translation type="vanished">A colocação de destaques parece estar em repetição infinita</translation>
</message> </message>
</context> </context>
<context> <context>

File diff suppressed because it is too large Load Diff

View File

@ -198,73 +198,6 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>CharsetInfoManager</name>
<message>
<source>Arabic</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Greek</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Baltic</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Western Europe</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Central Europe</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cyrillic</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Turkish</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Northern Europe</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Hebrew</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Thai</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Japanese</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Chinese</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Korean</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Vietnamese</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Eastern Europe</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Celtic</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>ChooseThemeDialog</name> <name>ChooseThemeDialog</name>
<message> <message>
@ -1363,6 +1296,14 @@
<source>UTF-8 BOM</source> <source>UTF-8 BOM</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Max Undo Memory Usage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MB</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>EditorSnippetWidget</name> <name>EditorSnippetWidget</name>
@ -5648,18 +5589,6 @@
<source>destructor</source> <source>destructor</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Can&apos;t open file &apos;%1&apos; to write!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Failed to write data.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Untitled</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>The following %1 directories don&apos;t exist:</source> <source>The following %1 directories don&apos;t exist:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -5884,10 +5813,6 @@
<source>Icon files</source> <source>Icon files</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Index %1 out of range</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>bytes</source> <source>bytes</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -6406,24 +6331,6 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>SynDocument</name>
<message>
<source>Can&apos;t open file &apos;%1&apos; for read!</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for save!</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>SynEdit</name>
<message>
<source>The highlighter seems to be in an infinite loop</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>TodoModel</name> <name>TodoModel</name>
<message> <message>

View File

@ -6585,6 +6585,11 @@ void SynEdit::setUndoLimit(int size)
mUndoList->setMaxUndoActions(size); mUndoList->setMaxUndoActions(size);
} }
void SynEdit::setUndoMemoryUsage(int size)
{
mUndoList->setMaxMemoryUsage(size*1024*1024);
}
int SynEdit::charsInWindow() const int SynEdit::charsInWindow() const
{ {
return mCharsInWindow; return mCharsInWindow;

View File

@ -334,6 +334,7 @@ public:
int charWidth() const; int charWidth() const;
void setUndoLimit(int size); void setUndoLimit(int size);
void setUndoMemoryUsage(int size);
int gutterWidth() const; int gutterWidth() const;
void setGutterWidth(int value); void setGutterWidth(int value);

View File

@ -825,6 +825,7 @@ SynDocumentLine::SynDocumentLine():
SynEditUndoList::SynEditUndoList():QObject() SynEditUndoList::SynEditUndoList():QObject()
{ {
mMaxUndoActions = 1024; mMaxUndoActions = 1024;
mMaxMemoryUsage = 50 * 1024 * 1024;
mNextChangeNumber = 1; mNextChangeNumber = 1;
mInsideRedo = false; mInsideRedo = false;
@ -832,6 +833,7 @@ SynEditUndoList::SynEditUndoList():QObject()
mBlockLock=0; mBlockLock=0;
mFullUndoImposible=false; mFullUndoImposible=false;
mBlockCount=0; mBlockCount=0;
mMemoryUsage=0;
mLastPoppedItemChangeNumber=0; mLastPoppedItemChangeNumber=0;
mInitialChangeNumber = 0; mInitialChangeNumber = 0;
mLastRestoredItemChangeNumber=0; mLastRestoredItemChangeNumber=0;
@ -853,7 +855,9 @@ void SynEditUndoList::addChange(SynChangeReason reason, const BufferCoord &start
changeNumber); changeNumber);
// qDebug()<<"add change"<<changeNumber<<(int)reason; // qDebug()<<"add change"<<changeNumber<<(int)reason;
mItems.append(newItem); mItems.append(newItem);
addMemoryUsage(newItem);
ensureMaxEntries(); ensureMaxEntries();
if (reason!=SynChangeReason::GroupBreak && !inBlock()) { if (reason!=SynChangeReason::GroupBreak && !inBlock()) {
mBlockCount++; mBlockCount++;
// qDebug()<<"add"<<mBlockCount; // qDebug()<<"add"<<mBlockCount;
@ -873,6 +877,7 @@ void SynEditUndoList::restoreChange(PSynEditUndoItem item)
{ {
size_t changeNumber = item->changeNumber(); size_t changeNumber = item->changeNumber();
mItems.append(item); mItems.append(item);
addMemoryUsage(item);
ensureMaxEntries(); ensureMaxEntries();
if (changeNumber>mNextChangeNumber) if (changeNumber>mNextChangeNumber)
mNextChangeNumber=changeNumber; mNextChangeNumber=changeNumber;
@ -912,6 +917,7 @@ void SynEditUndoList::clear()
mLastRestoredItemChangeNumber=0; mLastRestoredItemChangeNumber=0;
mBlockCount=0; mBlockCount=0;
mBlockLock=0; mBlockLock=0;
mMemoryUsage=0;
} }
void SynEditUndoList::endBlock() void SynEditUndoList::endBlock()
@ -941,6 +947,38 @@ unsigned int SynEditUndoList::getNextChangeNumber()
return mNextChangeNumber++; return mNextChangeNumber++;
} }
void SynEditUndoList::addMemoryUsage(PSynEditUndoItem item)
{
if (!item)
return;
int length=0;
foreach (const QString& s, item->changeText()) {
length+=s.length()+2;
}
mMemoryUsage += length * sizeof(QChar) ;
}
void SynEditUndoList::reduceMemoryUsage(PSynEditUndoItem item)
{
if (!item)
return;
int length=0;
foreach (const QString& s, item->changeText()) {
length+=s.length()+2;
}
mMemoryUsage -= length * sizeof(QChar) ;
}
int SynEditUndoList::maxMemoryUsage() const
{
return mMaxMemoryUsage;
}
void SynEditUndoList::setMaxMemoryUsage(int newMaxMemoryUsage)
{
mMaxMemoryUsage = newMaxMemoryUsage;
}
SynChangeReason SynEditUndoList::lastChangeReason() SynChangeReason SynEditUndoList::lastChangeReason()
{ {
if (mItems.count() == 0) if (mItems.count() == 0)
@ -978,6 +1016,7 @@ PSynEditUndoItem SynEditUndoList::popItem()
} }
} }
mLastPoppedItemChangeNumber = item->changeNumber(); mLastPoppedItemChangeNumber = item->changeNumber();
reduceMemoryUsage(item);
mItems.removeLast(); mItems.removeLast();
return item; return item;
} }
@ -1040,14 +1079,20 @@ bool SynEditUndoList::fullUndoImposible() const
void SynEditUndoList::ensureMaxEntries() void SynEditUndoList::ensureMaxEntries()
{ {
if (mMaxUndoActions>0 && mBlockCount > mMaxUndoActions){ if (mMaxUndoActions>0 && (mBlockCount > mMaxUndoActions || mMemoryUsage>mMaxMemoryUsage)){
mFullUndoImposible = true; mFullUndoImposible = true;
while (mBlockCount > mMaxUndoActions && !mItems.isEmpty()) { while ((mBlockCount > mMaxUndoActions || mMemoryUsage>mMaxMemoryUsage)
&& !mItems.isEmpty()) {
//remove all undo item in block //remove all undo item in block
PSynEditUndoItem item = mItems.front(); PSynEditUndoItem item = mItems.front();
size_t changeNumber = item->changeNumber(); size_t changeNumber = item->changeNumber();
while (mItems.count()>0 && mItems.front()->changeNumber() == changeNumber) while (mItems.count()>0) {
item = mItems.front();
if (item->changeNumber()!=changeNumber)
break;
reduceMemoryUsage(item);
mItems.removeFirst(); mItems.removeFirst();
}
if (item->changeReason()!=SynChangeReason::GroupBreak) if (item->changeReason()!=SynChangeReason::GroupBreak)
mBlockCount--; mBlockCount--;
} }

View File

@ -233,21 +233,28 @@ public:
bool fullUndoImposible() const; bool fullUndoImposible() const;
int maxMemoryUsage() const;
void setMaxMemoryUsage(int newMaxMemoryUsage);
signals: signals:
void addedUndo(); void addedUndo();
protected: protected:
void ensureMaxEntries(); void ensureMaxEntries();
bool inBlock(); bool inBlock();
unsigned int getNextChangeNumber(); unsigned int getNextChangeNumber();
void addMemoryUsage(PSynEditUndoItem item);
void reduceMemoryUsage(PSynEditUndoItem item);
protected: protected:
size_t mBlockChangeNumber; size_t mBlockChangeNumber;
int mBlockLock; int mBlockLock;
int mBlockCount; // count of action blocks; int mBlockCount; // count of action blocks;
int mMemoryUsage;
size_t mLastPoppedItemChangeNumber; size_t mLastPoppedItemChangeNumber;
size_t mLastRestoredItemChangeNumber; size_t mLastRestoredItemChangeNumber;
bool mFullUndoImposible; bool mFullUndoImposible;
QVector<PSynEditUndoItem> mItems; QVector<PSynEditUndoItem> mItems;
int mMaxUndoActions; int mMaxUndoActions;
int mMaxMemoryUsage;
size_t mNextChangeNumber; size_t mNextChangeNumber;
size_t mInitialChangeNumber; size_t mInitialChangeNumber;
bool mInsideRedo; bool mInsideRedo;