You are not logged in.
ok. thank you for explanation.
not working with checking ARaw>0.
...
if ARow > 0 then
with TDrawGrid(Sender).Canvas do begin
if ATValue = 3 then
Font.Style:= Font.Style + [fsBold]
else
Font.Style:= Font.Style - [fsBold];
// if ARow > 0 then
TDrawGrid(Sender).DefaultDrawing:= True;
end;
...
Solved.
I just set the DefaultDrawing to True after Setting Canvas.Font.Style
procedure TBPBaseMainForm.DoOnDrawCellEvent(Sender: TObject; ACol, ARow: Longint; Rect: TRect; State: TGridDrawState);
var T2G: TSQLTableToGrid;
ATIndex: Integer;
ATValue: Integer;
begin
T2G:= TSQLTableToGrid.From(TDrawGrid(Sender));
ATIndex:= T2G.Table.FieldIndex('AccountType');
ATValue:= T2G.Table.GetAsInteger(ARow,ATIndex);
// if not(gdFixed in State) then
with TDrawGrid(Sender).Canvas do begin
if ATValue = 3 then
Font.Style:= Font.Style + [fsBold]
else
Font.Style:= Font.Style - [fsBold];
TDrawGrid(Sender).DefaultDrawing:= True; //Just add this line;
end;
end;
But i loss the look and feel of the header.
any idea?
thanks
thank you.
BTW, what is the shortage when i use FloatToCurr(resDouble)?
i want to set the font as Bold in the TSQLTableToGrid row for some special condition.
this code is working with font as Bold, but i can not select the row.
procedure TBPBaseMainForm.DoOnDrawCellEvent(Sender: TObject; ACol, ARow: Longint; Rect: TRect; State: TGridDrawState);
var T2G: TSQLTableToGrid;
ATIndex: Integer;
ATValue: Integer;
begin
T2G:= TSQLTableToGrid.From(TDrawGrid(Sender));
if not(gdFocused in State) then begin
ATIndex:= T2G.Table.FieldIndex('AccountType');
ATValue:= T2G.Table.GetAsInteger(ARow,ATIndex);
with TDrawGrid(Sender) do begin
if ATValue = 3 then
Canvas.Font.Style:= Canvas.Font.Style + [fsBold]
else
Canvas.Font.Style:= Canvas.Font.Style - [fsBold];
end;
end;
end;
what is missing?
yes, it's working great. thanks.
TSynLabeledEdit.IsValid doesn't work for me with sleCurrency Kind.
...
sleCurrency: begin
val(Txt,resDouble,err);
if err<>0 then exit;
// ToValue := Currency(resDouble); //this is not work as expected
ToValue := FloatToCurr(resDouble); // i try this, and so far, its work
end;
...
before we could get the Model and the Model Index from a Class Record, with Rec.RecordProps.
M: = Rec.RecordProps.Model. Also to get the Index of RecordClass from the Model,
RCIndex: = Rec.RecordProps.ModelTableIndex.
But now it does not get done.
Now I'm using:
M: = Client.Model and
RCIndex: = Model.GetTableIndex (aRecordClass);
Did I use the right way?
thank you
@mpv. i never use ClientDataSet before. thnks you for the explanation.
@mpv: i don't understand about
put dataset Delta back to TSQLRecord class
.
i'll try to implement OnBeforeApplyUpdate as you suggest.
thnk you.
another issue, i never succes with TSQLRawBlob field. the field never added to TCLientDataset.
Thanks for the quick response.
Actually I also do not want to use the RAD approach, I prefer to wear such a way that mORMot do (generate control from the code).
But I'm trying to work with mORMot to make scheduling application, that I use cxScheduler for the user interface.
I really do not want to use cxScheduler in BoundMode that requires TDataSet and TDataSource.
Working in UnboundMode also actually very easy, TcxScheduleStorage have LoadFromFile and SaveToFile method.
But I have trouble when trying to save it to mORMot.
Then I go back to the BoundMode, with TSQLTableToDataSet facilities of mORMot. And I still tend to want to use cxSchedulre in UnboundMode.
Yes, changing aTable.FieldLengthMax() into aTable.FieldLengthMax()+1 in the unit SQLite3VCL solved the problem.
and abaut
EDatabaseError with message 'Cannot access field 'ID' as type Variant
i just add 2 lines of code to handle TLargeintField, and so far it's work.
...
if result.Fields[F] is TLargeintField then
result.Fields[F].AsInteger := aTable.GetAsInteger(i,F)
else
result.Fields[F].AsVariant := aTable.GetVariant(i,F,aClient);
will you add method in the future to Fill TSQLTable Back from updated conten of TDataset?
thank you.
Yes, there one row data, but not all column have a value.
then, i delete the row data, and exception still ocured.
i also got exception class EDBClient with message 'Invalid Parameter' at line 140
TClientDataSet(result).CreateDataSet;
this is how i call the function:
fTableSchedule:= fClient.List([TSQLSchedule],'*');
fDataSetSchedule:= TSQLTableToDataSet(Self,fTableSchedule,fClient);
and this is TSQLSchedule class declaration;
TSQLBaseSigned = class(TSQLRecordSigned)
private
fDocumentNumber: RawUTF8;
fDate: TTimeLog;
fData: TSQLRawBlob;
fNote: TSQLRawBlob;
fCreatedTime: TCreateTime;
fModifiedTime: TModTime;
fTimeLog: TTimeLog;
protected
public
published
property DocumentNumber: RawUTF8 read fDocumentNumber write fDocumentNumber stored False;
property Date: TTimeLog read fDate write fDate;
property Data: TSQLRawBlob read fData write fData;
property Note: TSQLRawBlob read fNote write fNote;
property CreatedTime: TCreateTime read fCreatedTime write fCreatedTime;
property ModifiedTime: TModTime read fModifiedTime write fModifiedTime;
property TimeLog: TTimeLog read fTimeLog write fTimeLog;
property SignatureTime;
property Signature;
end;
TSQLBaseSchedule = class(TSQLBaseSigned)
private
// internal fields
fActualFinish: Integer;
fActualStart: Integer;
fCaption: RawUTF8;
fEventType: Integer;
fFinish: TTimeLog;
fLabelColor: Integer;
fLocation: RawUTF8;
fMessage: RawUTF8;
fOptions: Integer;
fParentID: TSQLBaseSchedule;
fRecurrenceIndex: Integer;
fRecurrenceInfo: TSQLRawBlob;
fReminderDate: TTimeLog;
fReminderMinutesBeforeStart: Integer;
fResourceID: TSQLRawBlob;
fStart: TTimeLog;
fState: Integer;
// additional for tasks
fTaskComplete: Integer;
fTaskIndex: Integer;
fTaskLinks: TSQLRawBlob;
fTaskStatus: Integer;
// additional for reminders
fReminderResourcesData: TSQLRawBlob;
protected
public
published
// internal fields
property ActualFinish: Integer read fActualFinish write fActualFinish;
property ActualStart: Integer read fActualStart write fActualStart;
property Caption: RawUTF8 read fCaption write fCaption;
property EventType: Integer read fEventType write fEventType;
property Finish: TTimeLog read fFinish write fFinish;
property LabelColor: Integer read fLabelColor write fLabelColor;
property Location: RawUTF8 read fLocation write fLocation;
property Message: RawUTF8 read fMessage write fMessage;
property Options: Integer read fOptions write fOptions;
property ParentID: TSQLBaseSchedule read fParentID write fParentID;
property RecurrenceIndex: Integer read fRecurrenceIndex write fRecurrenceIndex;
property RecurrenceInfo: TSQLRawBlob read fRecurrenceInfo write fRecurrenceInfo;
property ReminderDate: TTimeLog read fReminderDate write fReminderDate;
property ReminderMinutesBeforeStart: Integer read fReminderMinutesBeforeStart write fReminderMinutesBeforeStart;
property ResourceID: TSQLRawBlob read fResourceID write fResourceID;
property Start: TTimeLog read fStart write fStart;
property State: Integer read fState write fState;
// additional for tasks
property TaskComplete: Integer read fTaskComplete write fTaskComplete;
property TaskIndex: Integer read fTaskIndex write fTaskIndex;
property TaskLinks: TSQLRawBlob read fTaskLinks write fTaskLinks;
property TaskStatus: Integer read fTaskStatus write fTaskStatus;
// additional for reminders
property ReminderResourcesData: TSQLRawBlob read fReminderResourcesData write fReminderResourcesData;
end;
TSQLSchedule = class(TSQLBaseSchedule)
private
protected
public
published
end;
thanks for your support.
hi, i got this error when trying to fill DB VCL dataset with TSQLTable.
EDatabaseError with message 'Cannot access field 'ID' as type Variant
i use SQLite3VCL.
one more: how to save back from Dataset to the framework?
many thanks
finally.., after all day trying..
RTP:= Pointer(fRibbon.GetParameter(RC));
thank you..
hallo ab, i cannot compile this code:
..
RTP: ^TFileRibbonTabParameters;
..
RTP:= fRibbon.GetParameter(RC);
//[Error] BPBaseEdit.pas(380): Incompatible types: 'TSQLRibbonTabParameters' and 'TFileRibbonTabParameters'
i also try this code
RTP:= TFileRibbonTabParameters(fRibbon.GetParameter(RC));
or
RTP^:= TFileRibbonTabParameters(fRibbon.GetParameter(RC));
or
RTP:= TFileRibbonTabParameters(fRibbon.GetParameter(RC)^);
//with compiler error: Invalid typecast
what i'm doing wrong? I don't know much about pointer.
thank you
Hallo ab, i tried create a unit to handle TSQLRecord and TSQLRecordMany published property. Just Inpired by TDBNavigatorButton from DB.pas unit.
i need some suggestion, the unit contain aroun 1200 lines of code. i want to share with the others even not so good code.
can i post here? or can i send to your email please?
ok, thank you. i'll try it.
How to read customs Field from TSQLRibbonTabParameters?
TFileRibbonTabParameters = object(TSQLRibbonTabParameters)
/// the SynFile actions
Actions: TFileActions;
Test1: string;
..
end;
...
var
T: TFileRibbonTabParameters;
Test: string;
begin
T:= Ribbon.GetParameter(TSQLSomeRecord)^;
Test:= T.Test1;
...
end;
is it possible to Save and load TSQLRibbonTabParameters to file on-the-fly?
thanks
this line of code also not compiling in fileclient.pas from the synfile
DrawTextAcrossColsFromCSV(PC,$C0C0FF);
Is it because e.g. the "Country" column does not have an easy way to filter the entry?
yes. i think there are an issue if the alias name same as Name of Field of the Primary table
(SELECT Name FROM Country WHERE ID=Country) AS Country
but, if i change the alias name, e.g CountryName, it's work.
but qoContains sometimes not found matches row, even if with the sftUTF8Text.
I did not do anything on SQLite3UIQuery, just create an instance on the new form.
TSQLBase = class(TSQLRecord)
private
fCode: RawUTF8;
fName: RawUTF8;
fIsInactive: Boolean;
fTimeLog: TTimeLog;
fCreatedTime: TCreateTime;
fModifiedTime: TModTime;
protected
public
property Code: RawUTF8 read fCode write fCode;
property Name: RawUTF8 read fName write fName;
property IsInactive: Boolean read fIsInactive write fIsInactive;
property TimeLog: TTimeLog read fTimeLog write fTimeLog;
property CreatedTime: TCreateTime read fCreatedTime write fCreatedTime;
property ModifiedTime: TModTime read fModifiedTime write fModifiedTime;
end;
TSQLBaseRegion = class(TSQLBase)
private
fLatitude: Double;
fLongitude: Double;
protected
public
published
property Code stored False;
property Name;
property Latitude: Double read fLatitude write fLatitude;
property Longitude: Double read fLongitude write fLongitude;
end;
TSQLBaseRegionClass = class of TSQLBaseRegion;
TSQLCity = class(TSQLBaseRegion)
private
fCityClass: TSQLBaseRegionClass;
protected
public
published
property CityClass: TSQLBaseRegionClass read fCityClass write fCityClass;
end;
TSQLCountry = class(TSQLBaseRegion)
private
fCity: TSQLCity;
fPrimaryLanguage: TSQLLanguage;
protected
public
published
property City: TSQLCity read fCity write fCity;
property PrimaryLanguage: TSQLLanguage read fPrimaryLanguage write fPrimaryLanguage;
end;
TSQLProvince = class(TSQLBaseRegion)
private
fCountry: TSQLCountry;
fCity: TSQLCity;
protected
public
published
property Country: TSQLCountry read fCountry write fCountry;
property City: TSQLCity read fCity write fCity;
end;
TSQLRegency = class(TSQLBaseRegion)
private
fProvince: TSQLProvince;
fCity: TSQLCity;
protected
public
published
property Province: TSQLProvince read fProvince write fProvince;
property City: TSQLCity read fCity write fCity;
end;
TSQLSubDistrict = class(TSQLBaseRegion)
private
fRegency: TSQLRegency;
fCity: TSQLCity;
protected
public
published
property Regency: TSQLRegency read fRegency write fRegency;
property City: TSQLCity read fCity write fCity;
end;
TSQLVillage = class(TSQLBaseRegion)
private
fSubDistrict: TSQLSubDistrict;
fCity: TSQLCity;
protected
public
published
property SubDistrict: TSQLSubDistrict read fSubDistrict write fSubDistrict;
property City: TSQLCity read fCity write fCity;
end;
TSQLHamlet = class(TSQLBaseRegion)
private
fVillage: TSQLVillage;
protected
public
published
property Village: TSQLVillage read fVillage write fVillage;
end;
TSQLAddress = class(TSQLBase)
private
fStreetLine1: RawUTF8;
fStreetLine2: RawUTF8;
fStreetLine3: RawUTF8;
fRTRW : RawUTF8;
fCountry: TSQLCountry;
fProvince: TSQLProvince;
fRegency: TSQLRegency;
fSubDistrict: TSQLSubDistrict;
fVillage: TSQLVillage;
fHamlet: TSQLHamlet;
fZipCode: RawUTF8;
protected
public
published
property StreetLine1: RawUTF8 read fStreetLine1 write fStreetLine1;
property StreetLine2: RawUTF8 read fStreetLine2 write fStreetLine2;
property StreetLine3: RawUTF8 read fStreetLine3 write fStreetLine3;
property RTRW: RawUTF8 read fRTRW write fRTRW;
property Country: TSQLCountry read fCountry write fCountry;
property Province: TSQLProvince read fProvince write fProvince;
property Regency: TSQLRegency read fRegency write fRegency;
property SubDistrict: TSQLSubDistrict read fSubDistrict write fSubDistrict;
property Village: TSQLVillage read fVillage write fVillage;
property Hamlet: TSQLHamlet read fHamlet write fHamlet;
property ZipCode: RawUTF8 read fZipCode write fZipCode;
end;
yes please, where I can send you a more complete version?
I think, SQLite3UIQuery not handle sftid type of field with a sub select query.
ADDRESS_SELECT = 'StreetLine1,StreetLine2,StreetLine3,RTRW, '+
'(SELECT Name FROM Country WHERE ID=Country) AS Country, '+
'(SELECT Name FROM Province WHERE ID=Province) AS Province, '+
'(SELECT Name FROM Regency WHERE ID=Regency) AS Regency, '+
'(SELECT Name FROM SubDistrict WHERE ID=SubDistrict) AS SubDistrict, '+
'(SELECT Name FROM Village WHERE ID=Village) AS Village ';
I also found that qoContains less accurate.
Could you check it?
many thanks.
I think you just need a line of code to do so.
dbcache.EngineExecuteAll(FormatUTF8('DELETE FROM Cache WHERE Time < %d',[lastcache]));
hopefully can help.
yes please, i need it, and thanks.
a also plan to add Browse Button, to show Browse form that containing TSQLRecordClass data related to sftID.
in this form (browse form) i plan to use facility of SQLite3UIQuery.
but with filtering (not marking) the match row.
i mean, only the matches rows will be displayed on the grid.
is it possible?
thank you.
I tried to call the form automatically, by creating an instance of TSynButton.
TSQLRecordButtonClass = class of TSQLRecordButton;
TSQLRecordButton = class(TSynButton)
private
fProp: PPropInfo;
fRecordClass: TSQLRecordClass;
fAssociateComponent: TWinControl;
protected
public
property Prop: PPropInfo read fProp write fProp;
property RecordClass: TSQLRecordClass read fRecordClass;
property AssociateComponent: TWinControl read fAssociateComponent;
constructor Create(aOwner: TComponent; P: PPropInfo; Comp: TWinControl); reintroduce;
class function CreateButton(aOwner: TComponent; P: PPropInfo;
Comp: TWinControl; RecordButtonClass: TSQLRecordButtonClass): TSQLRecordButton;
end;
TSQLRecordAddButton = class(TSQLRecordButton);
TSQLRecordEditButton = class(TSQLRecordButton);
I'm not sure, if this is a good idea or not. but so far it's working fine,
except I can not get RibbonTabParameters, because not all of RecordClass listed on the ribbon.
I'm hoping to get suggestions for a better way.
The following is a complete unit of BPBaseEditForm.
unit BPBaseEdit;
interface
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls,
ExtCtrls,
ComCtrls,
SynCommons,
SQLite3Commons,
SQLite3i18n,
SQLite3ToolBar,
SQLite3UIEdit,
SQLite3UILogin,
SQLBaseModel,
BPFrame,
ImgList,
SynTaskDialog;
type
TSQLRecordButtonClass = class of TSQLRecordButton;
TSQLRecordButton = class(TSynButton)
private
fProp: PPropInfo;
fRecordClass: TSQLRecordClass;
fAssociateComponent: TWinControl;
protected
public
property Prop: PPropInfo read fProp write fProp;
property RecordClass: TSQLRecordClass read fRecordClass;
property AssociateComponent: TWinControl read fAssociateComponent;
constructor Create(aOwner: TComponent; P: PPropInfo; Comp: TWinControl); reintroduce;
class function CreateButton(aOwner: TComponent; P: PPropInfo;
Comp: TWinControl; RecordButtonClass: TSQLRecordButtonClass): TSQLRecordButton;
end;
TSQLRecordAddButton = class(TSQLRecordButton);
TSQLRecordEditButton = class(TSQLRecordButton);
TBPBaseEditForm = class(TRecordEditForm)
pnlFrame: TPanel;
il16: TImageList;
il32: TImageList;
procedure BtnSaveClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
fModified: Boolean;
fPagerTop: TSynPager;
fTB: TSQLCustomToolBar;
fDetail: TFrameDetail;
protected
procedure CRUDActionClick(Sender: TObject);
procedure CRUDManyActionClick(Sender: TObject);
procedure DOOnChange(Sender: TObject);
procedure SetDetail(aDetail:TFrameDetail);
public
{ Public declarations }
function DOOnComponentCreate(Obj: TObject; Prop: PPropInfo; Parent: TWinControl): TWinControl;
procedure DOOnComponentCreated(Obj: TObject; Prop: PPropInfo; Comp: TWinControl);
property Modified: Boolean read fModified write fModified;
property Detail: TFrameDetail read fDetail write SetDetail;
end;
//var BPBaseEditForm: TBPBaseEditForm;
implementation
uses Contnrs;
{$R *.dfm}
{TSQLRecordButton}
constructor TSQLRecordButton.Create(aOwner: TComponent; P: PPropInfo; Comp: TWinControl);
begin
fProp:= P;
fRecordClass:= TSQLRecordClass(fProp^.Proptype^^.ClassType^.Classtype);
fAssociateComponent:= Comp;
Inherited Create(aOwner);
end;
class function TSQLRecordButton.CreateButton(aOwner: TComponent; P: PPropInfo;
Comp: TWinControl; RecordButtonClass: TSQLRecordButtonClass): TSQLRecordButton;
begin
if (aOwner = nil) or (P = nil) then
Result:= nil
else Result:= RecordButtonClass.Create(aOwner,P,Comp);
end;
{TBPBaseEditForm}
procedure TBPBaseEditForm.CRUDActionClick(Sender: TObject);
var
aRec: TSQLRecord;
BaseEditForm: TBPBaseEditForm;
aID, SetIndex: Integer;
CB: TComboBox;
IsOK: Boolean;
function CRUD(aRec: TSQLRecord): Boolean;
begin
BaseEditForm.SetRecord(Client,aRec);
Result := BaseEditForm.ShowModal= mrOk;
end;
procedure RefreshComboBox(aClient: TSQLRestClient; P: PPropInfo);
var
IDClass: TSQLRecordClass;
SourceID,OldIndex: Integer;
begin
if aClient <> nil then begin
OldIndex:= CB.ItemIndex;
IDClass := TSQLRecordClass(P^.PropType^^.ClassType^.ClassType);
SourceID := P^.GetOrdValue(Rec);
with IDClass.RecordProps do
if MainField[True] >= 0 then begin
aClient.OneFieldValues(IDClass,FieldsName[MainField[True]],'',CB.Items,@SourceID);
CB.ItemIndex:= OldIndex;
end;
end;
end;
begin
with TSQLRecordButton(Sender) do
begin
aRec:= RecordClass.Create;
CB:= TComboBox(AssociateComponent);
SetIndex:= CB.ItemIndex;
if SetIndex < 0 then
aID := 0
else aID := PtrInt(CB.Items.Objects[SetIndex]);
end;
if aRec = nil then
Exit;
BaseEditForm:= TBPBaseEditForm.Create(Application);
try
if Sender.InheritsFrom(TSQLRecordAddButton) then
while CRUD(aRec) do
try
aID:= Client.Add(aRec,True);
if aID > 0 then begin
aRec.ClearProperties;
end;
finally
Client.UnLock(aRec);
end else
if Sender.InheritsFrom(TSQLRecordEditButton) then
try
if Client.Retrieve(aID,aRec,False) then
try
IsOK:= CRUD(aRec);
if IsOK then
Client.Update(aRec);
finally
Client.UnLock(aRec);
end;
finally
end;
RefreshComboBox(Client, TSQLRecordButton(Sender).Prop);
finally
aRec.Free;
BaseEditForm.Free;
end;
end;
procedure TBPBaseEditForm.CRUDManyActionClick(Sender: TObject);
var
aRec: TSQLRecord;
aMany: TSQLRecordMany;
BaseEditForm: TBPBaseEditForm;
aID,aTag: Integer;
function CRUD(aRec: TSQLRecord): Boolean;
begin
BaseEditForm.SetRecord(Client,aRec);
Result := BaseEditForm.ShowModal= mrOk;
end;
begin
aTag:= TSynToolButton(Sender).Tag;
case aTag of
Ord(caCreate)..Ord(caUpdate):begin
BaseEditForm:= TBPBaseEditForm.Create(Application);
try
aRec:= Detail.CurrentPage.Dest;
if aRec = nil then
Exit;
aMany:= Detail.CurrentPage.Many;
if aTag = Ord(caCreate) then
while CRUD(aRec) do
try
aID:= Client.Add(aRec,True);
if aID > 0 then begin
aMany.ManyAdd(Client,Rec.ID,aID,True);
aRec.ClearProperties;
Detail.RefreshCurrentPage;
end;
finally
Client.UnLock(aRec);
end else
if aTag = Ord(caUpdate) then
try
finally
end;
finally
end;
end;
end;
end;
procedure TBPBaseEditForm.DOOnChange(Sender: TObject);
begin
Modified:= True;
end;
procedure TBPBaseEditForm.SetDetail(aDetail: TFrameDetail);
begin
if aDetail <> nil then
fDetail:= aDetail
else
fDetail:= TFrameDetail.Create(Self,Client,Rec);
end;
function TBPBaseEditForm.DOOnComponentCreate(Obj: TObject; Prop: PPropInfo; Parent: TWinControl): TWinControl;
var
SQLFieldType: TSQLFieldType;
P: PPropInfo;
begin
Result:= nil;
P:= Prop;
SQLFieldType:= P^.PropType^^.SQLFieldType;
case SQLFieldType of
sftMany: begin
Result := TComboBox.Create(Parent);
end;
end;
end;
procedure TBPBaseEditForm.DOOnComponentCreated(Obj: TObject; Prop: PPropInfo; Comp: TWinControl);
const
W = 50;
var
P: PPropInfo;
SQLFieldType: TSQLFieldType;
L: Integer;
begin
P:= Prop;
SQLFieldType:= P^.PropType^^.SQLFieldType;
case SQLFieldType of
sftID: begin
with TSQLRecordButton.CreateButton(Comp.Parent,Prop,Comp,TSQLRecordAddButton) do begin
Tag:= 0;
Parent := Comp.Parent;
L:= Comp.Left + Comp.Width + 1;
SetBounds(L,Comp.Top - 1,W,Comp.Height + 2);
Caption := 'Add';
OnClick := CRUDActionClick;
SetBitmap(BitmapArrow);
Anchors := [akLeft, akTop];
end;
with TSQLRecordButton.CreateButton(Comp.Parent,Prop,Comp,TSQLRecordEditButton) do begin
Tag:= 1;
Parent := Comp.Parent;
L:= L + W + 1;
SetBounds(L,Comp.Top - 1,W,Comp.Height + 2);
Caption := 'Edit';
OnClick := CRUDActionClick;
SetBitmap(BitmapArrow);
Anchors := [akLeft, akTop];
end;
end;
end;
if Comp.InheritsFrom(TLabeledEdit) then begin
if P^.Name = 'Name' then
Comp.Width:= Comp.Width + 100;
TLabeledEdit(Comp).OnChange:= DOOnChange;
end else
if Comp is TDateTimePicker then begin
TDateTimePicker(Comp).OnChange:= DOOnChange;
end else
if Comp is TComboBox then begin
TComboBox(Comp).OnChange:= DOOnChange;
end;
end;
procedure TBPBaseEditForm.BtnSaveClick(Sender: TObject);
begin
Modified:= False;
inherited BtnSaveClick(Sender);
end;
resourcestring
sSave= 'Save Changes ?';
procedure TBPBaseEditForm.FormClose(Sender: TObject;
var Action: TCloseAction);
var
aAnswer: Integer;
begin
inherited;
if Modified then begin
aAnswer:= MessageDlg(sSave,mtConfirmation,mbYesNoCancel,0);
case aAnswer of
mrYes: BtnSaveClick(Sender);
mrNo:;
mrCancel:Action:= caNone;
end;
end;
end;
procedure TBPBaseEditForm.FormCreate(Sender: TObject);
begin
inherited;
// OnComponentCreate:= DOOnComponentCreate;
OnComponentCreated:= DOOnComponentCreated;
BottomPanel.BevelOuter:= bvNone;
BottomPanel.Height:= 40;
BtnSave.SetBounds(BtnSave.Parent.Width - 220,5,100,27);
BtnCancel.SetBounds(BtnSave.Left + BtnSave.Width,5,100,27);
BtnSave.OnClick:= BtnSaveClick;
end;
[b]
procedure TBPBaseEditForm.FormShow(Sender: TObject);
begin
with Rec.RecordProps do
if Pointer(ManyFields) <> nil then try
Detail:= TFrameDetail.Create(pnlFrame,Client,Rec);
Detail.Parent:= pnlFrame;
fPagerTop:= TSynPager.Create(Detail);
fPagerTop.Parent:= Detail;
fPagerTop.Align:= alTop;
fPagerTop.Height:= 40;
fTB.Init(fPagerTop,TypeInfo(TCRUDAction),CRUDManyActionClick,nil,'');
fTB.AddToolBar('');
fTB.Toolbars[0].Align:= alClient;
except
end;
pnlFrame.Visible:= Detail <> nil;
if pnlFrame.Visible then begin
ClientHeight:= ClientHeight + pnlFrame.Height;
end;
SetStyle(Self);
inherited;
end;
[/b]
procedure TBPBaseEditForm.FormDestroy(Sender: TObject);
begin
if fPagerTop <> nil then
fPagerTop.Free;
if fDetail <> nil then
fDetail.Free;
inherited;
end;
end.
I also tried to handle sftMany SQLFieldType.
please note the FormShow () and CRUDManyActionClick ().
It also works pretty well, but I'm still not satisfied with the results.
I feel this way is not true.
The following is what I am trying to do on the unit FrameDetai
unit BPFrame;
interface
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
ComCtrls,
Forms,
Dialogs,
SynCommons,
SQLite3Commons,
SQLite3UI,
SQLite3ToolBar,
SQLite3UILogin,
{$IFDEF USENEXTPACK}
NxColumnClasses,
NxColumns,
NxScrollControl,
NxCustomGridControl,
NxCustomGrid,
NxGrid,
{$ELSE}
Grids,
{$ENDIF}
ExtCtrls;
type
TPagerMany= class;
TPageMany= class(TSynPage)
private
fDest: TSQLRecord;
fMany: TSQLRecordMany;
fTable: TSQLTable;
{$IFDEF USENEXTPACK}
fGrid: TNextGrid;
{$ELSE}
fTableToGrid: TSQLTableToGrid;
fGrid: TDrawGrid;
{$ENDIF}
fSourceCSVFieldNames: PUTF8Char;
fDestCSVFieldNames: PUTF8Char;
protected
function CreateGrid:{$IFDEF USENEXTPACK}TNextGrid{$ELSE}TDrawGrid{$ENDIF};
public
class function CreatePageMany(aPager: TPagerMany; aMany: TSQLRecordMany;
SourceCSVFieldNames: PUTF8Char=nil; DestCSVFieldNames: PUTF8Char=nil): TPageMany;
property Dest: TSQLRecord read fDest write fDest;
property Many: TSQLRecordMany read fMany;
property Table: TSQLTable read fTable write fTable;
property SourceCSVFieldNames: PUTF8Char read fSourceCSVFieldNames;
property DestCSVFieldNames: PUTF8Char read fDestCSVFieldNames;
{$IFDEF USENEXTPACK}
property Grid: TNextGrid read fGrid write fGrid;
{$ELSE}
property TableToGrid: TSQLTableToGrid read fTableToGrid write fTableToGrid;
property Grid: TDrawGrid read fGrid write fGrid;
{$ENDIF}
destructor Destroy; override;
end;
TPagerMany= class(TSynPager)
private
fClient: TSQLRestClient;
fSource: TSQLRecord;
function GetActivePageIndex: integer;
procedure SetActivePageIndex(const Value: integer);
protected
procedure Change; override;
function GetPageMany(aIndex: integer): TPageMany; {$ifdef HASINLINE}inline;{$endif}
function GetSQLMany(aIndex: integer): TSQLRecordMany; {$ifdef HASINLINE}inline;{$endif}
public
class function CreatePagerMany(aOwner: TComponent; aClient: TSQLRestClient; aSource: TSQLRecord): TPagerMany;
/// add a page instance
function AddPage(aPage: TPageMany): integer; overload;
/// create a new page with the specified caption
function AddPage: integer; overload;
/// mimic TTabSheet.Pages property
property Pages[aIndex: Integer]: TPageMany read GetPageMany;
/// force OnChange event to be triggered
property ActivePageIndex: integer read GetActivePageIndex write SetActivePageIndex;
property Client: TSQLRestClient read fClient;
property Source: TSQLRecord read fSource;
published
property OnChange;
end;
TFrameDetail = class(TFrame)
private
{ Private declarations }
fClient: TSQLRestClient;
fSource: TSQLRecord;
fCurrentPage: TPageMany;
protected
function GetActivePage: TPageMany;
procedure DoPageChange(Sender: TObject);
public
{ Public declarations }
PagerMany: TPagerMany;
property Client: TSQLRestClient read fClient;
property Source: TSQLRecord read fSource;
property CurrentPage: TPageMany read GetActivePage write fCurrentPage;
procedure RefreshCurrentPage;
constructor Create(aOwner: TComponent; aClient: TSQLRestClient; aSource: TSQLRecord); reintroduce;
destructor Destroy; override;
end;
implementation
{$R *.dfm}
{TPageMany}
function TPageMany.CreateGrid:{$IFDEF USENEXTPACK}TNextGrid{$ELSE}TDrawGrid{$ENDIF};
var
{$IFDEF USENEXTPACK}
CC: TNxColumnClass;
{$ENDIF}
C,R,aID: Integer;
S: String;
aClient: TSQLRestClient;
aSource: TSQLRecord;
FieldTableClass, IDClass: TSQLRecordClass;
aRecord: TSQLRecord;
P: PPropInfo;
NeedCreation: Boolean;
begin
with TPagerMany(Self.PageControl) do begin
aClient:= fClient;
aSource:= fSource;
end;
NeedCreation:= Self.Grid = nil;
if NeedCreation then begin
Grid:= {$IFDEF USENEXTPACK}TNextGrid.Create(Self){$ELSE}TDrawGrid.Create(Self){$ENDIF};
end;
with Grid do try
if NeedCreation then begin
Parent:= Self;
Align:= alClient;
end;
Table:= Many.DestGetJoinedTable(aClient,'',aSource.ID,jkDestFields);
if Table <> nil then try
{$IFDEF USENEXTPACK}
if NeedCreation then begin
for C := 0 to Table.FieldCount - 1 do begin
case Table.FieldType(C,nil) of
sftAnsiText,sftUTF8Text: CC:= TNxTextColumn;
sftEnumerate,sftSet: CC:= TNxCheckBoxColumn;
sftInteger: CC:= TNxIncrementColumn;
sftID: CC:= TNxComboBoxColumn;
sftDateTime,sftTimeLog,sftCreateTime,sftModTime: CC:= TNxDateColumn;
end;
with Columns.Add(CC, Table.GetCaption(0,C)) do begin
Options:= [coCanInput];
end;
end;
AppearanceOptions:= [aoBoldTextSelection,aoIndicateSortedColumn];
Options:= [goDisableColumnMoving,goFooter,goGrid,goHeader,goInplaceEditEvents,goLockFixedCols,goIndicator,goInput];
end;
ClearRows;
AddRow(Table.RowCount);
for R := 1 to Table.RowCount do
for C := 0 to Table.FieldCount - 1 do begin
case Table.ExpandAsString(R,C,aClient,S) of
sftID:
if aClient <> nil then try
FieldTableClass:= TSQLRecordClass(Table.FieldTable(C));
aRecord:= FieldTableClass.Create(aClient,StrToInt(S));
P:= FieldTableClass.RecordProps.Fields[C+1];
// S:= FieldTableClass.RecordProps.Fields[C+1].Name;
IDClass := TSQLRecordClass(P^.PropType^^.ClassType^.ClassType);
aID := P^.GetOrdValue(aRecord);
with IDClass.RecordProps do
if MainField[true]>=0 then begin
aClient.OneFieldValues(IDClass,FieldsName[MainField[True]],'',
TNxComboBoxColumn(Grid.Columns[C]).Items,@aID);
TNxComboBoxColumn(Grid.Columns[C]).Index:= aID;
if aID > 0 then
S:= TNxComboBoxColumn(Grid.Columns[C]).Items[aID];
end;
finally
aRecord.Free;
end;
end;
Cell[C,R-1].AsString:= S;
end;
{$ELSE}
RowCount:= 1;
ColCount:= 1;
TableToGrid:= TSQLTableToGrid.Create(Grid,Table,TSQLRestClientURI(aClient));
{$ENDIF};
finally
end;
finally
end;
Result:= Grid;
end;
class function TPageMany.CreatePageMany(aPager: TPagerMany; aMany: TSQLRecordMany;
SourceCSVFieldNames: PUTF8Char=nil; DestCSVFieldNames: PUTF8Char=nil): TPageMany;
var
PM: TPageMany;
DestClass: TSQLRecordClass;
begin
PM:= TPageMany.Create(aPager);
PM.Caption:= FormatUTF8('[%]',[aMany.SQLTableName]);
aPager.AddPage(PM);
PM.Name := 'P'+IntToStr(Random(GetTickCount));
PM.Tag := PtrInt(PM);
PM.fMany:= aMany;
DestClass:= PM.fMany.RecordProps.RecordManyDestClass;
PM.Dest:= DestClass.Create;
PM.PageControl := aPager;
PM.Grid:= PM.CreateGrid;
SetStyle(PM);
Result:= PM;
end;
destructor TPageMany.Destroy;
begin
fDest.Free;
fMany.Free;
fTableToGrid.Free;
fGrid.Free;
inherited Destroy;
end;
{ TPagerMany }
function TPagerMany.AddPage(aPage: TPageMany): Integer;
begin
aPage.PageControl := Self;
Result := PageCount-1;
end;
function TPagerMany.AddPage: Integer;
var aPage: TPageMany;
begin
aPage := TPageMany.Create(Self);
aPage.Parent := Self;
Result := AddPage(aPage);
end;
function TPagerMany.GetPageMany(aIndex: integer): TPageMany;
begin
result := inherited Pages[aIndex] as TPageMany;
end;
function TPagerMany.GetSQLMany(aIndex: integer): TSQLRecordMany;
begin
Result:= Pages[aIndex].Many;
end;
function TPagerMany.GetActivePageIndex: integer;
begin
Result := inherited ActivePageIndex;
end;
procedure TPagerMany.SetActivePageIndex(const Value: integer);
begin
inherited ActivePageIndex := Value;
Change;
if Assigned(OnChange) then
OnChange(Self);
end;
procedure TPagerMany.Change;
begin
inherited Change;
end;
class function TPagerMany.CreatePagerMany(aOwner: TComponent; aClient: TSQLRestClient; aSource: TSQLRecord): TPagerMany;
begin
Result:= TPagerMany.Create(aOwner);
if aOwner is TWinControl then
Result.Parent := TWinControl(aOwner);
Result.fClient:= aClient;
Result.fSource:= aSource;
Result.HotTrack := True;
Result.ControlStyle := Result.ControlStyle+[csClickEvents]; // enable OnDblClick
Result.Align := alClient;
Result.Font.Style:= Result.Font.Style + [fsBold];
Result.MultiLine:= True;
Result.TabWidth:= 75;
Result.OwnerDraw:= True;
SetStyle(Result);
end;
{TFrameDetail}
function TFrameDetail.GetActivePage: TPageMany;
begin
with PagerMany do
Result:= Pages[GetActivePageIndex];
end;
procedure TFrameDetail.DoPageChange(Sender: TObject);
begin
if not(Sender.InheritsFrom(TPageControl)) then
Exit;
CurrentPage:= GetActivePage;
CurrentPage.CreateGrid;
end;
procedure TFrameDetail.RefreshCurrentPage;
begin
CurrentPage.CreateGrid; //will do all the magiq
end;
constructor TFrameDetail.Create(aOwner: TComponent; aClient: TSQLRestClient; aSource: TSQLRecord);
var
i: Integer;
P: PPropInfo;
aMany: TSQLRecordMany;
IDClass: TSQLRecordClass;
begin
inherited Create(aOwner);
fClient:= aClient;
fSource:= aSource;
with Source.RecordProps do
if PagerMany = nil then begin
PagerMany:= TPagerMany.CreatePagerMany(Self,Client,Source);
PagerMany.OnChange:= DoPageChange;
for i := 0 to High(ManyFields) do begin
aMany := TSQLRecordManyClass(ManyFields[i]^.PropType^^.ClassType^.ClassType).Create;
TPageMany.CreatePageMany(PagerMany,aMany);
end;
end;
if aOwner is TWinControl then
Self.Parent:= TWinControl(aOwner);
Self.Align:= alClient;
SetStyle(Self);
end;
destructor TFrameDetail.Destroy;
begin
// PagerTop.Free;
// PagerMany.Free;
// fSource.Free;
// fClient.Free;
inherited Destroy;
end;
end.
I tried to use the event OnComponentCreated on RecordEditForm to create two buttons on the right control for the sftid field type.
procedure TBPBaseEditForm.DOOnComponentCreated(Obj: TObject; Prop: PPropInfo; Comp: TWinControl);
var
SQLFieldType: TSQLFieldType;
P: PPropInfo;
ButtonAdd, ButtonEdit: TSynButton;
begin
P:= Prop;
SQLFieldType:= P^.PropType^^.SQLFieldType;
case SQLFieldType of
sftID: begin
ButtonAdd := TSynButton.Create(Comp.Parent);
with ButtonAdd do begin
Parent := Comp.Parent;
SetBounds(Comp.Left + Comp.Width + 1,Comp.Top - 1,50,Comp.Height + 2);
Caption := 'Add';
// B.OnClick := BClick;
SetBitmap(BitmapArrow);
Anchors := [akLeft, akTop];
end;
ButtonEdit:= TSynButton.Create(Comp.Parent);
with ButtonEdit do begin
Parent := Comp.Parent;
SetBounds(ButtonAdd.Left + ButtonAdd.Width + 1,ButtonAdd.Top,50,ButtonAdd.Height);
Caption := 'Edit';
// B.OnClick := BClick;
SetBitmap(BitmapArrow);
Anchors := [akLeft, akTop];
end;
end;
end;
end;
but, I had trouble in adjusting the position of the buttons.
unless I move the trigger event, to the bottom.
....
fFieldComponents[i] := C;
//i move it to here
if Assigned(OnComponentCreated) then // allow component customization
OnComponentCreated(aRecord,P,C); // e.g. set C.Enabled := false
inc(Y,aHeight);
...
one more, can you add BitmapAdd and BitmapEdit to the SynTaskDialog.res?
thank you
sorry for my english, that made you confused.
i mean, from current selected row to another row.
for example:
current selected row is row 1, then immediately i double click another row quickly.
note: this AV will not occure in synfile main demo, only on my project with using RecordEditForm.
I think I found the cause that triggered the emergence of AV.
AV would happen if I do double click on "another row" in the grid with a "very fast", but it never happened if I did it with normal speed.
But if we choose the line first, then the AV will not happen even if we do a very quick double click.
There may be issues on TSQLLister.OnSelectCell ()?
now is worked.
thank you.
about vmtAutoTable, i think, i'm not using it for now.
i only use third-party grid component, but with conditional defines {$IFDEF USENEXTPACK}
i suspect the problem is that the Tab.CurrentRecord sometimes not get the right record.
...
faEdit: begin
if Tab.Retrieve(Client,Tab.List.Row,False) then
try
isOK:= CRUD(Tab.CurrentRecord,'',False);
if isOK then
if Client.Update(Tab.CurrentRecord) then
Ribbon.GotoRecord(Tab.CurrentRecord);
finally
Client.UnLock(Tab.CurrentRecord);
end;
end;
....
//CRUD
function TfrmMain.CRUD(aRec: TSQLRecord; const aTitle: string; aReadOnly: boolean): boolean;
var
BPBaseEditForm: TBPBaseEditForm;
begin
BPBaseEditForm:= TBPBaseEditForm.Create(Self);
try
BPBaseEditForm.SetRecord(Client,aRec,nil,Ribbon,'',0,'');
Result := BPBaseEditForm.ShowModal= mrOk;
finally
BPBaseEditForm.Free;
end;
end;
i'll try to step by step debuging more carefully.
ok i'll take a look the documentation again about TSQLRecordMany.
Thank you
I get AV error when calling a method TSQLRecord.ClrearProperties with sftEnumerate on property.
for the quick fix, i just add sftEnumerate to the subtraction of COPIABLE_FIELDS.
COPIABLE_FIELDS: TSQLFieldTypes =
[low(TSQLFieldType)..high(TSQLFieldType)] - [sftUnknown, sftEnumerate, sftMany];
In your normal code, you should better know the exact type of PM.
Yes, i understand.
But I think you are using a more generic functionality here, for all TSQLRecordMany.
You are right. i like control generation from the RecordEditForm.
i try to inheriting RecordEditForm, then modify it to agree with my requirement.
But, sometimes i have AV error that i can not fix.
many times debuger break at the line 15057 of the SQLite3Commons
if MainField[ReturnFirstIfNoUnique]<0 then
also at the line 13952
mov edx,[eax+vmtAutoTable]
i just doubleclick the row in the MainForm then press the Save button.
You'll have to destroy the Dest instance created as such manually;
Yes, i understand.
If you use a JOINed query, the Dest instance may be created by the framework.
i don't understand with this one. did you mean that it also need destroy by manualy?
thank you. so, now i can write something like this:
DestClass:= PM.fMany.RecordProps.RecordManyDestClass;
PM.Dest:= DestClass.Create;
sorry for the question is not so obvious.
to make no.1 and no.2 more clear, might be better if I make it directly on the form as follows:
object Form1: TForm1
Left = 192
Top = 124
Width = 870
Height = 552
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object pgc1: TPageControl
Left = 0
Top = 0
Width = 854
Height = 145
ActivePage = ts1
Align = alTop
TabOrder = 0
object ts1: TTabSheet
Caption = 'Home'
object pgc2: TPageControl
Left = 0
Top = 0
Width = 846
Height = 117
ActivePage = ts6
Align = alClient
TabOrder = 0
object ts6: TTabSheet
Caption = 'Family Card'
end
object ts23: TTabSheet
Caption = '...'
ImageIndex = 1
end
end
end
object ts2: TTabSheet
Caption = 'Regional'
ImageIndex = 1
object pgc3: TPageControl
Left = 0
Top = 0
Width = 846
Height = 117
ActivePage = ts13
Align = alClient
TabOrder = 0
object ts7: TTabSheet
Caption = 'City'
end
object ts8: TTabSheet
Caption = 'Country'
ImageIndex = 1
end
object ts9: TTabSheet
Caption = 'Province'
ImageIndex = 2
end
object ts10: TTabSheet
Caption = 'Regency'
ImageIndex = 3
end
object ts11: TTabSheet
Caption = 'Sub District'
ImageIndex = 4
end
object ts12: TTabSheet
Caption = 'Village'
ImageIndex = 5
end
object ts13: TTabSheet
Caption = 'Hamlet'
ImageIndex = 6
end
end
end
object ts3: TTabSheet
Caption = 'People'
ImageIndex = 2
object pgc4: TPageControl
Left = 0
Top = 0
Width = 846
Height = 117
ActivePage = ts22
Align = alClient
TabOrder = 0
object ts14: TTabSheet
Caption = 'Address'
end
object ts15: TTabSheet
Caption = 'Education'
ImageIndex = 1
end
object ts16: TTabSheet
Caption = 'Job'
ImageIndex = 2
end
object ts17: TTabSheet
Caption = 'People'
ImageIndex = 3
end
object ts22: TTabSheet
Caption = '...'
ImageIndex = 4
end
end
end
object ts4: TTabSheet
Caption = 'Identity'
ImageIndex = 3
object pgc5: TPageControl
Left = 0
Top = 0
Width = 846
Height = 117
ActivePage = ts21
Align = alClient
TabOrder = 0
object ts18: TTabSheet
Caption = 'SIN'
end
object ts19: TTabSheet
Caption = 'Passport'
ImageIndex = 1
end
object ts20: TTabSheet
Caption = 'KITAS'
ImageIndex = 2
end
object ts21: TTabSheet
Caption = '...'
ImageIndex = 3
end
end
end
object ts5: TTabSheet
Caption = 'Utility'
ImageIndex = 4
object pgc6: TPageControl
Left = 0
Top = 0
Width = 846
Height = 117
ActivePage = ts24
Align = alClient
TabOrder = 0
object ts24: TTabSheet
Caption = 'Audit Trail'
end
object ts25: TTabSheet
Caption = 'User Log'
ImageIndex = 1
end
object ts26: TTabSheet
Caption = 'Error Log'
ImageIndex = 2
end
object ts27: TTabSheet
Caption = '....'
ImageIndex = 3
end
end
end
end
object pgc7: TPageControl
Left = 0
Top = 145
Width = 854
Height = 369
ActivePage = ts28
Align = alClient
TabOrder = 1
object ts28: TTabSheet
Caption = 'Family Card'
object lbl2: TLabel
Left = 0
Top = 0
Width = 846
Height = 13
Align = alTop
Caption =
'If TSQLFamilyCard is Selected, i want to show User Interface thi' +
's.'
end
object pgc8: TPageControl
Left = 0
Top = 13
Width = 846
Height = 328
ActivePage = ts29
Align = alClient
TabOrder = 0
object ts29: TTabSheet
Caption = 'Family Card-1'
object pnl1: TPanel
Left = 0
Top = 0
Width = 838
Height = 73
Align = alTop
Caption = 'pnl1'
TabOrder = 0
object lbl1: TLabel
Left = 32
Top = 48
Width = 45
Height = 13
Caption = 'Patriarch:'
end
object lbledt1: TLabeledEdit
Left = 128
Top = 16
Width = 121
Height = 21
EditLabel.Width = 94
EditLabel.Height = 13
EditLabel.Caption = 'Family Card Number'
EditLabel.Transparent = True
LabelPosition = lpLeft
TabOrder = 0
end
object cbb1: TComboBox
Left = 128
Top = 40
Width = 145
Height = 21
ItemHeight = 13
TabOrder = 1
Text = 'cbb1'
end
end
object grp1: TGroupBox
Left = 0
Top = 73
Width = 838
Height = 227
Align = alClient
Caption = 'Family Member'
TabOrder = 1
object dg1: TDrawGrid
Left = 2
Top = 15
Width = 834
Height = 210
Align = alClient
TabOrder = 0
end
end
end
object ts30: TTabSheet
Caption = 'Family Card-2'
ImageIndex = 1
end
object ts31: TTabSheet
Caption = 'Family Card-3'
ImageIndex = 2
end
object ts32: TTabSheet
Caption = 'Family Card-4'
ImageIndex = 3
end
object ts33: TTabSheet
Caption = 'Family Card-5'
ImageIndex = 4
end
object ts34: TTabSheet
Caption = '...'
ImageIndex = 5
end
end
end
end
end
3. ok. i do as follow
var
TB: TSQLCustomToolBar;
begin
SynPager:= TSynPager.Create(Self);
SynPager.Parent:= pnl2;
SynPager.Align:= alClient;
TB.Init(SynPager,TypeInfo(TFileAction),nil,il32,sFileActionsHints);
TB.Page.PageControl:= SynPager;
TB.AddToolBar('Record');
thank you.
i need to know the Class of sftID SQLFieldType
this is what SetRecord() procedure does in the RecordEditForm
sftID:
if aClient<>nil then begin
// ID field (TSQLRecord descendant) is handled by a TComboBox component
// with all possible values of the corresponding TSQLRecord descendant
IDClass := TSQLRecordClass(P^.PropType^^.ClassType^.ClassType);
CB := TComboBox.Create(Scroll);
....
ok. thank you. maybe I'll use Notepad + +
I'd love to contribute, but frankly, I do not feel confident.
ok. thank you. maybe I'll use Notepad + +
I'd love to contribute, but frankly, I do not feel confident.
could you add GetSourceClass and GetDestClass to the TSQLRecordMany?
thank you.
In the project I was developing, there are many records to be displayed on the Ribbon.
So that not all records can appear on the screen (although there are navigation buttons (Prev Page and Next Page) on TSynPager).
TabGroup also not all can appear on the screen, because one group can have a lot of records.
The following fact what I need to my current project, which is associated with the Ribbon and ToolBar.
1. only associate records (TSynPage) which the group must be shown.
- Might be better if TopMostPanel replaced by TPageControl.
2. in particular TSQLRecordClass I also need to show a different behavior. Is there an easy way to override TSynBodyPager?
- for instance, I do not want to display data in a grid, but with PageControl.
3. I also need TSQLCustomToolBar can be placed on the TPanel or the other TWinControl class. But TSQLCustomToolBar.Init () does not allow it.
Thank you
What if after we call ExtractAllResources, and we've made a translation in the file *. Msg, and later we need to add or change the strings on the project we also need to be translate?
whether we should call ExtractAllResources again, then add and translate to the file *. msg?
I think this way is arduous.
is possible in the future will be made such a small program like kdlscan.exe?
Thank you.
is there any simple method to get classtype from PPropInfo? instead of using
TSQLRecordClass(P^.PropType^^.ClassType^.ClassType)
thank you.
ok. i'll try it. thank you.
hi. i solved the problem. should be
RecordEditForm.SetRecord(frmMain.Client,aRec,nil,Ribbon);
because Client variable exists in the RecordEditForm and frmMain form.
But, i have another issue with RecordEditForm.
How is the best way to implement the following scenario:
1. When RecordEditForm in mode to be Create, and everything is Ok to add a Record, I wish the form is still showing, and ready to receive new input from the user (all editor is blank).
- For that, I did it by adding a parameter CRUDAction: (caCreate, caRead, caUpdate, caDelete) on Procedure SetRecord(..)
if CRUDAction = caCreate then begin
if Client.Add (Rec, True)> 0 then begin
Rec.ClearProperties; //sometimes i get AV in this.
Self.Hide;
SetRecord (Client, Rec, caCreate, nil, fRibbon);
Self.Show;
end;
end else
ModalResult: = mrOK;// Update Mode (CRUDAction = caUpdate)
2. When user click the Cancel button, and if there are field(s) had changed, firstly, I want ask to user, whether the changes they made to the save or not.
- For this purpose, I've tried doing a litle test as follows:
...
sftID: begin
SetIndex if <0 then
AID: = 0 else
begin
AID: = PtrInt (CB.Items.Objects [SetIndex]);
if AID <> StrToInt (Rec.GetFieldValue (S2U (P ^. Name))) then / / this value is changed
MessageBox (0, PAnsiChar (Rec.GetFieldValue (S2U (P ^. Name))), PAnsiChar (IntToStr (AID)), 0);
end;
P ^. SetOrdValue (Rec, AID);
Include (ModifiedFields, FieldIndex);
end;
...
but, likely I need to split BtnSaveClick procedure;
I need your advice.
ok, thank you. i'll try to debug more carefully.
that is what i don't understand.
at this time
RecordEditForm.SetRecord(Client,aRec,nil,Ribbon);
debuger show me hint something like
Client=(fCache:nil;fTransactionActive:0;fTransactionCriticalSession:(DebugInfo:$1F4CD8;.............
but, in the SQLite3UIEdit
..
fRec := aRecord;
fClient := aClient; //here debuger shown hint aClient = nil.
CW := Scroll.ClientWidth;
...
no. i'd toggled breakpoint (F5) at
RecordEditForm.SetRecord(Client,aRec,nil,Ribbon);
in this breakpoint, Client not nil.
i also toggled breakpoint in the SQLite3UIEdit.pas at this line:
..
fRec := aRecord;
fClient := aClient; //here aClient is nil.
CW := Scroll.ClientWidth;
...
thank you.
ok. thank you.
thank you. but with this way the aClient is still always nil.