mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-26 20:50:20 +08:00
Switch ListColumns from TSortListView to TVirtualStringTree
Additionally/Sideeffects: - Fix vstFreeNode to delete the item from the array, not only free the item itself - Change/Rename GetSelectedNodesFromVT to GetVTCaptions and give it the ability to return all captions, not only the selected. This function is very useful now and saves writing much redundant code. A table with 500 columns needed 3 seconds to display in the TSortListView, now that takes less than a half second.
This commit is contained in:
@ -641,49 +641,70 @@ object MDIChild: TMDIChild
|
||||
end
|
||||
end
|
||||
end
|
||||
object ListColumns: TSortListView
|
||||
Tag = -1
|
||||
object ListColumns: TVirtualStringTree
|
||||
Left = 28
|
||||
Top = 17
|
||||
Width = 468
|
||||
Height = 203
|
||||
Align = alClient
|
||||
EditDelay = 500
|
||||
Header.AutoSizeIndex = 0
|
||||
Header.Font.Charset = DEFAULT_CHARSET
|
||||
Header.Font.Color = clWindowText
|
||||
Header.Font.Height = -11
|
||||
Header.Font.Name = 'Tahoma'
|
||||
Header.Font.Style = []
|
||||
Header.Height = 20
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDblClickResize, hoHotTrack, hoShowSortGlyphs, hoVisible]
|
||||
Images = MainForm.ImageList1
|
||||
IncrementalSearch = isInitializedOnly
|
||||
PopupMenu = popupTableGrid
|
||||
TabOrder = 2
|
||||
TreeOptions.MiscOptions = [toAcceptOLEDrop, toEditable, toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning]
|
||||
TreeOptions.PaintOptions = [toShowDropmark, toShowHorzGridLines, toShowVertGridLines, toThemeAware, toUseBlendedImages]
|
||||
TreeOptions.SelectionOptions = [toFullRowSelect, toMultiSelect, toRightClickSelect]
|
||||
OnChange = ListColumnsChange
|
||||
OnCompareNodes = vstCompareNodes
|
||||
OnDblClick = UpdateField
|
||||
OnFreeNode = vstFreeNode
|
||||
OnGetText = vstGetText
|
||||
OnGetImageIndex = vstGetImageIndex
|
||||
OnGetNodeDataSize = vstGetNodeDataSize
|
||||
OnHeaderClick = vstHeaderClick
|
||||
OnInitNode = vstInitNode
|
||||
OnKeyUp = controlsKeyUp
|
||||
OnNewText = ListColumnsNewText
|
||||
Columns = <
|
||||
item
|
||||
Caption = 'Name'
|
||||
Width = -1
|
||||
WidthType = (
|
||||
-1)
|
||||
Options = [coAllowClick, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
|
||||
Position = 0
|
||||
Width = 94
|
||||
WideText = 'Name'
|
||||
end
|
||||
item
|
||||
Caption = 'Type'
|
||||
Options = [coAllowClick, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
|
||||
Position = 1
|
||||
Width = 100
|
||||
WideText = 'Type'
|
||||
end
|
||||
item
|
||||
Caption = 'Null'
|
||||
Options = [coAllowClick, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
|
||||
Position = 2
|
||||
Width = 40
|
||||
WideText = 'Null'
|
||||
end
|
||||
item
|
||||
Caption = 'Default'
|
||||
Options = [coAllowClick, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
|
||||
Position = 3
|
||||
Width = 115
|
||||
WideText = 'Default'
|
||||
end
|
||||
item
|
||||
Caption = 'Extra'
|
||||
Width = 200
|
||||
Options = [coAllowClick, coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible]
|
||||
Position = 4
|
||||
Width = 100
|
||||
WideText = 'Extra'
|
||||
end>
|
||||
GridLines = True
|
||||
MultiSelect = True
|
||||
RowSelect = True
|
||||
PopupMenu = popupTableGrid
|
||||
SmallImages = MainForm.ImageList1
|
||||
TabOrder = 2
|
||||
ViewStyle = vsReport
|
||||
OnDblClick = UpdateField
|
||||
OnEdited = ListColumnsEdited
|
||||
OnKeyUp = controlsKeyUp
|
||||
OnSelectItem = ListColumnsSelectItem
|
||||
ImageIndexSortAsc = 0
|
||||
ImageIndexSortDesc = 0
|
||||
end
|
||||
end
|
||||
object tabData: TTabSheet
|
||||
|
@ -110,7 +110,7 @@ type
|
||||
PopupMenuDropTable: TMenuItem;
|
||||
N17: TMenuItem;
|
||||
pnlTableToolbar: TPanel;
|
||||
ListColumns: TSortListView;
|
||||
ListColumns: TVirtualStringTree;
|
||||
CopycontentsasHTML1: TMenuItem;
|
||||
CopycontentsasHTML2: TMenuItem;
|
||||
Copy3: TMenuItem;
|
||||
@ -307,8 +307,8 @@ type
|
||||
tlbTableLeft2: TToolBar;
|
||||
btnTableInsertRecord: TToolButton;
|
||||
procedure menuRenameColumnClick(Sender: TObject);
|
||||
procedure ListColumnsEdited(Sender: TObject; Item: TListItem;
|
||||
var S: string);
|
||||
procedure ListColumnsNewText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||
Column: TColumnIndex; NewText: WideString);
|
||||
procedure menuclearClick(Sender: TObject);
|
||||
procedure popupQueryPopup(Sender: TObject);
|
||||
procedure lboxQueryHelpersClick(Sender: TObject);
|
||||
@ -321,8 +321,7 @@ type
|
||||
procedure DBtreeExpanding(Sender: TObject; Node: TTreeNode;
|
||||
var AllowExpansion: Boolean);
|
||||
procedure ListTablesClick(Sender: TObject);
|
||||
procedure ListColumnsSelectItem(Sender: TObject; Item: TListItem;
|
||||
Selected: Boolean);
|
||||
procedure ListColumnsChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
||||
procedure DBMemo1Exit(Sender: TObject);
|
||||
procedure btnUnsafeEditClick(Sender: TObject);
|
||||
procedure gridMouseDown(Sender: TObject; Button: TMouseButton;
|
||||
@ -545,7 +544,8 @@ type
|
||||
VTRowDataListVariables,
|
||||
VTRowDataListProcesses,
|
||||
VTRowDataListCommandStats,
|
||||
VTRowDataListTables : Array of TVTreeData;
|
||||
VTRowDataListTables,
|
||||
VTRowDataListColumns : TVTreeDataArray;
|
||||
|
||||
FProgressForm : TFrmQueryProgress;
|
||||
procedure Init(AConn : POpenConnProf; AMysqlConn : TMysqlConn);
|
||||
@ -1280,8 +1280,6 @@ begin
|
||||
tabTable.TabVisible := false;
|
||||
tabData.TabVisible := false;
|
||||
|
||||
ListTables.Clear;
|
||||
ListColumns.Items.Clear();
|
||||
pnlTableTop.Caption := 'Table-Properties';
|
||||
Caption := Description + ' - /' + ActualDatabase;
|
||||
ActualDatabase := db;
|
||||
@ -1381,7 +1379,7 @@ var
|
||||
DropDown : TStringList;
|
||||
i : Integer;
|
||||
j : Integer;
|
||||
Columns : TStringList;
|
||||
ValidColumns : TStringList;
|
||||
PrimaryKeyColumns : TStringList;
|
||||
reg : TRegistry;
|
||||
reg_value : String;
|
||||
@ -1473,20 +1471,12 @@ begin
|
||||
begin
|
||||
orderclauses := explode( ',', reg.ReadString( reg_value ) );
|
||||
RewriteOrderClause := False;
|
||||
ValidColumns := GetVTCaptions( ListColumns );
|
||||
for i := 0 to ( orderclauses.Count - 1 ) do
|
||||
begin
|
||||
columnname := Trim( Copy( orderclauses[i], 0, LastPos( ' ', orderclauses[i] ) ) );
|
||||
columnname := trimc( columnname, '`' );
|
||||
columnexists := false;
|
||||
|
||||
for j := 0 to ( ListColumns.Items.Count - 1 ) do
|
||||
begin
|
||||
if ( ListColumns.Items[j].Caption = columnname ) then
|
||||
begin
|
||||
columnexists := true;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
columnexists := ValidColumns.IndexOf(columnname) > -1;
|
||||
|
||||
if ( not columnexists ) then
|
||||
begin
|
||||
@ -1533,7 +1523,6 @@ begin
|
||||
end;
|
||||
|
||||
MenuLimit.Checked := Mainform.CheckBoxLimit.Checked;
|
||||
Columns := TStringList.Create();
|
||||
PrimaryKeyColumns := TStringList.Create();
|
||||
|
||||
if ( ( ActualTable <> '' ) and ( ActualDatabase <> '' ) ) then
|
||||
@ -1645,14 +1634,13 @@ begin
|
||||
|
||||
MainForm.ShowStatus( STATUS_MSG_READY, 2 );
|
||||
|
||||
for i := 0 to ( ListColumns.Items.Count - 1 ) do
|
||||
for i := 0 to Length(VTRowDataListColumns) - 1 do
|
||||
begin
|
||||
Columns.Add( ListColumns.Items[i].Caption );
|
||||
|
||||
// give all enum-fields a PickList with its Items
|
||||
if ( StrCmpBegin( 'enum', ListColumns.Items[i].SubItems[0]) ) then
|
||||
if ( StrCmpBegin( 'enum', VTRowDataListColumns[i].Captions[1]) ) then
|
||||
begin
|
||||
DropDown := explode( ''',''', getEnumValues( ListColumns.Items[i].SubItems[0] ) );
|
||||
DropDown := explode( ''',''', getEnumValues( VTRowDataListColumns[i].Captions[1] ) );
|
||||
for j := 0 to ( DropDown.Count - 1 ) do
|
||||
begin
|
||||
DropDown[j] := trimc( DropDown[j], '''' );
|
||||
@ -1660,7 +1648,7 @@ begin
|
||||
|
||||
for j := 0 to ( gridData.Columns.Count - 1 ) do
|
||||
begin
|
||||
if ( gridData.Columns[j].FieldName = ListColumns.Items[i].Caption ) then
|
||||
if ( gridData.Columns[j].FieldName = VTRowDataListColumns[i].Captions[0] ) then
|
||||
begin
|
||||
gridData.Columns[j].PickList := DropDown;
|
||||
end;
|
||||
@ -1671,11 +1659,11 @@ begin
|
||||
for j := 0 to ( gridData.Columns.Count - 1 ) do
|
||||
begin
|
||||
if (
|
||||
( gridData.Columns[j].FieldName = ListColumns.Items[i].Caption ) and
|
||||
( ListColumns.Items[i].ImageIndex = 26 )
|
||||
( gridData.Columns[j].FieldName = VTRowDataListColumns[i].Captions[0] ) and
|
||||
( VTRowDataListColumns[i].ImageIndex = 26 )
|
||||
) then
|
||||
begin
|
||||
PrimaryKeyColumns.Add( ListColumns.Items[i].Caption );
|
||||
PrimaryKeyColumns.Add( VTRowDataListColumns[i].Captions[0] );
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -2145,7 +2133,6 @@ end;
|
||||
procedure TMDIChild.ShowTableProperties(Sender: TObject);
|
||||
var
|
||||
i,j : Integer;
|
||||
n : TListItem;
|
||||
tn, tndb : TTreeNode;
|
||||
isFulltext : Boolean;
|
||||
ds : TDataSet;
|
||||
@ -2185,26 +2172,28 @@ begin
|
||||
end;
|
||||
|
||||
MainForm.ShowStatus( 'Reading table properties...', 2, true );
|
||||
ListColumns.Items.BeginUpdate;
|
||||
ListColumns.Items.Clear;
|
||||
ListColumns.BeginUpdate;
|
||||
ListColumns.Clear;
|
||||
Try
|
||||
ds := GetResults( 'SHOW COLUMNS FROM ' + mask(ActualTable), false );
|
||||
|
||||
SetLength(VTRowDataListColumns, ds.RecordCount);
|
||||
for i:=1 to ds.RecordCount do
|
||||
begin
|
||||
n := ListColumns.Items.Add;
|
||||
n.ImageIndex := ICONINDEX_FIELD;
|
||||
|
||||
n.Caption := ds.FieldByName('Field').AsString;
|
||||
n.Subitems.Add( ds.FieldByName('Type').AsString );
|
||||
VTRowDataListColumns[i-1].ImageIndex := ICONINDEX_FIELD;
|
||||
VTRowDataListColumns[i-1].Captions := TStringList.Create;
|
||||
VTRowDataListColumns[i-1].Captions.Add( ds.FieldByName('Field').AsString );
|
||||
VTRowDataListColumns[i-1].Captions.Add( ds.FieldByName('Type').AsString );
|
||||
if lowercase( ds.FieldByName('Null').AsString ) = 'yes' then
|
||||
n.Subitems.Add('Yes')
|
||||
else n.Subitems.Add('No');
|
||||
n.Subitems.Add( ds.FieldByName('Default').AsString );
|
||||
n.Subitems.Add( ds.FieldByName('Extra').AsString );
|
||||
VTRowDataListColumns[i-1].Captions.Add('Yes')
|
||||
else VTRowDataListColumns[i-1].Captions.Add('No');
|
||||
VTRowDataListColumns[i-1].Captions.Add( ds.FieldByName('Default').AsString );
|
||||
VTRowDataListColumns[i-1].Captions.Add( ds.FieldByName('Extra').AsString );
|
||||
ds.Next;
|
||||
end;
|
||||
|
||||
ListColumns.RootNodeCount := Length(VTRowDataListColumns);
|
||||
|
||||
// Manually invoke OnChange event of tabset to fill helper list with data
|
||||
if tabsetQueryHelpers.TabIndex = 0 then
|
||||
tabsetQueryHelpers.OnChange( Sender, tabsetQueryHelpers.TabIndex, dummy);
|
||||
@ -2232,12 +2221,12 @@ begin
|
||||
for i:=1 to ds.RecordCount do
|
||||
begin
|
||||
// Search for the column name in listColumns
|
||||
for j:=0 to ListColumns.Items.Count-1 do
|
||||
for j:=0 to Length(VTRowDataListColumns)-1 do
|
||||
begin
|
||||
if ds.FieldByName('Column_name').AsString = ListColumns.Items[j].Caption then
|
||||
if ds.FieldByName('Column_name').AsString = VTRowDataListColumns[j].Captions[0] then
|
||||
begin
|
||||
// Only apply a new icon if it was not already changed
|
||||
if ListColumns.Items[j].ImageIndex <> ICONINDEX_FIELD then
|
||||
if VTRowDataListColumns[j].ImageIndex <> ICONINDEX_FIELD then
|
||||
break;
|
||||
|
||||
// Check if column is part of a fulltext key
|
||||
@ -2248,16 +2237,16 @@ begin
|
||||
|
||||
// Primary key
|
||||
if ds.FieldByName('Key_name').AsString = 'PRIMARY' then
|
||||
ListColumns.Items[j].ImageIndex := ICONINDEX_PRIMARYKEY
|
||||
VTRowDataListColumns[j].ImageIndex := ICONINDEX_PRIMARYKEY
|
||||
// Fulltext index
|
||||
else if isFullText then
|
||||
ListColumns.Items[j].ImageIndex := ICONINDEX_FULLTEXTKEY
|
||||
VTRowDataListColumns[j].ImageIndex := ICONINDEX_FULLTEXTKEY
|
||||
// Unique index
|
||||
else if ds.FieldByName('Non_unique').AsString = '0' then
|
||||
ListColumns.Items[j].ImageIndex := ICONINDEX_UNIQUEKEY
|
||||
VTRowDataListColumns[j].ImageIndex := ICONINDEX_UNIQUEKEY
|
||||
// Normal index
|
||||
else
|
||||
ListColumns.Items[j].ImageIndex := ICONINDEX_INDEXKEY;
|
||||
VTRowDataListColumns[j].ImageIndex := ICONINDEX_INDEXKEY;
|
||||
|
||||
// Column was found and processed
|
||||
break;
|
||||
@ -2265,17 +2254,28 @@ begin
|
||||
end;
|
||||
ds.Next;
|
||||
end;
|
||||
{
|
||||
** note, ansgarbecker, 2007-08-26
|
||||
VT has a pretty autosorting feature, which keeps the sorting even after having
|
||||
filled it with new data.
|
||||
But: Don't use this auto-sorting here, neither automatically nor manual
|
||||
because that would cause big confusion to the user if a just clicked
|
||||
table displays its fields not in the natural order.
|
||||
|
||||
@todo Detect if the list was just refreshed (and then keep sorting)
|
||||
or if another table get displayed (then don't sort, as below)
|
||||
}
|
||||
ListColumns.Header.SortColumn := -1;
|
||||
ListColumns.Header.SortDirection := sdAscending;
|
||||
|
||||
finally
|
||||
ListColumns.Items.EndUpdate;
|
||||
// Remove existing column-sort-images
|
||||
// (TODO: auomatically invoke this method in TSortListView itself)
|
||||
ListColumns.ClearSortColumnImages;
|
||||
|
||||
ListColumns.EndUpdate;
|
||||
Screen.Cursor := crDefault;
|
||||
end;
|
||||
|
||||
MainForm.ShowStatus( STATUS_MSG_READY, 2, false );
|
||||
MainForm.showstatus(ActualDatabase + ': '+ ActualTable + ': ' + IntToStr(ListColumns.Items.count) +' field(s)');
|
||||
MainForm.showstatus(ActualDatabase + ': '+ ActualTable + ': ' + IntToStr(ListColumns.RootNodeCount) +' field(s)');
|
||||
Screen.Cursor := crDefault;
|
||||
end;
|
||||
|
||||
@ -2478,7 +2478,7 @@ begin
|
||||
exit;
|
||||
|
||||
// Add selected items/tables to helper list
|
||||
t := GetSelectedNodesFromVT(ListTables);
|
||||
t := GetVTCaptions(ListTables, True);
|
||||
|
||||
if MessageDlg('Empty ' + IntToStr(t.count) + ' Table(s) ?' + crlf + '(' + implodestr(', ', t) + ')', mtConfirmation, [mbok,mbcancel], 0) <> mrok then
|
||||
exit;
|
||||
@ -2932,44 +2932,41 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TMDIChild.ListColumnsSelectItem(Sender: TObject; Item: TListItem;
|
||||
Selected: Boolean);
|
||||
{**
|
||||
Clicked somewhere in the field-list of the "Table"-tabsheet
|
||||
}
|
||||
procedure TMDIChild.ListColumnsChange(Sender: TBaseVirtualTree; Node:
|
||||
PVirtualNode);
|
||||
var
|
||||
SomeSelected: Boolean;
|
||||
SomeSelected, OneFocused: Boolean;
|
||||
begin
|
||||
// Clicked somewhere in the field-list of the "Table"-tabsheet
|
||||
|
||||
// some columns selected ?
|
||||
SomeSelected := ListColumns.Selected <> nil;
|
||||
OneFocused := Assigned(Sender.FocusedNode);
|
||||
SomeSelected := Length(Sender.GetSortedSelection(False))>0;
|
||||
|
||||
// Toggle state of menuitems and buttons
|
||||
btnTableDropField.Enabled := SomeSelected;
|
||||
DropField1.Enabled := SomeSelected;
|
||||
MenuEditField.Enabled := SomeSelected;
|
||||
btnTableEditField.enabled := SomeSelected;
|
||||
menuRenameColumn.Enabled := SomeSelected;
|
||||
MenuEditField.Enabled := OneFocused;
|
||||
btnTableEditField.enabled := OneFocused;
|
||||
menuRenameColumn.Enabled := OneFocused;
|
||||
end;
|
||||
|
||||
|
||||
procedure TMDIChild.DropField(Sender: TObject);
|
||||
var
|
||||
tn : TTreeNode;
|
||||
i, j: Integer;
|
||||
i : Integer;
|
||||
dropCmd : String;
|
||||
dropList : TStringList;
|
||||
begin
|
||||
// Drop Columns
|
||||
|
||||
// We allow the user to select and delete multiple listItems
|
||||
dropList := TStringList.Create;
|
||||
for i := 0 to ListColumns.Items.Count - 1 do
|
||||
begin
|
||||
if ListColumns.Items[i].Selected then
|
||||
dropList.Add(ListColumns.Items[i].Caption);
|
||||
end;
|
||||
dropList := GetVTCaptions( ListColumns, True );
|
||||
|
||||
// In case all listItems are selected:
|
||||
if dropList.Count = ListColumns.Items.Count then
|
||||
if dropList.Count = Length(VTRowDataListColumns) then
|
||||
begin
|
||||
if MessageDlg('Can''t drop all or the last Field - drop Table '+ActualTable+'?', mtConfirmation, [mbok,mbcancel], 0) = mrok then
|
||||
begin
|
||||
@ -2999,20 +2996,12 @@ begin
|
||||
|
||||
// Rely on the server respective ExecUpdateQuery has raised an exception so the
|
||||
// following code will be skipped on any error
|
||||
for i := ListColumns.Items.Count - 1 downto 0 do
|
||||
begin
|
||||
for j := 0 to dropList.Count - 1 do
|
||||
begin
|
||||
if dropList[j] = ListColumns.Items[i].Caption then
|
||||
begin
|
||||
ListColumns.Items[i].Delete;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
ListColumns.BeginUpdate;
|
||||
ListColumns.DeleteSelectedNodes;
|
||||
ListColumns.EndUpdate;
|
||||
|
||||
// Set focus on automatically focused item
|
||||
ListColumns.Selected := ListColumns.ItemFocused;
|
||||
// Set focus on first item
|
||||
ListColumns.FocusedNode := ListColumns.GetFirstVisible;
|
||||
except
|
||||
On E : Exception do
|
||||
begin
|
||||
@ -3307,8 +3296,8 @@ begin
|
||||
fn := '';
|
||||
fem := femFieldAdd;
|
||||
|
||||
if ListColumns.Selected<>nil then
|
||||
fn := ListColumns.Selected.Caption;
|
||||
if Assigned(ListColumns.FocusedNode) then
|
||||
fn := ListColumns.Text[ListColumns.FocusedNode, 0];
|
||||
|
||||
if fn<>'' then
|
||||
fem := femFieldUpdate;
|
||||
@ -3484,7 +3473,7 @@ var
|
||||
begin
|
||||
// Optimize tables
|
||||
Screen.Cursor := crHourGlass;
|
||||
Selected := GetSelectedNodesFromVT( ListTables );
|
||||
Selected := GetVTCaptions( ListTables, True );
|
||||
try
|
||||
for i:=0 to Selected.Count-1 do
|
||||
begin
|
||||
@ -3506,7 +3495,7 @@ begin
|
||||
// Check tables
|
||||
Screen.Cursor := crHourGlass;
|
||||
tables := '';
|
||||
Selected := GetSelectedNodesFromVT( ListTables );
|
||||
Selected := GetVTCaptions( ListTables, True );
|
||||
try
|
||||
for i:=0 to Selected.Count-1 do
|
||||
begin
|
||||
@ -3550,7 +3539,7 @@ begin
|
||||
// Analyze tables
|
||||
Screen.Cursor := crHourGlass;
|
||||
tables := '';
|
||||
Selected := GetSelectedNodesFromVT( ListTables );
|
||||
Selected := GetVTCaptions( ListTables, True );
|
||||
try
|
||||
for i:=0 to Selected.Count-1 do
|
||||
begin
|
||||
@ -3575,7 +3564,7 @@ begin
|
||||
// Repair tables
|
||||
Screen.Cursor := crHourGlass;
|
||||
tables := '';
|
||||
Selected := GetSelectedNodesFromVT( ListTables );
|
||||
Selected := GetVTCaptions( ListTables, True );
|
||||
try
|
||||
for i:=0 to Selected.Count - 1 do
|
||||
begin
|
||||
@ -4192,7 +4181,7 @@ var
|
||||
begin
|
||||
tabletype := (Sender as TMenuItem).Caption;
|
||||
tabletype := StringReplace( tabletype, '&', '', [rfReplaceAll] ); // Remove Auto-Hotkey
|
||||
Selected := GetSelectedNodesFromVT(ListTables);
|
||||
Selected := GetVTCaptions(ListTables, True);
|
||||
for i:=0 to Selected.Count - 1 do
|
||||
ExecUpdateQuery( 'ALTER TABLE ' + mask(Selected[i]) + ' TYPE = ' + tabletype);
|
||||
Selected.Free;
|
||||
@ -4207,7 +4196,7 @@ var
|
||||
begin
|
||||
// change table-type:
|
||||
if inputquery('Change table-type...','New table-type:', strtype) then begin
|
||||
Selected := GetSelectedNodesFromVT(ListTables);
|
||||
Selected := GetVTCaptions(ListTables, True);
|
||||
for i:=0 to Selected.Count - 1 do
|
||||
ExecUpdateQuery( 'ALTER TABLE ' + mask(Selected[i]) + ' TYPE = ' + strtype );
|
||||
Selected.Free;
|
||||
@ -4537,14 +4526,14 @@ begin
|
||||
// Data-Tab
|
||||
else if (PageControlMain.ActivePage = tabData)
|
||||
and (-1 < gridData.Col)
|
||||
and (gridData.Col <= ListColumns.Items.Count) then
|
||||
and (gridData.Col <= Length(VTRowDataListColumns)) then
|
||||
begin
|
||||
keyword := ListColumns.Items[gridData.Col-1].SubItems[0];
|
||||
keyword := VTRowDataListColumns[gridData.Col-1].Captions[1];
|
||||
end
|
||||
// Table-Tab
|
||||
else if ListColumns.Focused and (ListColumns.Selected <> nil) then
|
||||
else if ListColumns.Focused and Assigned(ListColumns.FocusedNode) then
|
||||
begin
|
||||
keyword := ListColumns.Selected.SubItems[0];
|
||||
keyword := ListColumns.Text[ListColumns.FocusedNode, 1];
|
||||
end
|
||||
else if lboxQueryHelpers.Focused then
|
||||
begin
|
||||
@ -5682,9 +5671,9 @@ begin
|
||||
begin
|
||||
// Keep native order of columns
|
||||
lboxQueryHelpers.Sorted := False;
|
||||
for i := 0 to ListColumns.Items.Count - 1 do
|
||||
for i := 0 to High(VTRowDataListColumns) do
|
||||
begin
|
||||
lboxQueryHelpers.Items.Add(ListColumns.Items[i].Caption);
|
||||
lboxQueryHelpers.Items.Add(VTRowDataListColumns[i].Captions[0]);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -5793,25 +5782,29 @@ end;
|
||||
}
|
||||
procedure TMDIChild.menuRenameColumnClick(Sender: TObject);
|
||||
begin
|
||||
listColumns.Selected.EditCaption;
|
||||
ListColumns.EditNode(ListColumns.FocusedNode, 0);
|
||||
end;
|
||||
|
||||
|
||||
{**
|
||||
Rename a column name from within listColumns
|
||||
}
|
||||
procedure TMDIChild.ListColumnsEdited(Sender: TObject; Item: TListItem;
|
||||
var S: string);
|
||||
procedure TMDIChild.ListColumnsNewText(Sender: TBaseVirtualTree; Node:
|
||||
PVirtualNode; Column: TColumnIndex; NewText: WideString);
|
||||
var
|
||||
def : TDataSet;
|
||||
sql_update, sql_null, sql_default, sql_extra, DefaultValue : String;
|
||||
NodeData : PVTreeData;
|
||||
begin
|
||||
// Try to rename, on any error abort and don't rename ListItem
|
||||
try
|
||||
ensureValidIdentifier( S );
|
||||
ensureValidIdentifier( NewText );
|
||||
|
||||
// Fetch data from listitem
|
||||
NodeData := ListColumns.GetNodeData(Node);
|
||||
|
||||
// Fetch column definition
|
||||
def := GetResults( 'SHOW COLUMNS FROM ' + mask(ActualTable) + ' LIKE ' + esc(Item.Caption), False, False );
|
||||
def := GetResults( 'SHOW COLUMNS FROM ' + mask(ActualTable) + ' LIKE ' + esc(NodeData.Captions[0]), False, False );
|
||||
|
||||
// Check NOT NULL
|
||||
sql_null := 'NULL ';
|
||||
@ -5835,8 +5828,8 @@ begin
|
||||
|
||||
// Concat column definition
|
||||
sql_update := 'ALTER TABLE ' + mask(ActualTable) +
|
||||
' CHANGE ' + mask(Item.Caption) +
|
||||
' ' + mask(S) + ' ' +
|
||||
' CHANGE ' + mask(NodeData.Captions[0]) +
|
||||
' ' + mask(NewText) + ' ' +
|
||||
def.FieldByName('Type').AsString + ' ' +
|
||||
sql_null +
|
||||
sql_default +
|
||||
@ -5844,11 +5837,13 @@ begin
|
||||
|
||||
// Fire ALTER query
|
||||
ExecUpdateQuery( sql_update, False, False );
|
||||
|
||||
// Update listitem
|
||||
NodeData.Captions[0] := NewText;
|
||||
except
|
||||
On E : Exception do
|
||||
begin
|
||||
MessageDlg( E.Message, mtError, [mbOK], 0 );
|
||||
abort;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -5968,6 +5963,11 @@ begin
|
||||
begin
|
||||
NodeData.Captions := VTRowDataListTables[Node.Index].Captions;
|
||||
NodeData.ImageIndex := VTRowDataListTables[Node.Index].ImageIndex;
|
||||
end
|
||||
else if Sender = ListColumns then
|
||||
begin
|
||||
NodeData.Captions := VTRowDataListColumns[Node.Index].Captions;
|
||||
NodeData.ImageIndex := VTRowDataListColumns[Node.Index].ImageIndex;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -5978,13 +5978,30 @@ end;
|
||||
procedure TMDIChild.vstFreeNode(Sender: TBaseVirtualTree; Node:
|
||||
PVirtualNode);
|
||||
var
|
||||
NodeData : PVTreeData;
|
||||
a : TVTreeDataArray;
|
||||
begin
|
||||
// Get the pointer to the node data
|
||||
NodeData := Sender.GetNodeData(Node);
|
||||
// Free data
|
||||
NodeData.Captions.Free;
|
||||
NodeData.ImageIndex := -1;
|
||||
// Detect which global array should be processed
|
||||
if Sender = ListVariables then
|
||||
a := VTRowDataListVariables
|
||||
else if Sender = ListCommandStats then
|
||||
a := VTRowDataListCommandStats
|
||||
else if Sender = ListProcesses then
|
||||
a := VTRowDataListProcesses
|
||||
else if Sender = ListTables then
|
||||
a := VTRowDataListTables
|
||||
else if Sender = ListColumns then
|
||||
a := VTRowDataListColumns;
|
||||
|
||||
if Node.Index < Cardinal(High(a)-1) then
|
||||
begin
|
||||
// Delete node somewhere in the middle of the array
|
||||
// Taken from http://delphi.about.com/cs/adptips2004/a/bltip0204_2.htm
|
||||
System.Move( a[Node.Index +1],
|
||||
a[Node.Index],
|
||||
(Cardinal(Length(a)) - Node.Index -1) * SizeOf(TVTreeData) + 1
|
||||
);
|
||||
end;
|
||||
SetLength(a, Length(a) - 1)
|
||||
end;
|
||||
|
||||
|
||||
|
@ -46,11 +46,7 @@ var
|
||||
reg_columns : TStringList;
|
||||
begin
|
||||
// Take column names from listColumns and add here
|
||||
chklistColumns.Items.Clear;
|
||||
for i := 0 to Mainform.Childwin.listColumns.Items.Count-1 do
|
||||
begin
|
||||
chklistColumns.Items.Add( Mainform.Childwin.listColumns.Items[i].Caption );
|
||||
end;
|
||||
chklistColumns.Items := GetVTCaptions(Mainform.Childwin.ListColumns);
|
||||
|
||||
// Set global reg_name (also used in btnOKClick)
|
||||
reg_name := REGNAME_DISPLAYEDCOLUMNS + '_' + Mainform.Childwin.ActualDatabase + '.' + Mainform.Childwin.ActualTable;
|
||||
@ -218,10 +214,9 @@ begin
|
||||
|
||||
// Add all fieldnames again and check those which are in the checkedfields list
|
||||
chklistColumns.Items.BeginUpdate;
|
||||
chklistColumns.Items.Clear;
|
||||
for i := 0 to Mainform.Childwin.listColumns.Items.Count-1 do
|
||||
chklistColumns.Items := GetVTCaptions(Mainform.Childwin.ListColumns);
|
||||
for i := 0 to chklistColumns.Items.Count-1 do
|
||||
begin
|
||||
chklistColumns.Items.Add( Mainform.Childwin.listColumns.Items[i].Caption );
|
||||
if checkedfields.IndexOf( chklistColumns.Items[i] ) > -1 then
|
||||
chklistColumns.Checked[i] := True;
|
||||
end;
|
||||
|
@ -49,7 +49,7 @@ const
|
||||
|
||||
implementation
|
||||
|
||||
uses main;
|
||||
uses main, helpers;
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
@ -64,11 +64,7 @@ var
|
||||
reg : TRegistry;
|
||||
begin
|
||||
// Take column names from listColumns and add here
|
||||
ColumnNames := TStringList.Create;
|
||||
for i := 0 to Mainform.Childwin.listColumns.Items.Count-1 do
|
||||
begin
|
||||
ColumnNames.Add( Mainform.Childwin.listColumns.Items[i].Caption );
|
||||
end;
|
||||
ColumnNames := GetVTCaptions( Mainform.Childwin.ListColumns );
|
||||
|
||||
// Read original ORDER clause from registry
|
||||
reg := TRegistry.Create();
|
||||
|
@ -358,7 +358,7 @@ begin
|
||||
checkListTables.Items := Mainform.ChildWin.GetCol( 'SHOW TABLES FROM ' + MainForm.mask(comboSelectDatabase.Text) );
|
||||
|
||||
// Fetch selected tables in list
|
||||
Selected := GetSelectedNodesFromVT( Mainform.ChildWin.ListTables );
|
||||
Selected := GetVTCaptions( Mainform.ChildWin.ListTables, True );
|
||||
|
||||
// select all/some:
|
||||
for i:=0 to checkListTables.Items.Count-1 do
|
||||
|
@ -10,7 +10,7 @@ interface
|
||||
|
||||
uses
|
||||
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
||||
StdCtrls, ComCtrls, ImgList, ToolWin, ExtCtrls, Buttons;
|
||||
StdCtrls, ComCtrls, ImgList, ToolWin, ExtCtrls, Buttons, VirtualTrees;
|
||||
|
||||
type
|
||||
TFieldEditorMode = (femFieldAdd,femFieldUpdate,femIndexEditor);
|
||||
@ -130,7 +130,8 @@ procedure TFieldEditForm.InitFieldEditor(Sender: TObject);
|
||||
var
|
||||
strtype : String;
|
||||
i : Integer;
|
||||
ListColumns : TListView;
|
||||
ListColumns : TVirtualStringTree;
|
||||
NodeData : PVTreeData;
|
||||
begin
|
||||
|
||||
// Initiate "Position"-combobox
|
||||
@ -143,9 +144,9 @@ begin
|
||||
|
||||
// get fieldlist
|
||||
// add fieldnames
|
||||
for i:=0 to ListColumns.Items.Count-1 do
|
||||
for i:=0 to High(Mainform.Childwin.VTRowDataListColumns) do
|
||||
begin
|
||||
ComboBoxPosition.Items.Add('AFTER ' + mainform.mask(ListColumns.Items[i].Caption));
|
||||
ComboBoxPosition.Items.Add('AFTER ' + mainform.mask(Mainform.Childwin.VTRowDataListColumns[i].Captions[0]));
|
||||
end;
|
||||
|
||||
// re-fill datatypes-combobox
|
||||
@ -168,8 +169,8 @@ begin
|
||||
EditDefault.Text := '';
|
||||
CheckBoxUnsigned.Checked := true;
|
||||
|
||||
if ListColumns.Selected <> nil then
|
||||
ComboBoxPosition.ItemIndex := ListColumns.Selected.Index+2
|
||||
if Assigned(ListColumns.FocusedNode) then
|
||||
ComboBoxPosition.ItemIndex := ListColumns.FocusedNode.Index+2
|
||||
else
|
||||
ComboBoxPosition.ItemIndex := 0;
|
||||
end;
|
||||
@ -177,12 +178,13 @@ begin
|
||||
// "Field" tab in Update-mode
|
||||
femFieldUpdate:
|
||||
begin
|
||||
EditFieldname.Text := ListColumns.Selected.Caption;
|
||||
EditLength.Text := getEnumValues( ListColumns.Selected.Subitems[0] );
|
||||
EditDefault.Text := ListColumns.Selected.Subitems[2];
|
||||
NodeData := ListColumns.GetNodeData(ListColumns.FocusedNode);
|
||||
EditFieldname.Text := FFieldName;
|
||||
EditLength.Text := getEnumValues( NodeData.Captions[1] );
|
||||
EditDefault.Text := NodeData.Captions[3];
|
||||
|
||||
// extract field type
|
||||
strtype := UpperCase( ListColumns.Selected.Subitems[0] );
|
||||
strtype := UpperCase( NodeData.Captions[1] );
|
||||
if Pos ('(',strtype) > 0 then
|
||||
strtype := Trim(copy (strtype,0,Pos ('(',strtype)-1));
|
||||
|
||||
@ -202,12 +204,12 @@ begin
|
||||
end;
|
||||
|
||||
// set attributes:
|
||||
strtype := LowerCase( ListColumns.Selected.Subitems[0] );
|
||||
strtype := LowerCase( NodeData.Captions[1] );
|
||||
CheckBoxBinary.Checked := pos('binary', strtype) > 0;
|
||||
CheckBoxZerofill.Checked := pos('zerofill', strtype) > 0;
|
||||
CheckBoxUnsigned.Checked := pos('unsigned', strtype) > 0;
|
||||
CheckBoxNotNull.Checked := lowercase(ListColumns.Selected.Subitems[1]) <> 'yes';
|
||||
CheckBoxAutoIncrement.Checked := lowercase(ListColumns.Selected.Subitems[3]) = 'auto_increment';
|
||||
CheckBoxNotNull.Checked := lowercase(NodeData.Captions[2]) <> 'yes';
|
||||
CheckBoxAutoIncrement.Checked := lowercase(NodeData.Captions[4]) = 'auto_increment';
|
||||
|
||||
// TODO: Disable 'auto increment' checkbox if field is not part of index or primary key.
|
||||
end;
|
||||
@ -252,10 +254,7 @@ begin
|
||||
ds.Next;
|
||||
end;
|
||||
|
||||
for i:=0 to cwin.ListColumns.Items.Count-1 do begin
|
||||
if cwin.ListColumns.Items[i] <> nil then
|
||||
self.listColumnsAvailable.Items.Add(cwin.ListColumns.Items[i].Caption);
|
||||
end;
|
||||
listColumnsAvailable.Items := GetVTCaptions(cwin.ListColumns);
|
||||
showkeys();
|
||||
end;
|
||||
|
||||
@ -431,7 +430,7 @@ begin
|
||||
end else if (FMode = femFieldUpdate) then begin
|
||||
cwin.ExecUpdateQuery(
|
||||
'ALTER TABLE ' + mainform.mask(cwin.ActualTable) + ' ' + // table
|
||||
'CHANGE ' + mainform.mask(cwin.ListColumns.Selected.Caption) + ' ' + // old name
|
||||
'CHANGE ' + mainform.mask(FFieldName) + ' ' + // old name
|
||||
mainform.mask(EditFieldName.Text) + ' ' + // new name
|
||||
fielddef
|
||||
);
|
||||
@ -532,13 +531,16 @@ end;
|
||||
@todo code cleanup, get rid of WITH statement
|
||||
}
|
||||
procedure TFieldEditForm.ComboBoxKeysChange(Sender: TObject);
|
||||
var i : Integer;
|
||||
var i, j : Integer;
|
||||
begin
|
||||
if ComboBoxKeys.ItemIndex > -1 then begin
|
||||
listColumnsAvailable.Items.Clear;
|
||||
for i:=0 to Mainform.ChildWin.ListColumns.Items.Count-1 do
|
||||
if (Mainform.ChildWin.ListColumns.Items[i] <> nil) and (klist[ComboBoxKeys.ItemIndex].columns.Indexof(Mainform.ChildWin.ListColumns.Items[i].Caption)=-1) then
|
||||
listColumnsAvailable.Items.Add(Mainform.ChildWin.ListColumns.Items[i].Caption);
|
||||
listColumnsAvailable.Items := GetVTCaptions(Mainform.ChildWin.ListColumns);
|
||||
for i:=0 to klist[ComboBoxKeys.ItemIndex].columns.Count-1 do
|
||||
begin
|
||||
j := listColumnsAvailable.Items.IndexOf(klist[ComboBoxKeys.ItemIndex].columns[i]);
|
||||
if j > -1 then
|
||||
listColumnsAvailable.Items.Delete( j );
|
||||
end;
|
||||
with klist[ComboBoxKeys.ItemIndex] do begin
|
||||
listColumnsUsed.Items := Columns;
|
||||
CheckBoxUnique.OnClick := nil;
|
||||
|
@ -21,6 +21,9 @@ type
|
||||
end;
|
||||
PVTreedata = ^TVTreeData;
|
||||
|
||||
// Standardize the list with node-data-records to be able to
|
||||
// use this type as variables in functions/procedures (fx VT.OnFreeNode)
|
||||
TVTreeDataArray = Array of TVTreeData;
|
||||
|
||||
{$I const.inc}
|
||||
|
||||
@ -81,7 +84,7 @@ type
|
||||
function FormatByteNumber( Bytes: Int64; Decimals: Byte = 1 ): String;
|
||||
function FormatTimeNumber( Seconds: Cardinal ): String;
|
||||
function TColorToHex( Color : TColor ): string;
|
||||
function GetSelectedNodesFromVT( VT: TVirtualStringTree; Column: Integer = 0 ): TStringList;
|
||||
function GetVTCaptions( VT: TVirtualStringTree; OnlySelected: Boolean = False; Column: Integer = 0 ): TStringList;
|
||||
|
||||
var
|
||||
MYSQL_KEYWORDS : TStringList;
|
||||
@ -1996,18 +1999,31 @@ end;
|
||||
Return a TStringList with captions from all selected nodes in a VirtualTree
|
||||
Especially helpful when toMultiSelect is True
|
||||
}
|
||||
function GetSelectedNodesFromVT( VT: TVirtualStringTree; Column: Integer = 0 ): TStringList;
|
||||
function GetVTCaptions( VT: TVirtualStringTree; OnlySelected: Boolean = False; Column: Integer = 0 ): TStringList;
|
||||
var
|
||||
SelectedNodes : TNodeArray;
|
||||
NodeData : PVTreeData;
|
||||
Node : PVirtualNode;
|
||||
i: Integer;
|
||||
begin
|
||||
Result := TStringList.Create;
|
||||
if OnlySelected then
|
||||
begin
|
||||
// Fetch only selected nodes
|
||||
SelectedNodes := VT.GetSortedSelection(False);
|
||||
for i := 0 to Length(SelectedNodes) - 1 do
|
||||
begin
|
||||
NodeData := VT.GetNodeData(SelectedNodes[i]);
|
||||
Result.Add(NodeData.Captions[Column]);
|
||||
Node := SelectedNodes[i];
|
||||
Result.Add( VT.Text[ Node, Column ] );
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
// Fetch all nodes
|
||||
Node := VT.GetFirst;
|
||||
for i := 0 to VT.RootNodeCount - 1 do
|
||||
begin
|
||||
Result.Add( VT.Text[ Node, Column ] );
|
||||
Node := VT.GetNext(Node);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -994,7 +994,7 @@ begin
|
||||
t.add(mask(DBRightClickSelectedItem.Parent.text) + '.' + mask(DBRightClickSelectedItem.text));
|
||||
end else if PageControlMain.ActivePage = tabDatabase then begin
|
||||
// Invoked from one of the various buttons, SheetDatabase is the active page, drop highlighted table(s).
|
||||
t := GetSelectedNodesFromVT(ListTables);
|
||||
t := GetVTCaptions(ListTables, True);
|
||||
for i:=0 to t.count-1 do
|
||||
begin
|
||||
t[i] := mask(t[i]);
|
||||
|
@ -72,15 +72,16 @@ begin
|
||||
cwin := Mainform.ChildWin;
|
||||
|
||||
// which ListView to print?
|
||||
case cwin.PageControlMain.ActivePageIndex of
|
||||
// TODO: Reactivate after switching to VirtualTree!
|
||||
// case cwin.PageControlMain.ActivePageIndex of
|
||||
// 0 : case cwin.PageControlHost.ActivePageIndex of
|
||||
// 0 : begin list := cwin.ListVariables; title := 'Server-Variables for ' + cwin.Conn.MysqlParams.Host; end;
|
||||
// 1 : begin list := cwin.ListProcesses; title := 'Processlist for ' + cwin.Conn.MysqlParams.Host; end;
|
||||
// 2 : begin list := cwin.ListCommandStats; title := 'Command-statistics for ' + cwin.Conn.MysqlParams.Host; end;
|
||||
// end;
|
||||
// 1 : begin list := cwin.ListTables; title := 'Tables-List for Database ' + cwin.ActualDatabase; end;
|
||||
2 : begin list := cwin.ListColumns; title := 'Field-List for ' + cwin.ActualDatabase + '/' + cwin.ActualTable; end;
|
||||
end;
|
||||
// 2 : begin list := cwin.ListColumns; title := 'Field-List for ' + cwin.ActualDatabase + '/' + cwin.ActualTable; end;
|
||||
// end;
|
||||
caption := 'Print ' + title + '...';
|
||||
|
||||
// delete all CheckBoxes
|
||||
|
@ -95,7 +95,7 @@ begin
|
||||
end;
|
||||
|
||||
// Fetch selected nodes
|
||||
Selected := GetSelectedNodesFromVT(ListTables);
|
||||
Selected := GetVTCaptions(ListTables, True);
|
||||
|
||||
// for tables found
|
||||
for t := 0 to (query.RecordCount - 1) do
|
||||
|
Reference in New Issue
Block a user