unit U_ObjsProp; interface uses Windows, U_LNG, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, U_BaseCommon, U_BaseConstants, U_SCSComponent, ExtCtrls, RzPanel, RzButton, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxDataStorage, cxEdit, DB, cxDBData, cxGridLevel, cxClasses, cxControls, cxGridCustomView, cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid, kbmMemTable, siComp, siLngLnk, cxCheckBox, cxCurrencyEdit, cxColorComboBox, cxSpinEdit, cxDBLookupComboBox, cxMemo, cxTextEdit, RzRadChk, Buttons, cxLookAndFeels, cxLookAndFeelPainters, cxNavigator; type TOnSetPropValue = procedure (ASender, AObj: TObject; AProp: PProperty; const AOldVal: String; AChecked: Boolean) of Object; TF_ObjsProp = class(TForm) gbInterfaces: TRzGroupBox; RzGroupBox2: TRzGroupBox; btOk: TRzBitBtn; btCancel: TRzBitBtn; dsrcProps: TDataSource; mtProps: TkbmMemTable; lng_Forms: TsiLangLinked; Grid_CompData: TcxGrid; GT_PROPERTY: TcxGridDBTableView; GT_PROPERTYNAME: TcxGridDBColumn; GT_PROPERTYVALUE: TcxGridDBColumn; GT_PROPERTYIZM: TcxGridDBColumn; GT_PROPERTYTakeIntoConnect: TcxGridDBColumn; GT_PROPERTYTakeIntoJoin: TcxGridDBColumn; GT_PROPERTYDESCRIPTION: TcxGridDBColumn; GT_PROPERTYDBColumn1: TcxGridDBColumn; GT_PROPERTYSysName: TcxGridDBColumn; GL_PROPERTY: TcxGridLevel; GT_PROPERTYOn: TcxGridDBColumn; pnApplyParams: TPanel; cbApplyForAllSameType: TRzCheckBox; Timer_PostGridTableView: TTimer; btCheckAll: TSpeedButton; btUnCheckAll: TSpeedButton; procedure FormCreate(Sender: TObject); procedure RzGroupBox2Resize(Sender: TObject); procedure GT_PROPERTYVALUEGetDisplayText( Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord; var AText: String); procedure GT_PROPERTYVALUEGetProperties(Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord; var AProperties: TcxCustomEditProperties); procedure GT_PROPERTYIZMGetDisplayText(Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord; var AText: String); procedure FormDestroy(Sender: TObject); procedure GT_PROPERTYEditValueChanged(Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem); procedure Timer_PostGridTableViewTimer(Sender: TObject); procedure btCheckAllClick(Sender: TObject); procedure btUnCheckAllClick(Sender: TObject); procedure GT_PROPERTYEditChanged(Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem); procedure mtPropsAfterPost(DataSet: TDataSet); procedure GT_PROPERTYInitEdit(Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem; AEdit: TcxCustomEdit); private GForm: TForm; FObject: TObject; FOnSetPropValue: TOnSetPropValue; FModified: TStringList; FEditedItem: TcxCustomGridTableItem; procedure SetIsOnForAll(AIsOn: Boolean); public Constructor Create(AOwner: TComponent; AForm: TForm); Destructor Destroy; override; function Execute(AObject: TObject; AAllowApplyForAll: Boolean=true; AOnSetPropValue: TOnSetPropValue=nil): Boolean; end; function EditObjectProps(ASender: TForm; AObject: TObject; AAllowApplyForAll: Boolean=true; AOnSetPropValue: TOnSetPropValue=nil): Boolean; var F_ObjsProp: TF_ObjsProp; implementation Uses U_Main, Unit_DM_SCS, U_DMCommon; {$R *.dfm} { TF_ObjsProp } constructor TF_ObjsProp.Create(AOwner: TComponent; AForm: TForm); begin GForm := AForm; inherited Create(AOwner); end; destructor TF_ObjsProp.Destroy; begin inherited; end; procedure TF_ObjsProp.SetIsOnForAll(AIsOn: Boolean); var //StrBookMark: String; StrBookMark: TBookMark; begin //StrBookMark := mtProps.Bookmark; // StrBookMark := mtProps.GetBookmark; mtProps.DisableControls; try mtProps.First; while Not mtProps.Eof do begin mtProps.Edit; mtProps.FieldByName(fnIsOn).AsBoolean := AIsOn; mtProps.Post; mtProps.Next; end; finally mtProps.EnableControls; end; end; function TF_ObjsProp.Execute(AObject: TObject; AAllowApplyForAll: Boolean=true; AOnSetPropValue: TOnSetPropValue=nil): Boolean; var ptrProperty: PProperty; OldProps: TStringList; SavedAfterPost: TDataSetNotifyEvent; begin Result := false; try FObject := AObject; FOnSetPropValue := AOnSetPropValue; OldProps := CreateStringListSorted; mtProps.Active := false; mtProps.Active := true; SavedAfterPost := mtProps.AfterPost; mtProps.AfterPost := nil; mtProps.DisableControls; try if AObject is TSCSComponCatalogClass then begin TF_Main(GForm).DM.FillMemTablePropFromList(mtProps, TSCSComponCatalogClass(AObject).Properties, false, true, false); end; // Запоминаем исходное свойство //fnPValueSrc mtProps.First; while Not mtProps.Eof do begin ptrProperty := PProperty(mtProps.FieldByName(fnObjectAddress).AsInteger); mtProps.Edit; mtProps.FieldByName(fnIsOn).AsBoolean := false; mtProps.FieldByName(fnPValueSrc).AsString := mtProps.FieldByName(fnPValue).AsString; if ptrProperty.Name_ <> '' then mtProps.FieldByName(fnName).AsString := ptrProperty.Name_; mtProps.Post; OldProps.Add(mtProps.FieldByName(fnSysName).AsString); mtProps.Next; end; mtProps.SortOn(fnID, []); finally mtProps.EnableControls; mtProps.AfterPost := SavedAfterPost; end; FModified.Clear; FEditedItem := nil; pnApplyParams.Visible := AAllowApplyForAll; GT_PROPERTYOn.Visible := AAllowApplyForAll; if ShowModal = mrOk then begin Result := true; mtProps.DisableControls; try mtProps.First; while Not mtProps.Eof do begin if {(mtProps.FieldByName(fnPValueSrc).AsString <> mtProps.FieldByName(fnPValue).AsString) or} mtProps.FieldByName(fnIsModified).AsBoolean or (mtProps.FieldByName(fnIsOn).AsBoolean = true) or (OldProps.IndexOf(mtProps.FieldByName(fnSysName).AsString) = -1) then begin FModified.Add(mtProps.FieldByName(fnSysName).AsString); //ptrProperty := PProperty(mtProps.FieldByName(fnObjectAddress).AsInteger); ptrProperty := nil; if AObject is TSCSComponCatalogClass then ptrProperty := TSCSComponCatalogClass(AObject).GetPropertyBySysName(mtProps.FieldByName(fnSysName).AsString); if ptrProperty <> nil then begin ptrProperty.Value := mtProps.FieldByName(fnPValue).AsString; if Assigned(AOnSetPropValue) then AOnSetPropValue(Self, AObject, ptrProperty, mtProps.FieldByName(fnPValueSrc).AsString, mtProps.FieldByName(fnIsOn).AsBoolean); end; end; mtProps.Next; end; finally mtProps.EnableControls; end; end; OldProps.Free; except on E: Exception do AddExceptionToLogExt(ClassName, 'Execute', E.Message); end; end; procedure TF_ObjsProp.RzGroupBox2Resize(Sender: TObject); begin SetMiddleControlChilds(TControl(Sender), Self); end; procedure TF_ObjsProp.GT_PROPERTYVALUEGetDisplayText( Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord; var AText: String); begin SetDisplayTextToGridTablePropValue(AText, ARecord, 7, 8, TF_Main(GForm).FUOM); end; procedure TF_ObjsProp.GT_PROPERTYVALUEGetProperties( Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord; var AProperties: TcxCustomEditProperties); begin // 05/07/2019 -- IGOR // Tolik : здесь выполнен сброс обработчика, если нужно "подсунуть" значение, иначе стандартный обработчик // получит текущее значение поля, что не есть гут. Раньше такой проблемы не было, а "ЭТО" выплыло следствие того, // что разработчики немного подшаманили новую версию DevExpress'ов ... GT_PROPERTYVALUE.OnGetDisplayText := GT_PROPERTYVALUEGetDisplayText; if ARecord.Values[7] <> null then with DMCommon do begin if (ARecord.Values[7] = dtBoolean) or (ARecord.Values[7] = dtCompStateType) or (ARecord.Values[7] = dtPlaneMaterialType) or (ARecord.Values[7] = dtRoofHipType) or (ARecord.Values[7] = dtRoofHipApexType) or (ARecord.Values[7] = dtRoofHipValleyType) or (ARecord.Values[7] = dtColor) or (ARecord.Values[7] = dtCableCanalElementType) then GT_PROPERTYVALUE.OnGetDisplayText := nil; // case ARecord.Values[7] of dtBoolean: AProperties := EditRepositoryCheckBoxItem.Properties; //dtFloat: // AProperties := EditRepositorySpinItem.Properties; //dtDate: // AProperties := EditRepositoryDateItem.Properties; dtCompStateType: AProperties := EditRepositoryLookupCompSateType.Properties; dtColor: AProperties := EditRepositoryColorComboBox.Properties; dtCableCanalElementType: AProperties := EditRepositoryLookupCableCanalElementType.Properties; //dtSectionSide: // AProperties := EditRepositoryMaskItemSectionSide.Properties; //dtStringList: // AProperties := EditRepositoryMemo.Properties; dtPlaneMaterialType: AProperties := erLookupPlaneMaterialType.Properties; dtRoofHipType: AProperties := erLookupRoofHipType.Properties; dtRoofHipApexType: AProperties := erLookupRoofHipApexType.Properties; dtRoofHipValleyType: AProperties := erLookupRoofHipValleyType.Properties; end; end; end; procedure TF_ObjsProp.GT_PROPERTYIZMGetDisplayText( Sender: TcxCustomGridTableItem; ARecord: TcxCustomGridRecord; var AText: String); begin SetDisplayTextToGridTablePropIzm(AText, ARecord, 8, TF_Main(GForm).FUOM); end; procedure TF_ObjsProp.FormCreate(Sender: TObject); begin //mtProps.LoadFromDataSet(TF_Main(GForm).DM.MemTable_Property, [mtcpoStructure]); //mtProps.CreateTableAs(TF_Main(GForm).DM.MemTable_Property, [mtcpoStructure]); //LoadFromDataSet(TF_Main(GForm).DM.MemTable_Property, [mtcpoStructure]); mtProps.FieldDefs.Assign(TF_Main(GForm).DM.MemTable_Property.FieldDefs); mtProps.FieldDefs.Add(fnPValueSrc, ftString, 255); mtProps.FieldDefs.Add(fnObjectAddress, ftInteger); mtProps.FieldDefs.Add(fnIsOn, ftBoolean); FModified := TStringList.Create; end; procedure TF_ObjsProp.FormDestroy(Sender: TObject); begin FModified.Free; end; function EditObjectProps(ASender: TForm; AObject: TObject; AAllowApplyForAll: Boolean=true; AOnSetPropValue: TOnSetPropValue=nil): Boolean; begin if F_ObjsProp = nil then F_ObjsProp := TF_ObjsProp.Create(Application, ASender); F_ObjsProp.GForm := ASender; Result := F_ObjsProp.Execute(AObject, AAllowApplyForAll, AOnSetPropValue); end; procedure TF_ObjsProp.GT_PROPERTYEditValueChanged( Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem); begin if (Sender.DataController.IsEditing) and (mtProps.State <> dsBrowse) then begin //EnableTimerWithOrder(Timer_PostGridTableView, true, true); //if FEditedItem <> GT_PROPERTYOn then Timer_PostGridTableView.Enabled := true; end; end; procedure TF_ObjsProp.Timer_PostGridTableViewTimer(Sender: TObject); var CurrPropSysName: String; CurrProp: PProperty; CurrPropOldVal: String; TempCompon: TSCSComponent; PropFromMT: TProperty; ptrProperty: PProperty; OldSysNames: TStringList; i: Integer; begin TTimer(Sender).Enabled := false; if GT_PROPERTY.DataController.IsEditing and (mtProps.State <> dsBrowse) then begin GT_PROPERTY.DataController.Post; //mtProps.Edit; //mtProps.FieldByName(fnPValue).AsFloat := FloatInUOM(mtProps.FieldByName(fnPValue).AsFloat, TF_Main(GForm).FUOM, umMetr); //mtProps.Post; //exit; if Assigned(FOnSetPropValue) then begin CurrPropSysName := mtProps.FieldByName(fnSysName).AsString; CurrPropOldVal := mtProps.FieldByName(fnPValueSrc).AsString; CurrProp := nil; OldSysNames := TStringList.Create; OldSysNames.Sorted := true; TempCompon := TSCSComponent.Create(GForm); if FObject is TSCSComponent then TempCompon.ProjectOwner := TSCSComponent(FObject).ProjectOwner; mtProps.DisableControls; try mtProps.First; while Not mtProps.Eof do begin PropFromMT := TF_Main(GForm).DM.GetPropertyFromTable(dsrcProps); ptrProperty := TempCompon.GetPropertyAsNew; ptrProperty^ := PropFromMT; mtProps.Next; OldSysNames.Add(PropFromMT.SysName); if PropFromMT.SysName = CurrPropSysName then CurrProp := ptrProperty; end; if CurrProp <> nil then begin FOnSetPropValue(Self, TempCompon, CurrProp, CurrPropOldVal, false); // Из таблицы удаляем то чего уже нету в комопненте for i := 0 to OldSysNames.Count - 1 do begin if TempCompon.GetPropertyBySysName(OldSysNames[i]) = nil then begin if mtProps.Locate(fnSysName, OldSysNames[i], []) then mtProps.Delete; end; end; // Из компонента убиваем свойства которые есть в гриде for i := TempCompon.Properties.Count - 1 downto 0 do begin ptrProperty := TempCompon.Properties[i]; if OldSysNames.IndexOf(ptrProperty^.SysName) <> -1 then TempCompon.RemovePropertyBySysName(ptrProperty^.SysName); end; // Те что остались добавляем в таблицу TF_Main(GForm).DM.FillMemTablePropFromList(mtProps, TempCompon.Properties, false, true, false); end; TempCompon.Free; mtProps.Locate(fnSysName, CurrPropSysName, []); finally mtProps.EnableControls; end; end; end; end; procedure TF_ObjsProp.btCheckAllClick(Sender: TObject); begin SetIsOnForAll(true); end; procedure TF_ObjsProp.btUnCheckAllClick(Sender: TObject); begin SetIsOnForAll(false); end; procedure TF_ObjsProp.GT_PROPERTYEditChanged( Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem); begin FEditedItem := AItem; end; procedure TF_ObjsProp.mtPropsAfterPost(DataSet: TDataSet); var SavedEvent: TDataSetNotifyEvent; begin SavedEvent := DataSet.AfterPost; try DataSet.AfterPost := nil; DataSet.Edit; DataSet.FieldByName(fnIsModified).AsBoolean := true; //02.04.2012 DataSet.FieldByName(fnPValue).AsFloat := FloatInUOM(DataSet.FieldByName(fnPValue).AsFloat, TF_Main(GForm).FUOM, umMetr); DataSet.Post; finally DataSet.AfterPost := SavedEvent; end; end; procedure TF_ObjsProp.GT_PROPERTYInitEdit(Sender: TcxCustomGridTableView; AItem: TcxCustomGridTableItem; AEdit: TcxCustomEdit); begin if AItem = GT_PROPERTYVALUE then AEdit.EditValue := GetDisplayTextInFLoatUOM(AEdit.EditValue, TF_Main(GForm).FUOM); end; end.