cxfiltercontrol.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 2,067 行 · 第 1/5 页

PAS
2,067
字号
            if AHotTrack and (Row = Condition) and (HitTest = fhtAddValue) then
              FAddButtonState := cxbsHot
            else
              FAddButtonState := cxbsNormal
  end
  else
    FAddButtonRect := EmptyRect;
end;

procedure TcxValuesViewInfo.Clear;
var
  I: Integer;
begin
  for I := 0 to FList.Count - 1 do
    Values[I].Free;
  FList.Clear;
end;

procedure TcxValuesViewInfo.GetHitTestInfo(const P: TPoint;
  var HitInfo: TcxFilterControlHitTestInfo);
var
  I: Integer;
begin
  if PtInRect(AddButtonRect, P) then
    HitInfo.HitTest := fhtAddValue
  else
    for I := 0 to Count - 1 do
      if PtInRect(Values[I].ValueRect, P) then
      begin
        HitInfo.HitTest := fhtValue;
        HitInfo.ValueIndex := I;
        break;
      end;
end;

procedure TcxValuesViewInfo.RemoveValue(AIndex: Integer);
begin
  if (AIndex < 0) or (AIndex >= FList.Count) then Exit;
  Values[AIndex].Free;
  FList.Delete(AIndex);
end;

function TcxValuesViewInfo.GetCount: Integer;
begin
  Result := FList.Count;
end;

procedure TcxValuesViewInfo.UpdateEditorStyle(AStyle: TcxCustomEditStyle;
  AHightlited, AEnabled: Boolean);
const
  ButtonTransparency: array[Boolean] of TcxEditButtonTransparency =
    (ebtHideInactive, ebtNone);
begin
  if AEnabled then
    AStyle.StyleData.FontColor := Control.FontValue.Color
  else
    AStyle.StyleData.FontColor := clBtnShadow;
  AStyle.ButtonTransparency := ButtonTransparency[AHightlited];
  if AHightlited then
    AStyle.Color := clWindow
  else
    AStyle.Color := Control.ViewInfo.Painter.ContentColor;
end;

function TcxValuesViewInfo.GetControl: TcxCustomFilterControl;
begin
  Result := Condition.Control;
end;

function TcxValuesViewInfo.GetValue(Index: Integer): TcxValueInfo;
begin
  Result := TcxValueInfo(FList[Index]);
end;

function TcxValuesViewInfo.GetWidth: Integer;
begin
  with Condition do
    case Operator of
      fcoBetween, fcoNotBetween:
        Result := Values[Count - 1].ValueRect.Right - OperatorRect.Right;
      fcoInList, fcoNotInList:
        Result := FAddButtonRect.Right - OperatorRect.Right;
      else
        if HasDisplayValues then
          Result := Values[Count - 1].ValueRect.Right - OperatorRect.Right
        else
          Result := 0;
    end;
end;

{ TcxConditionViewInfo }

constructor TcxConditionViewInfo.Create(AControl: TcxCustomFilterControl;
  AParent: TcxCustomRowViewInfo; ACriteriaItem: TcxCustomFilterCriteriaItem);
var
  I, J: Integer;
  S: string;
begin
  inherited Create(AControl, AParent, ACriteriaItem);
  FValues := TcxValuesViewInfo.Create(Self);
  if ACriteriaItem <> nil then
  begin
    FItemLink := TcxFilterCriteriaItem(ACriteriaItem).ItemLink;
    FItemIndex := GetItemIndex;
    with Control do
    begin
      if HasItems and (FItemIndex >= 0) and (FItemIndex < FilterLink.Count) then
        FItemText := FilterLink.Captions[FItemIndex]
      else
        FilterControlError(cxGetResourceString(@cxSFilterErrorBuilding));
    end;
    with TcxFilterCriteriaItem(ACriteriaItem) do
    begin
      FOperator := GetFilterControlOperator(OperatorKind, ValueIsNull(Value));
      case FOperator of
        fcoBetween, fcoNotBetween, fcoInList, fcoNotInList:
          begin
            S := DisplayValue;
            J := 1;
            for I := VarArrayLowBound(Value, 1) to VarArrayHighBound(Value, 1) do
            begin
              FValues.AddValue;
              FValues[I].Value := Value[I];
              FValues[I].ValueText := ExtractFilterDisplayValue(S, J);
            end;
          end;
        else
        begin
          FValues.AddValue;
          FValues[0].Value := Value;
          FValues[0].ValueText := DisplayValue;
        end;
      end;
    end;
    InternalInit;
  end
  else
  begin
    FItemIndex := -1;
    SetItem(-1);
  end;
end;

destructor TcxConditionViewInfo.Destroy;
begin
  FreeAndNil(FValues);
  FreeAndNil(FEditorProperties);
  FreeAndNil(ValueEditorData);
  inherited Destroy;
end;

procedure TcxConditionViewInfo.Calc(const ARowRect: TRect);
var
  ASize: TSize;
begin
  inherited Calc(ARowRect);
  with Control.Canvas do
  begin
    Font.Assign(Control.FontItem);
    ASize := TextExtent(FItemText);
    FItemRect := Bounds(ButtonRect.Right + 8, 0, ASize.cx + 2, ASize.cy + 2);
    CenterRectVert(FRowRect, FItemRect);
    Font.Assign(Control.FontCondition);
    FOperatorText := cxConditionText[Operator];
    ASize := TextExtent(FOperatorText);
    FOperatorRect := Bounds(FItemRect.Right + 8, 0, ASize.cx + 2, ASize.cy + 2);
    CenterRectVert(FRowRect, FOperatorRect);
    if HasDisplayValues then Values.Calc;
  end;
end;

procedure TcxConditionViewInfo.GetHitTestInfo(const P: TPoint;
  var HitInfo: TcxFilterControlHitTestInfo);
begin
  inherited;
  if HitInfo.HitTest = fhtNone then
    if PtInRect(FItemRect, P) then
      HitInfo.HitTest := fhtItem
    else
      if PtInRect(FOperatorRect, P) then
        HitInfo.HitTest := fhtOperator
      else
        Values.GetHitTestInfo(P, HitInfo);
end;

function TcxConditionViewInfo.GetProperties: TcxCustomEditProperties;
begin
  with Control do
  begin
    if HasItems and (ItemIndex >= 0) and (ItemIndex < FilterLink.Count) then
      Result := FilterLink.Properties[ItemIndex]
    else
      Result := GetDefaultProperties;
    if Result = nil then Result := GetDefaultProperties;
  end;
end;

function TcxConditionViewInfo.Ready: Boolean;
begin
  Result := (FItemText <> '') and (FOperatorText <> '');
end;

procedure TcxConditionViewInfo.AddValue;
begin
  Values.AddValue;
  Control.LayoutChanged;
end;

function TcxConditionViewInfo.GetWidth: Integer;
begin
  Result := inherited GetWidth + WidthOf(FItemRect) + WidthOf(FOperatorRect) +
    Values.Width + 8 * 2;
end;

function TcxConditionViewInfo.HasDisplayValues: Boolean;
begin
  Result := not (Operator in [fcoBlanks, fcoNonBlanks, fcoYesterday, fcoToday, fcoTomorrow,
    fcoLast7Days, fcoLastWeek, fcoLast14Days, fcoLastTwoWeeks, fcoLast30Days, fcoLastMonth, fcoLastYear, fcoInPast,
    fcoThisWeek, fcoThisMonth, fcoThisYear,
    fcoNext7Days, fcoNextWeek, fcoNext14Days, fcoNextTwoWeeks, fcoNext30Days, fcoNextMonth, fcoNextYear, fcoInFuture]);
end;

procedure TcxConditionViewInfo.InitValues(ASaveValue: Boolean);
begin
  if ASaveValue and HasDisplayValues then
  begin
    case Operator of
      fcoBetween, fcoNotBetween:
        begin
          while Values.Count > 2 do Values.RemoveValue(2);
          if Values.Count < 2 then Values.AddValue;
        end;
      fcoInList, fcoNotInList:;
      else
      begin
        while Values.Count > 1 do Values.RemoveValue(1);
        if Values.Count < 1 then Values.AddValue;
      end;
    end;
  end
  else
  begin
    Values.Clear;
    Values.AddValue;
    if Operator in [fcoBetween, fcoNotBetween] then Values.AddValue;
  end;
end;

procedure TcxConditionViewInfo.InternalInit;
var
  AEditClass: TcxCustomEditClass;
  AProperties: TcxCustomEditProperties;
begin
  FreeAndNil(ValueEditorData);
  FreeAndNil(FEditorProperties);
  AProperties := GetProperties;
  with Control do
  begin
    FEditorHelper := FilterEditsController.FindHelper(AProperties.ClassType);
    if FEditorHelper = nil then
      FEditorHelper := TcxFilterTextEditHelper;
    AEditClass := FEditorHelper.GetFilterEditClass;
    if AEditClass <> nil then
      FEditorProperties := AEditClass.GetPropertiesClass.Create(nil)
    else
      FEditorProperties := TcxCustomEditPropertiesClass(AProperties.ClassType).Create(nil);
    FEditorHelper.InitializeProperties(FEditorProperties, AProperties, True);
    FValueType := FilterLink.ValueTypes[FItemIndex];
    FSupportedOperators := FEditorHelper.GetSupportedFilterOperators(AProperties, FValueType, True);
  end;
  ValidateConditions;
end;

procedure TcxConditionViewInfo.SetItem(AIndex: Integer);
var
  AOperator: TcxFilterControlOperator;
  I: Integer;
  L: TStringList;
begin
  with Control, Control.FilterLink do
  begin
    if (AIndex >= 0) and (AIndex = ItemIndex) then Exit;
    if AIndex < 0 then
    begin
      AIndex := 0;
      if FSortItems then
      begin
        L := TStringList.Create;
        try
          L.BeginUpdate;
          for I := 0 to Count - 1 do
            L.AddObject(Captions[I], TObject(I));
          L.Sort;
          L.EndUpdate;
          if L.Count > 0 then AIndex := Integer(L.Objects[0]);
        finally
          L.Free;
        end;
      end;
    end;
    FItemIndex := AIndex;
    FItemLink  := ItemLinks[AIndex];
    FItemText  := Captions[AIndex];
    InternalInit;
    if fcoLike in FSupportedOperators then
      FOperator := fcoLike
    else
      for AOperator := Low(TcxFilterControlOperator) to High(TcxFilterControlOperator) do
        if AOperator in FSupportedOperators then
        begin
          FOperator := AOperator;
          break;
        end;
    InitValues(False);
    Values.Calc;
    if FValueEditor <> nil then
      FInplaceEditors.RemoveItem(FValueEditor.ActiveProperties);
  end;
end;

procedure TcxConditionViewInfo.ValidateConditions;
begin
  Control.ValidateConditions(FSupportedOperators);
end;

function TcxConditionViewInfo.GetItemIndex: Integer;
var
  I: Integer;
begin
  Result := -1;
  with Control do
    for I := 0 to FilterLink.Count - 1 do
      if FilterLink.ItemLinks[I] = FItemLink then
      begin
        Result := I;
        break;
      end;
end;

{ TcxCustomFilterControl }

constructor TcxCustomFilterControl.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  WantTabs := False;
  FCriteria := GetFilterControlCriteriaClass.Create(Self);
  FRoot := TcxGroupViewInfo.Create(Self, nil, FCriteria.Root);
  FRows := TList.Create;
  FRows.Add(FRoot);
  FViewInfo := GetViewInfoClass.Create(Self);
  CreateFonts;
  CreateInternalControls;
  CheckInplaceControlsColor;
  UpdateBoundsRect(Rect(0, 0, 300, 200));
  FFocusedInfo.Row := FRoot;
  FFocusedInfo.HitTest := fhtBoolOperator;
  FHotTrackOnUnfocused := True;
  FNullString := cxGetResourceString(@cxSFilterControlNullString);
  FShowLevelLines := True;
  cxFormatController.AddListener(Self);
  ParentColor := False;
  Color := clBtnFace;
end;

destructor TcxCustomFilterControl.Destroy;
var
  AFont: TcxFilterControlFont;
begin
  cxFormatController.RemoveListener(Self);
  EndMouseTracking(Self);
  DestroyInternalControls;
  FreeAndNil(FCriteria);
  FreeAndNil(FViewInfo);
  FreeAndNil(FRows);
  FreeAndNil(FRoot);
  for AFont := fcfBoolOperator to fcfValue do FreeAndNil(FFonts[AFont]);
  inherited Destroy;
end;

procedure TcxCustomFilterControl.ApplyFilter;
begin
  DoApplyFilter;
end;

procedure TcxCustomFilterControl.BeginUpdate;
begin
  Inc(FLockCount);
end;

procedure TcxCustomFilterControl.Clear;
begin
  ValueEditorHide(False);
  BeginUpdate;
  try
    ClearRows;
    FCriteria.Clear;
  finally
    EndUpdate;
  end;
end;

procedure TcxCustomFilterControl.EndUpdate;
begin
  Dec(FLockCount);
  LayoutChanged;
end;

function TcxCustomFilterControl.IsValid: Boolean;
var
  I: Integer;
begin
  Result := True;
  for I := 0 to RowCount - 1 do
    if not Rows[I].Ready then

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?