- 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: project and non-project files use different bookmark view (auto switch when switch editors)
- 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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>515</width>
<height>300</height>
<height>315</height>
</rect>
</property>
<property name="windowTitle">
@ -89,6 +89,57 @@
</layout>
</widget>
</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>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">

View File

@ -206,67 +206,67 @@
<name>CharsetInfoManager</name>
<message>
<source>Arabic</source>
<translation>Árabe</translation>
<translation type="vanished">Árabe</translation>
</message>
<message>
<source>Greek</source>
<translation>Grego</translation>
<translation type="vanished">Grego</translation>
</message>
<message>
<source>Baltic</source>
<translation>Báltico</translation>
<translation type="vanished">Báltico</translation>
</message>
<message>
<source>Western Europe</source>
<translation>Europa Ocidental</translation>
<translation type="vanished">Europa Ocidental</translation>
</message>
<message>
<source>Central Europe</source>
<translation>Europa Central</translation>
<translation type="vanished">Europa Central</translation>
</message>
<message>
<source>Cyrillic</source>
<translation>Cirílico</translation>
<translation type="vanished">Cirílico</translation>
</message>
<message>
<source>Turkish</source>
<translation>Turco</translation>
<translation type="vanished">Turco</translation>
</message>
<message>
<source>Northern Europe</source>
<translation>Europa setentrional</translation>
<translation type="vanished">Europa setentrional</translation>
</message>
<message>
<source>Hebrew</source>
<translation>Hebraico</translation>
<translation type="vanished">Hebraico</translation>
</message>
<message>
<source>Thai</source>
<translation>Tailandês</translation>
<translation type="vanished">Tailandês</translation>
</message>
<message>
<source>Japanese</source>
<translation>Japonês</translation>
<translation type="vanished">Japonês</translation>
</message>
<message>
<source>Chinese</source>
<translation>Chinês</translation>
<translation type="vanished">Chinês</translation>
</message>
<message>
<source>Korean</source>
<translation>Coreano</translation>
<translation type="vanished">Coreano</translation>
</message>
<message>
<source>Vietnamese</source>
<translation>Vietnamês</translation>
<translation type="vanished">Vietnamês</translation>
</message>
<message>
<source>Eastern Europe</source>
<translation>Europa Oriental</translation>
<translation type="vanished">Europa Oriental</translation>
</message>
<message>
<source>Celtic</source>
<translation>Celta</translation>
<translation type="vanished">Celta</translation>
</message>
</context>
<context>
@ -1371,6 +1371,14 @@
<source>UTF-8 BOM</source>
<translation>UTF-8 BOM</translation>
</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>
<name>EditorSnippetWidget</name>
@ -5698,15 +5706,15 @@
</message>
<message>
<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>
<source>Failed to write data.</source>
<translation>Falha ao gravar dados.</translation>
<translation type="vanished">Falha ao gravar dados.</translation>
</message>
<message>
<source>Untitled</source>
<translation>Sem nome</translation>
<translation type="vanished">Sem nome</translation>
</message>
<message>
<source>The following %1 directories don&apos;t exist:</source>
@ -5934,7 +5942,7 @@
</message>
<message>
<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>
<source>bytes</source>
@ -6474,18 +6482,18 @@
<name>SynDocument</name>
<message>
<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>
<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>
</context>
<context>
<name>SynEdit</name>
<message>
<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>
</context>
<context>

File diff suppressed because it is too large Load Diff

View File

@ -198,73 +198,6 @@
<translation type="unfinished"></translation>
</message>
</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>
<name>ChooseThemeDialog</name>
<message>
@ -1363,6 +1296,14 @@
<source>UTF-8 BOM</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Max Undo Memory Usage</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>MB</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EditorSnippetWidget</name>
@ -5648,18 +5589,6 @@
<source>destructor</source>
<translation type="unfinished"></translation>
</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>
<source>The following %1 directories don&apos;t exist:</source>
<translation type="unfinished"></translation>
@ -5884,10 +5813,6 @@
<source>Icon files</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Index %1 out of range</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>bytes</source>
<translation type="unfinished"></translation>
@ -6406,24 +6331,6 @@
<translation type="unfinished"></translation>
</message>
</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>
<name>TodoModel</name>
<message>

View File

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

View File

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

View File

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

View File

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