Display first available text column value when editing InnoDB contents. Fixes issue #1849.

This commit is contained in:
Ansgar Becker
2010-04-14 22:45:12 +00:00
parent 46fd8f5e99
commit b1ab76e0ba
2 changed files with 62 additions and 17 deletions

View File

@ -93,7 +93,7 @@ type
private private
FCombo: TComboBox; FCombo: TComboBox;
public public
ValueList: TStringList; ValueList, DisplayList: TStringList;
AllowCustomText: Boolean; AllowCustomText: Boolean;
constructor Create(Tree: TVirtualStringTree); override; constructor Create(Tree: TVirtualStringTree); override;
destructor Destroy; override; destructor Destroy; override;
@ -707,6 +707,7 @@ begin
FCombo.OnKeyDown := DoKeyDown; FCombo.OnKeyDown := DoKeyDown;
FCombo.OnExit := DoEndEdit; FCombo.OnExit := DoEndEdit;
ValueList := TStringList.Create; ValueList := TStringList.Create;
DisplayList := TStringList.Create;
FMainControl := FCombo; FMainControl := FCombo;
end; end;
@ -729,26 +730,39 @@ end;
function TEnumEditorLink.EndEdit: Boolean; stdcall; function TEnumEditorLink.EndEdit: Boolean; stdcall;
var
NewText: String;
begin begin
Result := EndEditHelper(FCombo.Text); if AllowCustomText then
NewText := FCombo.Text
else if ValueList.Count > 0 then
NewText := ValueList[FCombo.ItemIndex]
else
NewText := '';
Result := EndEditHelper(NewText);
end; end;
function TEnumEditorLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall; function TEnumEditorLink.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean; stdcall;
var var
i: Integer; i: Integer;
Items: TStringList;
begin begin
Result := inherited PrepareEdit(Tree, Node, Column); Result := inherited PrepareEdit(Tree, Node, Column);
if Result then begin if Result then begin
for i := 0 to ValueList.Count - 1 do if DisplayList.Count = ValueList.Count then
FCombo.Items.Add(ValueList[i]); Items := DisplayList
else
Items := ValueList;
for i:=0 to Items.Count - 1 do
FCombo.Items.Add(Items[i]);
if AllowCustomText then begin if AllowCustomText then begin
FCombo.Style := csDropDown; FCombo.Style := csDropDown;
FCombo.Text := FCellText; FCombo.Text := FCellText;
end else begin end else begin
// Set style to OwnerDraw, otherwise we wouldn't be able to adjust the combo's height // Set style to OwnerDraw, otherwise we wouldn't be able to adjust the combo's height
FCombo.Style := csOwnerDrawFixed; FCombo.Style := csOwnerDrawFixed;
FCombo.ItemIndex := FCombo.Items.IndexOf(FCellText); FCombo.ItemIndex := ValueList.IndexOf(FCellText);
end; end;
end; end;
end; end;

View File

@ -7375,31 +7375,62 @@ var
InplaceEditor: TInplaceEditorLink; InplaceEditor: TInplaceEditorLink;
TypeCat: TDatatypeCategoryIndex; TypeCat: TDatatypeCategoryIndex;
ForeignKey: TForeignKey; ForeignKey: TForeignKey;
TblColumn: TTableColumn;
idx: Integer; idx: Integer;
Col: String; KeyCol, TextCol, SQL, CreateTable: String;
ForeignValues: TStringList; Columns: TTableColumnList;
Keys: TTableKeyList;
ForeignKeys: TForeignKeyList;
ForeignResults: TMySQLQuery;
begin begin
VT := Sender as TVirtualStringTree; VT := Sender as TVirtualStringTree;
// Find foreign key values on InnoDB table cells // Find foreign key values on InnoDB table cells
ForeignValues := nil;
for ForeignKey in SelectedTableForeignKeys do begin for ForeignKey in SelectedTableForeignKeys do begin
idx := ForeignKey.Columns.IndexOf(DataGrid.Header.Columns[Column].Text); idx := ForeignKey.Columns.IndexOf(DataGrid.Header.Columns[Column].Text);
if idx > -1 then begin if idx > -1 then begin
Col := Mask(ForeignKey.ForeignColumns[idx]); // Find the first text column if available and use that for displaying in the pulldown instead of using meaningless id numbers
ForeignValues := Connection.GetCol('SELECT '+Col+' FROM '+MaskMulti(ForeignKey.ReferenceTable)+' GROUP BY '+Col+' ORDER BY '+Col); CreateTable := Connection.GetVar('SHOW CREATE TABLE '+MaskMulti(ForeignKey.ReferenceTable), 1);
Columns := TTableColumnList.Create;
Keys := nil;
ForeignKeys := nil;
ParseTableStructure(CreateTable, Columns, Keys, ForeignKeys);
TextCol := '';
for TblColumn in Columns do begin
if (TblColumn.DataType.Category = dtcText) and (TblColumn.Name <> ForeignKey.ForeignColumns[idx]) then begin
TextCol := TblColumn.Name;
break;
end;
end;
KeyCol := Mask(ForeignKey.ForeignColumns[idx]);
SQL := 'SELECT '+KeyCol;
if TextCol <> '' then SQL := SQL + ', LEFT(' + Mask(TextCol) + ', 256)';
SQL := SQL + ' FROM '+MaskMulti(ForeignKey.ReferenceTable)+' GROUP BY '+KeyCol+' ORDER BY ';
if TextCol <> '' then SQL := SQL + Mask(TextCol) else SQL := SQL + KeyCol;
SQL := SQL + ' LIMIT 1000';
EnumEditor := TEnumEditorLink.Create(VT);
EnumEditor.DataType := DataGridResult.Columns[Column].Datatype;
EditLink := EnumEditor;
if TextCol = '' then
EnumEditor.ValueList := Connection.GetCol(SQL)
else begin
ForeignResults := Connection.GetResults(SQL);
while not ForeignResults.Eof do begin
EnumEditor.ValueList.Add(ForeignResults.Col(0));
EnumEditor.DisplayList.Add(ForeignResults.Col(0)+': '+ForeignResults.Col(1));
ForeignResults.Next;
end;
end;
break; break;
end; end;
end; end;
TypeCat := DataGridResult.Columns[Column].DatatypeCat; TypeCat := DataGridResult.Columns[Column].DatatypeCat;
if Assigned(ForeignValues) then begin if Assigned(EditLink) then
EnumEditor := TEnumEditorLink.Create(VT); // Editor was created above, do nothing now
EnumEditor.AllowCustomText := True; else if (TypeCat = dtcText) or ((TypeCat in [dtcBinary, dtcSpatial]) and actBlobAsText.Checked) then begin
EnumEditor.DataType := DataGridResult.Columns[Column].Datatype;
EnumEditor.ValueList := ForeignValues;
EditLink := EnumEditor;
end else if (TypeCat = dtcText) or ((TypeCat in [dtcBinary, dtcSpatial]) and actBlobAsText.Checked) then begin
InplaceEditor := TInplaceEditorLink.Create(VT); InplaceEditor := TInplaceEditorLink.Create(VT);
InplaceEditor.DataType := DataGridResult.Columns[Column].Datatype; InplaceEditor.DataType := DataGridResult.Columns[Column].Datatype;
InplaceEditor.MaxLength := DataGridResult.Columns[Column].MaxLength; InplaceEditor.MaxLength := DataGridResult.Columns[Column].MaxLength;