lazarus/components/ideintf/lazstringgridedit.pas

350 lines
9.8 KiB
ObjectPascal

{
*****************************************************************************
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
}
unit LazStringGridEdit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,
// LCL
Forms, Controls, Dialogs, StdCtrls, Buttons, Grids, ExtCtrls,
// IdeIntf
ObjInspStrConsts, IDEWindowIntf;
type
{ TStringGridEditorDlg }
TStringGridEditorDlg = class(TForm)
BtnOK: TBitBtn;
BtnCancel: TBitBtn;
BtnApply: TBitBtn;
BtnHelp: TBitBtn;
BtnLoad: TButton;
BtnSave: TButton;
BtnClean: TButton;
GroupBox: TGroupBox;
Images: TImageList;
OpenDialog: TOpenDialog;
BtnPanel: TPanel;
LoadSavePanel: TPanel;
PanelEdit: TPanel;
SaveDialog: TSaveDialog;
BtnAddRow: TSpeedButton;
BtnDelRow: TSpeedButton;
BtnRowUp: TSpeedButton;
BtnRowDown: TSpeedButton;
BtnAddCol: TSpeedButton;
BtnDelCol: TSpeedButton;
BtnColLeft: TSpeedButton;
BtnColRight: TSpeedButton;
StringGrid: TStringGrid;
procedure BtnApplyClick(Sender: TObject);
procedure BtnCleanClick(Sender: TObject);
procedure BtnLoadClick(Sender: TObject);
procedure BtnSaveClick(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure StringGridHeaderClick(Sender: TObject; IsColumn: Boolean;
Index: Integer);
procedure StringGridPrepareCanvas({%H-}sender: TObject; Col, Row: Integer;
{%H-}aState: TGridDrawState);
procedure ManageGrid(Sender:TObject);
procedure SwapRowCol(Sender:TObject);
private
FModified: Boolean;
FStringGrid: TStringGrid;
FGroupBoxHeader: String;
procedure AssignGrid(Dest, Src: TStringGrid);
procedure UpdateBtnStates;
procedure UpdateGridInfo;
public
property Modified: Boolean read FModified;
procedure LoadFromGrid(AStringGrid: TStringGrid);
procedure SaveToGrid;
end;
implementation
{$R *.lfm}
var
saved_InputQueryEditSizePercents: Integer;
type
TStringGridAccess = class(TStringGrid)
public
function ColumnIndexFromGridColumn(AIndex: Integer):Integer;
end;
function TStringGridAccess.ColumnIndexFromGridColumn(AIndex: Integer): Integer;
begin
Result := inherited;
end;
{ TStringGridEditorDlg }
procedure TStringGridEditorDlg.AssignGrid(Dest, Src: TStringGrid);
var
I, J: Integer;
col: TGridColumn;
begin
Dest.BeginUpdate;
try
Dest.Clear;
Dest.RowCount := Src.RowCount;
if Src.Columns.Enabled then
begin
Dest.Columns.Clear;
for I := 0 to Src.Columns.Count-1 do
begin
col := Dest.Columns.Add;
col.Assign(Src.Columns[I]);
end;
Dest.FixedCols := Src.FixedCols;
Dest.FixedRows := Src.FixedRows;
end else
Dest.ColCount := Src.ColCount;
for I := 0 to Src.RowCount - 1 do
Dest.RowHeights[I] := Src.RowHeights[I];
for I := 0 to Src.ColCount - 1 do
Dest.ColWidths[I] := Src.ColWidths[I];
for I := 0 to Src.ColCount - 1 do
for J := 0 to Src.RowCount - 1 do
Dest.Cells[I, J] := Src.Cells[I, J];
finally
Dest.EndUpdate;
end;
end;
procedure TStringGridEditorDlg.FormCreate(Sender: TObject);
begin
Caption := sccsSGEdtCaption;
GroupBox.Caption := sccsSGEdtGrp;
BtnClean.Caption := sccsSGEdtClean;
BtnApply.Caption := sccsSGEdtApply;
BtnLoad.Caption := sccsSGEdtLoad;
BtnSave.Caption := sccsSGEdtSave;
BtnHelp.Caption:=cActionListEditorHelpCategory;
BtnCancel.Caption:=oiStdActDataSetCancel1Hint;
BtnOK.Caption:=oisOk2;
OpenDialog.Title := sccsSGEdtOpenDialog;
SaveDialog.Title := sccsSGEdtSaveDialog;
BtnRowUp.Hint := sccsSGEdtMoveRowsCols;
BtnRowDown.Hint := sccsSGEdtMoveRowsCols;
BtnColLeft.Hint := sccsSGEdtMoveRowsCols;
BtnColRight.Hint := sccsSGEdtMoveRowsCols;
BtnAddRow.Hint := sccsSGEdtInsRow;
BtnAddCol.Hint := sccsSGEdtInsCol;
BtnDelRow.Hint := sccsSGEdtDelRow;
BtnDelCol.Hint := sccsSGEdtDelCol;
StringGrid.ExtendedColSizing := True;
IDEDialogLayoutList.ApplyLayout(Self);
FGroupBoxHeader := Groupbox.Caption;
end;
procedure TStringGridEditorDlg.StringGridHeaderClick(Sender: TObject;
IsColumn: Boolean; Index: Integer);
var
s: String;
colIndex: Integer;
mouseCell: TPoint;
begin
mouseCell := StringGrid.MouseToCell(StringGrid.ScreenToClient(Mouse.CursorPos));
if IsColumn then
begin
if StringGrid.Columns.Enabled and (Index >= StringGrid.FixedCols) then
begin
colIndex := TStringGridAccess(StringGrid).ColumnIndexFromGridColumn(Index);
if mouseCell.Y = 0 then
begin
s := InputBox(sccsSGEdtEditColTitle, sccsSGEdtTitle, StringGrid.Columns[colIndex].Title.Caption);
StringGrid.Columns[colIndex].Title.Caption := s;
end else
begin
s := InputBox(sccsSGEdtEditColTitle, sccsSGEdtTitle, StringGrid.Cells[Index, mouseCell.Y]);
StringGrid.Cells[Index, mouseCell.Y] := s;
end;
end else
begin
s := InputBox(sccsSGEdtEditFixedColTitle, sccsSGEdtTitle, StringGrid.Cells[Index, mouseCell.Y]);
StringGrid.Cells[Index, mouseCell.Y] := s;
end;
end else
begin
s := InputBox(sccsSGEdtEditRowHeader, sccsSGEdtTitle, StringGrid.Cells[mouseCell.X, Index]);
StringGrid.Cells[mouseCell.X, Index] := s;
end;
end;
procedure TStringGridEditorDlg.FormClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
IDEDialogLayoutList.SaveLayout(Self);
cInputQueryEditSizePercents := saved_InputQueryEditSizePercents;
end;
procedure TStringGridEditorDlg.BtnApplyClick(Sender: TObject);
begin
SaveToGrid;
end;
procedure TStringGridEditorDlg.BtnCleanClick(Sender: TObject);
begin
StringGrid.Clean;
end;
procedure TStringGridEditorDlg.BtnLoadClick(Sender: TObject);
begin
if OpenDialog.Execute then
begin
StringGrid.SaveOptions := [soDesign, soContent];
StringGrid.LoadFromFile(OpenDialog.FileName);
end;
end;
procedure TStringGridEditorDlg.BtnSaveClick(Sender: TObject);
begin
if SaveDialog.Execute then
begin
StringGrid.SaveOptions := [soDesign, soContent];
StringGrid.SaveToFile(SaveDialog.FileName);
end;
end;
procedure TStringGridEditorDlg.FormActivate(Sender: TObject);
var
delta: Integer;
begin
// Avoid the ultra-wide InputBox.
saved_InputQueryEditSizePercents := cInputQueryEditSizePercents;
cInputQueryEditSizePercents := 0;
// Adjust constraints (assuming all borderspacings are equal)
delta := Groupbox.BorderSpacing.Around;
Constraints.MinWidth := BtnColRight.Left + BtnColRight.Width +
(BtnClean.Left + BtnClean.Width - BtnLoad.Left) + 6*delta;
if Width < Constraints.MinWidth then
Width := 0; // Enforce constraints
end;
procedure TStringGridEditorDlg.StringGridPrepareCanvas(sender: TObject; Col,
Row: Integer; aState: TGridDrawState);
begin
if (Col < FStringGrid.FixedCols) or (Row < FStringGrid.FixedRows) then
StringGrid.Canvas.Brush.Color := FStringGrid.FixedColor;
end;
procedure TStringGridEditorDlg.ManageGrid(Sender:TObject);
var
irow, icol: integer;
fixed: Integer;
begin
irow := StringGrid.Row;
icol := StringGrid.Col;
if (Sender = BtnAddRow) then
begin
fixed := StringGrid.FixedRows;
StringGrid.InsertColRow(false, irow);
StringGrid.FixedRows := fixed;
StringGrid.Row := StringGrid.Row-1;
end
else
if (Sender = BtnDelRow) and (irow >= 0) then
begin
if MessageDlg(Application.Title, Format(sccsSGEdtDelRowNo, [irow]), mtConfirmation, mbYesNo, 0) = mrYes then
StringGrid.DeleteRow(irow);
end else
if Sender = BtnAddCol then
begin
fixed := StringGrid.FixedCols;
StringGrid.InsertColRow(true, icol);
StringGrid.FixedCols := fixed;
StringGrid.Col := StringGrid.Col - 1;
end
else
if (Sender = BtnDelCol) and (icol >= 0) then
if MessageDlg(Application.Title, Format(sccsSGEdtDelColNo, [icol]), mtConfirmation, mbYesNo, 0) = mrYes then
StringGrid.DeleteCol(icol);
UpdateBtnStates;
UpdateGridInfo;
end;
procedure TStringGridEditorDlg.SwapRowCol(Sender:TObject);
begin
if Sender = BtnColLeft then begin
if StringGrid.Col > StringGrid.FixedCols then
StringGrid.ExchangeColRow(true,StringGrid.Col-1,StringGrid.Col);
end else
if Sender = BtnRowUp then begin
if StringGrid.Row > StringGrid.FixedRows then
StringGrid.ExchangeColRow(false,StringGrid.Row-1,StringGrid.Row);
end;
if Sender = BtnColRight then begin
if StringGrid.Col < StringGrid.ColCount-1 then
StringGrid.ExchangeColRow(true,StringGrid.Col,StringGrid.Col+1);
end;
if Sender = BtnRowDown then begin
if StringGrid.Row < StringGrid.RowCount-1 then
StringGrid.ExchangeColRow(false,StringGrid.Row,StringGrid.Row+1);
end;
UpdateBtnStates;
end;
procedure TStringGridEditorDlg.LoadFromGrid(AStringGrid: TStringGrid);
begin
if Assigned(AStringGrid) then
begin
FStringGrid := AStringGrid;
AssignGrid(StringGrid, AStringGrid);
UpdateBtnStates;
UpdateGridInfo;
FModified := False;
end;
end;
procedure TStringGridEditorDlg.SaveToGrid;
begin
if Assigned(FStringGrid) then
begin
AssignGrid(FStringGrid, StringGrid);
FModified := True;
end;
end;
procedure TStringGridEditorDlg.UpdateBtnStates;
begin
BtnDelRow.Enabled := StringGrid.RowCount > StringGrid.FixedRows;
BtnDelCol.Enabled := StringGrid.ColCount > StringGrid.FixedCols;
BtnColLeft.Enabled := StringGrid.Col > StringGrid.FixedCols;
BtnRowUp.Enabled := StringGrid.Row > StringGrid.FixedRows;
BtnColRight.Enabled := StringGrid.Col < StringGrid.ColCount-1;
BtnRowDown.Enabled := StringGrid.Row < StringGrid.RowCount-1;
end;
procedure TStringGridEditorDlg.UpdateGridInfo;
begin
GroupBox.Caption := FGroupboxHeader + ' ' +
Format(sccsSGEdtColRowInfo, [StringGrid.ColCount, StringGrid.RowCount]);
end;
end.