📄 unit2.cpp
字号:
//---------------------------------------------------------------------------
//
// C++Builder Visual Component Library
// ClientDataSet Standard Reconcile Error Dialog
//
// Copyright (c) 1999 Borland International
//
//---------------------------------------------------------------------------
// To use this dialog you should add a call to HandleReconcileError in
// the OnReconcileError event handler of TClientDataSet. Cut and paste the
// following line into the event handler:
//
// Action = HandleReconcileError(Owner, DataSet, UpdateKind, E);
//
#include <stdio.h>
#include <vcl.h>
#pragma hdrstop
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
char *ActionStr[] = {"Skip", "Abort", "Merge",
"Correct", "Cancel", "Refresh"};
char *UpdateKindStr[] = {"Modified", "Inserted", "Deleted"};
char *SCaption = "Update Error - ";
char *SUnchanged = "<Unchanged>";
char *SBinary = "(Binary)";
char *SFieldName = "Field Name";
char *SOriginal = "Original Value";
char *SConflict = "Conflicting Value";
char *SValue = " Value";
char *SNoData = "<No Records>";
char *SNew = "New";
//---------------------------------------------------------------------------
TReconcileErrorForm *ReconcileErrorForm;
TFieldData *PFieldData;
//---------------------------------------------------------------------------
// Public and Private Methods
//---------------------------------------------------------------------------
TReconcileAction HandleReconcileError(TComponent* Owner, TDataSet *DataSet,
TUpdateKind UpdateKind, EReconcileError *ReconcileError) {
TReconcileAction retVal;
TReconcileErrorForm *UpdateForm;
UpdateForm = new TReconcileErrorForm (Owner, DataSet, UpdateKind, ReconcileError);
try {
if (UpdateForm->ShowModal() == mrOk) {
retVal = (TReconcileAction) (UpdateForm->ActionGroup->Items->Objects[UpdateForm->ActionGroup->ItemIndex]);
if (retVal == raCorrect)
UpdateForm->SetFieldValues(DataSet);
} else
retVal = raAbort;
} __finally {
delete UpdateForm;
}
return retVal;
}
//---------------------------------------------------------------------------
// Routine to convert a variant value into a string.
// Handles binary field types and "empty" (Unchanged) field values specially
AnsiString VarToAnsiStr (Variant &V, TFieldType DataType) {
try {
if (VarIsEmpty(V))
return SUnchanged;
else {
switch (DataType) {
case ftBytes:
case ftVarBytes:
case ftBlob:
// ftGraphic .. ftCursor
case ftGraphic:
case ftFmtMemo:
case ftParadoxOle:
case ftDBaseOle:
case ftTypedBinary:
case ftCursor:
return SBinary;
default:
return VarToStr(V);
}
}
} catch (Exception &e) {
return e.Message;
}
}
//---------------------------------------------------------------------------
__fastcall TReconcileErrorForm::TReconcileErrorForm(TComponent* Owner) :
TForm(Owner) {
FDataSet = NULL;
FDataFields = NULL;
}
//---------------------------------------------------------------------------
__fastcall TReconcileErrorForm::TReconcileErrorForm(TComponent* Owner,
TDataSet *DataSet, TUpdateKind UpdateKind, EReconcileError *Error) : TForm(Owner) {
FDataFields = NULL;
FDataSet = DataSet;
FUpdateKind = UpdateKind;
FError = Error;
}
//---------------------------------------------------------------------------
//__fastcall ~TReconcileErrorForm(TComponent* Owner) {
//}
//---------------------------------------------------------------------------
// Create a list of the data fields in the dataset, and store string values
// associated with NewValue, OldValue, and Curvalue in string variables
// to make display switching faster
void __fastcall TReconcileErrorForm::InitDataFields() {
int i;
bool HasCurValues;
TFieldData *FD;
TField *ds;
HasCurValues = false;
for(i = 0; i < FDataSet->FieldCount; i++) {
ds = FDataSet->Fields->Fields[i];
if (ds->FieldKind != fkData)
continue;
FD = new TFieldData;
try {
FD->Field = ds;
FD->Edited = false;
if (FUpdateKind != ukDelete)
FD->NewValue = VarToAnsiStr(ds->NewValue, ds->DataType);
if (!VarIsEmpty(ds->CurValue))
HasCurValues = true;
FD->CurValue = VarToAnsiStr(ds->CurValue, ds->DataType);
if (FUpdateKind != ukInsert)
FD->OldValue = VarToAnsiStr(ds->OldValue, ds->DataType);
FDataFields->Add(FD);
} catch (Exception &e) {
delete FD;
throw;
}
}
InitUpdateData (HasCurValues);
}
//---------------------------------------------------------------------------
// Initalize the column indexes and grid titles
void __fastcall TReconcileErrorForm::InitUpdateData(bool HasCurValues) {
int FColCount;
FColCount = 1;
UpdateData->ColCount = 4;
UpdateData->Cells[0][0] = SFieldName;
if (FUpdateKind != ukDelete) {
FNewColIdx = FColCount;
FColCount++;
UpdateData->Cells[FNewColIdx][0] = UpdateKindStr[FUpdateKind] + String(SValue);
} else {
FOldColIdx = FColCount;
FColCount++;
UpdateData->Cells[FOldColIdx][0] = SOriginal;
}
if (HasCurValues) {
FCurColIdx = FColCount;
FColCount++;
UpdateData->Cells[FCurColIdx][0] = SConflict;
}
if (FUpdateKind == ukModify) {
FOldColIdx = FColCount;
FColCount++;
UpdateData->Cells[FOldColIdx][0] = SOriginal;
}
UpdateData->ColCount = FColCount;
}
//---------------------------------------------------------------------------
// Update the reconcile action radio group based on the valid reconcile actions
void __fastcall TReconcileErrorForm::AddAction(TReconcileAction Action) {
ActionGroup->Items->AddObject(ActionStr[Action], (TObject *) Action);
}
void __fastcall TReconcileErrorForm::InitReconcileActions() {
AddAction(raSkip);
AddAction(raCancel);
AddAction(raCorrect);
if (FCurColIdx > 0) {
AddAction(raRefresh);
AddAction(raMerge);
}
ActionGroup->ItemIndex = 0;
}
//---------------------------------------------------------------------------
// Update the grid based on the current display options
void __fastcall TReconcileErrorForm::DisplayFieldValues(TObject *Sender) {
int i, CurRow;
TFieldData *fd;
TReconcileAction Action;
if (!Visible)
return;
Action = (TReconcileAction) ActionGroup->Items->Objects[ActionGroup->ItemIndex];
UpdateData->Col = 1;
UpdateData->Row = 1;
CurRow = 1;
UpdateData->RowCount = 2;
UpdateData->Cells[0][CurRow] = SNoData;
for (i = 1; i < UpdateData->ColCount; i++)
UpdateData->Cells[i][CurRow] = "";
for (i = 0; i < FDataFields->Count; i++) {
fd = (TFieldData *) FDataFields->Items[i];
if (ConflictsOnly->Checked && (fd->CurValue == SUnchanged))
continue;
if (ChangedOnly->Checked && (fd->NewValue == SUnchanged))
continue;
UpdateData->RowCount = CurRow + 1;
UpdateData->Cells[0][CurRow] = fd->Field->DisplayName;
if (FNewColIdx > 0) {
switch (Action) {
case raCancel, raRefresh:
UpdateData->Cells[FNewColIdx][CurRow] = SUnchanged;
break;
case raCorrect:
if (fd->Edited)
UpdateData->Cells[FNewColIdx][CurRow] = fd->EditValue;
else
UpdateData->Cells[FNewColIdx][CurRow] = fd->NewValue;
break;
default:
UpdateData->Cells[FNewColIdx][CurRow] = fd->NewValue;
}
UpdateData->Objects[FNewColIdx][CurRow] = (TObject *) FDataFields->Items[i];
}
if (FCurColIdx > 0)
UpdateData->Cells[FCurColIdx][CurRow] = fd->CurValue;
if (FOldColIdx > 0)
if (((Action == raMerge) || (Action == raRefresh)) && (fd->CurValue != SUnchanged))
UpdateData->Cells[FOldColIdx][CurRow] = fd->CurValue;
else
UpdateData->Cells[FOldColIdx][CurRow] = fd->OldValue;
CurRow++;
}
AdjustColumnWidths();
}
//---------------------------------------------------------------------------
// For fields that the user has edited, copy the changes back into the
// NewValue property of the associated field
void __fastcall TReconcileErrorForm::SetFieldValues(TDataSet *DataSet) {
int i;
TFieldData *fd;
for (i = 0; i < FDataFields->Count; i++) {
fd = (TFieldData *) FDataFields->Items[i];
if (fd->Edited)
fd->Field->NewValue = fd->EditValue;
}
}
//---------------------------------------------------------------------------
void __fastcall TReconcileErrorForm::AdjustColumnWidths() {
int NewWidth, i;
NewWidth = (UpdateData->ClientWidth - UpdateData->ColWidths[0]) /
(UpdateData->ColCount - 1);
for (i = 1; i < UpdateData->ColCount; i++)
UpdateData->ColWidths[i] = NewWidth - 1;
}
//---------------------------------------------------------------------------
// Event Handlers
//---------------------------------------------------------------------------
// Set the Edited flag in the DataField list and save the value
void __fastcall TReconcileErrorForm::UpdateDataSetEditText (TObject *Sender,
int ACol, int ARow, const AnsiString Value) {
((TFieldData *) UpdateData->Objects[ACol][ARow])->EditValue = Value;
((TFieldData *) UpdateData->Objects[ACol][ARow])->Edited = true;
}
//---------------------------------------------------------------------------
// Enable the editing in the grid if we are on the NewValue column and the
// current reconcile action is raCorrect
void __fastcall TReconcileErrorForm::UpdateDataSelectCell(TObject *Sender, int Col, int Row,
bool &CanSelect) {
TReconcileAction Action;
Action = (TReconcileAction) ActionGroup->Items->Objects[ActionGroup->ItemIndex];
if ((Col == FNewColIdx) && (Action == raCorrect))
UpdateData->Options = UpdateData->Options << goEditing;
else
UpdateData->Options = UpdateData->Options >> goEditing;
}
/*
void __fastcall TReconcileErrorForm::FormShow(TObject *Sender) {
// display value fields procedure
}
*/
//---------------------------------------------------------------------------
void __fastcall TReconcileErrorForm::FormDestroy(TObject *Sender) {
int i;
if (FDataFields != NULL) {
for (i = 0; i < FDataFields->Count; i++)
delete ((TFieldData *) FDataFields->Items[i]);
delete FDataFields;
} // if
}
//---------------------------------------------------------------------------
void __fastcall TReconcileErrorForm::FormCreate(TObject *Sender) {
if (FDataSet == NULL)
return;
FDataFields = new TList;
InitDataFields();
Caption = SCaption + FDataSet->Name;
UpdateType->Caption = UpdateKindStr[FUpdateKind];
ErrorMsg->Text = FError->Message;
if (FError->Context != "")
ErrorMsg->Lines->Add(FError->Context);
ConflictsOnly->Enabled = (FCurColIdx > 0);
ConflictsOnly->Checked = ConflictsOnly->Enabled;
ChangedOnly->Enabled = (FNewColIdx > 0);
InitReconcileActions();
UpdateData->DefaultRowHeight = UpdateData->Canvas->TextHeight("SQgjp") + 7; // do not localize
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -