Implement a preference option to limit the size of "Copy as CSV/HTML/XML/SQL" actions. Helps with bug #793: app freezes when 'copy as csv/xml/html' is selected.

This commit is contained in:
Ansgar Becker
2009-01-18 22:32:31 +00:00
parent a74673befa
commit 1f6e894ba5
4 changed files with 79 additions and 8 deletions

View File

@@ -170,6 +170,8 @@ const
REGNAME_CSV_LOWPRIO = 'CSVImportLowPriority';
REGNAME_CSV_REPLACE = 'CSVImportReplace';
REGNAME_CSV_IGNORE = 'CSVImportIgnore';
REGNAME_COPYMAXSIZE = 'CopyDataMaxSize';
DEFAULT_COPYMAXSIZE = 5;
REGNAME_DO_UPDATECHECK = 'Updatecheck';
DEFAULT_DO_UPDATECHECK = False;
REGNAME_DO_UPDATECHECK_BUILDS = 'UpdatecheckBuilds';
@@ -294,3 +296,7 @@ const
VTREE_NOTLOADED = 0;
VTREE_LOADED = 1;
MSG_COPYMAXSIZE = 'Copying data is limited to %s but more data is available. '
+ 'Only %s out of %s rows were copied.' + CRLF + CRLF
+ 'Increase the value in Tools > Preferences > Export if you need more.';

View File

@@ -784,10 +784,11 @@ end;
}
procedure GridToHtml(Grid: TVirtualStringTree; GridData: PGridResult; Title: WideString; S: TStream);
var
i: Integer;
i, MaxSize: Integer;
tmp, Data, Generator: WideString;
Node: PVirtualNode;
begin
MaxSize := GetRegValue(REGNAME_COPYMAXSIZE, DEFAULT_COPYMAXSIZE) * SIZE_MB;
Generator := APPNAME+' '+FullAppVersion;
tmp :=
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" ' + CRLF +
@@ -866,6 +867,12 @@ begin
// Release some memory.
Mainform.DiscardNodeData(Grid, Node);
Node := Grid.GetNext(Node);
if (MaxSize > 0) and Assigned(Node) and (S is TMemoryStream) and (S.Size >= MaxSize) then begin
MessageDlg(
Format(MSG_COPYMAXSIZE, [FormatByteNumber(MaxSize), FormatNumber(Node.Index), FormatNumber(Grid.RootNodeCount)]),
mtWarning, [mbOK], 0);
break;
end;
end;
// footer:
tmp :=
@@ -893,13 +900,14 @@ end;
}
procedure GridToCsv(Grid: TVirtualStringTree; GridData: PGridResult; Separator, Encloser, Terminator: String; S: TStream);
var
i: Integer;
i, MaxSize: Integer;
tmp, Data: WideString;
Node: PVirtualNode;
begin
separator := esc2ascii(separator);
encloser := esc2ascii(encloser);
terminator := esc2ascii(terminator);
MaxSize := GetRegValue(REGNAME_COPYMAXSIZE, DEFAULT_COPYMAXSIZE) * SIZE_MB;
tmp := '';
// Columns
@@ -951,6 +959,12 @@ begin
// Release some memory.
Mainform.DiscardNodeData(Grid, Node);
Node := Grid.GetNext(Node);
if (MaxSize > 0) and Assigned(Node) and (S is TMemoryStream) and (S.Size >= MaxSize) then begin
MessageDlg(
Format(MSG_COPYMAXSIZE, [FormatByteNumber(MaxSize), FormatNumber(Node.Index), FormatNumber(Grid.RootNodeCount)]),
mtWarning, [mbOK], 0);
break;
end;
end;
Grid.Visible := true;
Mainform.showstatus(STATUS_MSG_READY);
@@ -965,10 +979,11 @@ end;
}
procedure GridToXml(Grid: TVirtualStringTree; GridData: PGridResult; root: WideString; S: TStream);
var
i: Integer;
i, MaxSize: Integer;
tmp, Data: WideString;
Node: PVirtualNode;
begin
MaxSize := GetRegValue(REGNAME_COPYMAXSIZE, DEFAULT_COPYMAXSIZE) * SIZE_MB;
tmp := '<?xml version="1.0"?>' + CRLF + CRLF +
'<table name="'+root+'">' + CRLF;
StreamWrite(S, tmp);
@@ -1011,6 +1026,12 @@ begin
// Release some memory.
Mainform.DiscardNodeData(Grid, Node);
Node := Grid.GetNext(Node);
if (MaxSize > 0) and Assigned(Node) and (S is TMemoryStream) and (S.Size >= MaxSize) then begin
MessageDlg(
Format(MSG_COPYMAXSIZE, [FormatByteNumber(MaxSize), FormatNumber(Node.Index), FormatNumber(Grid.RootNodeCount)]),
mtWarning, [mbOK], 0);
break;
end;
end;
// footer:
tmp := '</table>' + CRLF;
@@ -1027,10 +1048,11 @@ end;
}
procedure GridToSql(Grid: TVirtualStringTree; GridData: PGridResult; Tablename: WideString; S: TStream);
var
i: Integer;
i, MaxSize: Integer;
tmp, Data: WideString;
Node: PVirtualNode;
begin
MaxSize := GetRegValue(REGNAME_COPYMAXSIZE, DEFAULT_COPYMAXSIZE) * SIZE_MB;
// Avoid reloading discarded data before the end.
Grid.Visible := false;
Node := Grid.GetFirst;
@@ -1074,6 +1096,12 @@ begin
// Release some memory.
Mainform.DiscardNodeData(Grid, Node);
Node := Grid.GetNext(Node);
if (MaxSize > 0) and Assigned(Node) and (S is TMemoryStream) and (S.Size >= MaxSize) then begin
MessageDlg(
Format(MSG_COPYMAXSIZE, [FormatByteNumber(MaxSize), FormatNumber(Node.Index), FormatNumber(Grid.RootNodeCount)]),
mtWarning, [mbOK], 0);
break;
end;
end;
// footer:
tmp := CRLF;

View File

@@ -587,14 +587,21 @@ object optionsform: Toptionsform
end
object tabCSV: TTabSheet
BorderWidth = 5
Caption = 'CSV'
Caption = 'Export'
ImageIndex = 2
object lblCopyDataMaxSize: TLabel
Left = 8
Top = 200
Width = 244
Height = 13
Caption = 'Limit "Copy as CSV/HTML/XML/SQL" actions to [MB]'
end
object grpCSV: TGroupBox
Left = 0
Top = 0
Width = 399
Height = 288
Align = alClient
Height = 177
Align = alTop
Caption = 'CSV-Strings for copying/saving CSV-data'
TabOrder = 0
object lblCSVSeparator: TLabel
@@ -678,6 +685,28 @@ object optionsform: Toptionsform
OnChange = Modified
end
end
object editCopyDataMaxSize: TEdit
Left = 314
Top = 197
Width = 65
Height = 21
Anchors = [akTop, akRight]
TabOrder = 1
Text = '0'
OnChange = Modified
end
object updownCopyDataMaxSize: TUpDown
Left = 377
Top = 197
Width = 17
Height = 21
Anchors = [akTop, akRight]
Associate = editCopyDataMaxSize
Max = 999
TabOrder = 2
Wrap = True
OnChanging = anyUpDownLimitChanging
end
end
end
object btnCancel: TButton

View File

@@ -91,6 +91,9 @@ type
grpSQLSample: TGroupBox;
SynMemoSQLSample: TSynMemo;
SynSQLSynSQLSample: TSynSQLSyn;
lblCopyDataMaxSize: TLabel;
editCopyDataMaxSize: TEdit;
updownCopyDataMaxSize: TUpDown;
procedure FormShow(Sender: TObject);
procedure Modified(Sender: TObject);
procedure Apply(Sender: TObject);
@@ -192,6 +195,8 @@ begin
MainReg.WriteString(REGNAME_CSV_SEPARATOR, editCSVSeparator.Text);
MainReg.WriteString(REGNAME_CSV_ENCLOSER, editCSVEncloser.Text);
MainReg.WriteString(REGNAME_CSV_TERMINATOR, editCSVTerminator.Text);
MainReg.WriteInteger(REGNAME_COPYMAXSIZE, updownCopyDataMaxSize.Position);
MainReg.WriteInteger(REGNAME_MAXCOLWIDTH, updownMaxColWidth.Position);
MainReg.WriteString(REGNAME_DATAFONTNAME, comboDataFontName.Text);
MainReg.WriteInteger(REGNAME_DATAFONTSIZE, updownDataFontSize.Position);
@@ -322,10 +327,13 @@ begin
// Default Column-Width in DBGrids:
updownMaxColWidth.Position := GetRegValue(REGNAME_MAXCOLWIDTH, DEFAULT_MAXCOLWIDTH);
// CSV-Options:
// Export-Options:
editCSVSeparator.Text := GetRegValue(REGNAME_CSV_SEPARATOR, DEFAULT_CSV_SEPARATOR);
editCSVEncloser.Text := GetRegValue(REGNAME_CSV_ENCLOSER, DEFAULT_CSV_ENCLOSER);
editCSVTerminator.Text := GetRegValue(REGNAME_CSV_TERMINATOR, DEFAULT_CSV_TERMINATOR);
updownCopyDataMaxSize.Position := GetRegValue(REGNAME_COPYMAXSIZE, DEFAULT_COPYMAXSIZE);
// Log to file
chkLogToFile.Checked := GetRegValue(REGNAME_LOGTOFILE, DEFAULT_LOGTOFILE);
btnOpenLogFolder.Enabled := DirectoryExists(DirnameSessionLogs);