Solved

Search and Replace Component Property

Posted on 2002-06-25
13
341 Views
Last Modified: 2013-11-23
Dear Experts

I've write a delphi application about 2 years, using a lot of TQuery and now I want to change width of table field, in example 10 to 30.

How can I replace all TQuery field property to match the new database field width ?

Is there any tools available ? i try to use GEReplace, it's very nice tools, but it can't solve my problem.

Best Regards
Adeng
0
Comment
Question by:adeng
  • 5
  • 3
  • 3
  • +2
13 Comments
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7108197
well notepad would be a great tool for this :)
ofcourse if you have your forms in Text format not in Binary

the form as text looks like :

object Form1: TForm1
  Left = 192
  Top = 107
  Width = 870
  Height = 600
  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 Query1: TQuery
    Left = 160
    Top = 88
    object Query1xxx: TStringField
      FieldName = 'xxx'
      Size = 10
    end
  end
end


so what you do is simply find all of the TStringField entries and replace the Size value
you could create an app to do this for you but this method is also fast :)
0
 
LVL 1

Author Comment

by:adeng
ID: 7109493
ya I agree with you, but the problem is *.dfm in binary format, and there's about 200 dfm file. It take alot of time to do it manually.

I can't use simple search and replace procedure, like search Size = 10 and replace it to Size = 35, because there's alot of posilibity other table field that has size 10.

I need tools, to search more than 1 line of code like :
  FieldName = 'xxx'
  Size = 10

and replace it to :
  FieldName = 'xxx'
  Size = 35

So only 'xxx' field will changed.

btw, thanks.

Regards
Adeng
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7109832
You can use regular expressions in search/replace.
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7109973
What version of Delphi are you using?
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 50 total points
ID: 7110062
that's what I meant, and also wrote :)
> search for all the TStringField and replace the Size value <


another option would be to make an expert
in the expert you simply do:
for I:=0 to ComponentCount-1 do
  if Components[I] is TStringField then
    TStringField(Components[I]).Size:=30;

for help on experts check out GExperts @ www.gexperts.org
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7110091
> that's what I meant, and also wrote :)
What are you referring to?

> another option would be to make an expert
I'm writing the expert, I'll post it here when it's ready.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7110261
that's what I meant, and also wrote :) ->
> search for all the TStringField and replace the Size value <

the line above in qwazy comments :)



about the expert
will it have settings like :

Component Type: TComponent descendant;
Range: All comps, Selected comps;
Property: the PropertyName;
Value: NewValue for the property;

I wanted to write it myself but no time for it :)
0
 
LVL 8

Assisted Solution

by:TOndrej
TOndrej earned 50 total points
ID: 7110344
It has an input dialog where you can specify:

component class (exact or including descendants)
property names and values to match
target property name
target property value

It will enumerate all modules in the active project, changing the matching components.

I don't see much sense in having a "Selected comps" option since you can already do that with the Object Inspector (and you can only select components on one form at a time).

Here's the code, although not thoroughly tested. Delphi 6 required; sorry, I don't keep earlier versions anymore.

PropChangeWizard.pas:

unit PropChangeWizard;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, ValEdit;

type
  TFormPropChange = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ComboBox1: TComboBox;
    Label1: TLabel;
    Label2: TLabel;
    ComboBox2: TComboBox;
    CheckBox1: TCheckBox;
    ValueListEditor1: TValueListEditor;
    Label3: TLabel;
    Label4: TLabel;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure ComboBox2Change(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure ValueListEditor1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
    procedure Edit1Change(Sender: TObject);
  private
    procedure ValidateInput;
  public
  end;

procedure Register;

implementation

uses
  ToolsAPI, TypInfo;

{$R *.dfm}

function ShowPropChangeDlg(var AClassName, APropName, AValue: string; var IncludeDescendants: Boolean;
  SearchProps: TStrings): TModalResult;
begin
  with TFormPropChange.Create(nil) do
    try
      Result := ShowModal;
      if Result = mrOK then
      begin
        AClassName := ComboBox1.Text;
        APropName := ComboBox2.Text;
        AValue := Edit1.Text;
        IncludeDescendants := CheckBox1.Checked;
        SearchProps.Text := ValueListEditor1.Strings.Text;
      end;
    finally
      Free;
    end;
end;

type
  TPropertyChangeWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
  private
    FFormName: string;
    FMatches: TStringList;

    { IOTAWizard }
    function GetIDString: string;
    function GetName: string;
    function GetState: TWizardState;
    procedure Execute;
    { IOTAMenuWizard }
    function GetMenuText: string;

    function ChangeProperty(Component: IOTAComponent; const AClassName, APropName, AValue: string;
      IncludeDescendants: Boolean; SearchProps: TStrings): Boolean;
    function FindActiveProject: IOTAProject;
  public
    constructor Create;
    destructor Destroy; override;
  end;

function TPropertyChangeWizard.GetIDString: string;
begin
  Result := 'TOndrej.PropertyChange';
end;

function TPropertyChangeWizard.GetName: string;
begin
  Result := 'Property Change Wizard';
end;

function TPropertyChangeWizard.GetState: TWizardState;
begin
  Result := [wsEnabled];
end;

procedure TPropertyChangeWizard.Execute;
var
  AClassName, APropName, AValue: string;
  IncludeDescendants: Boolean;
  SearchProps: TStringList;
  I, J: Integer;
  Project: IOTAProject;
  Module: IOTAModule;
  FormEditor: IOTAFormEditor;
  Root: IOTAComponent;
begin
  FMatches.Clear;
  SearchProps := TStringList.Create;
  try
    if ShowPropChangeDlg(AClassName, APropName, AValue, IncludeDescendants, SearchProps) = mrOK then
    begin
      Project := FindActiveProject;
      if not Assigned(Project) then
        Exit;

      for I := 0 to Project.GetModuleCount - 1 do
      begin
        with Project.GetModule(I) do
        begin
          FFormName := FormName;
          if FormName = '' then
            Module := nil
          else
            Module := OpenModule;
          if Assigned(Module) then
          begin
            FormEditor := nil;
            for J := 0 to Module.ModuleFileCount - 1 do
              if Supports(Module.ModuleFileEditors[J], IOTAFormEditor, FormEditor) then
              begin
                Root := FormEditor.GetRootComponent;
                FormEditor := nil;
                if ChangeProperty(Root, AClassName, APropName, AValue, IncludeDescendants, SearchProps) then
                  Module.MarkModified;
                Root := nil;

                Break;
              end;
          end;
          Module := nil;
          FFormName := '';
        end;
      end;

      if FMatches.Count > 0 then
        ShowMessage('Affected component(s):'#13#10#13#10 + FMatches.Text);
    end;
  finally
    SearchProps.Free;
  end;
end;

function TPropertyChangeWizard.GetMenuText: string;
begin
  Result := 'Change properties';
end;

function TPropertyChangeWizard.ChangeProperty(Component: IOTAComponent; const AClassName, APropName, AValue: string;
  IncludeDescendants: Boolean; SearchProps: TStrings): Boolean;
var
  I: Integer;
  C1, C2: TPersistentClass;
  Instance: TComponent;
  PropInfo: PPropInfo;
  Match: Boolean;
begin
  Result := False;
  if not Assigned(Component) then
    Exit;

  Instance := TComponent(Component.GetComponentHandle);
  C1 := GetClass(AClassName);
  C2 := TPersistentClass(Instance.ClassType);
  if not Assigned(C1) or not Assigned(C2) then
    Exit;
  if (C1 = C2) or (IncludeDescendants and C2.InheritsFrom(C1)) then
  begin
    Match := True;
    for I := 0 to SearchProps.Count - 1 do
      if SearchProps.Names[I] <> '' then
      begin
        PropInfo := GetPropInfo(C2, SearchProps.Names[I]);
        if not Assigned(PropInfo) then
        begin
          Match := False;
          Break;
        end;
        with SearchProps do
          if GetPropValue(Instance, Names[I], True) <> Values[Names[I]] then
          begin
            Match := False;
            Break;
          end;
      end;
    if Match then
    begin
      PropInfo := GetPropInfo(C2, APropName);
      if Assigned(PropInfo) then
      begin
        SetPropValue(Instance, APropName, AValue);
        FMatches.Add(Format('%s.%s [%s]', [FFormName, Instance.GetNamePath, Instance.ClassName]));
        Result := True;
      end;
    end;
  end;
  for I := 0 to Component.GetComponentCount - 1 do
    Result := Result or ChangeProperty(Component.GetComponent(I), AClassName, APropName, AValue, IncludeDescendants,
      SearchProps);
end;

function TPropertyChangeWizard.FindActiveProject: IOTAProject;
var
  ProjectGroup: IOTAProjectGroup;
  I: Integer;
begin
  Result := nil;
  ProjectGroup := nil;
  with BorlandIDEServices as IOTAModuleServices do
    for I := 0 to ModuleCount - 1 do
      if Supports(Modules[I], IOTAProjectGroup, ProjectGroup) then
        Break;
  if Assigned(ProjectGroup) then
    Result := ProjectGroup.ActiveProject
  else
  begin
    Result := nil;
    with BorlandIDEServices as IOTAModuleServices do
      for I := 0 to ModuleCount - 1 do
        if Supports(Modules[I], IOTAProject, Result) then
          Break;
  end;
end;

constructor TPropertyChangeWizard.Create;
begin
  inherited Create;
  FMatches := TStringList.Create;
end;

destructor TPropertyChangeWizard.Destroy;
begin
  FMatches.Free;
  inherited Destroy;
end;

procedure TFormPropChange.ValidateInput;
var
  C: TPersistentClass;
begin
  C := GetClass(ComboBox1.Text);
  Button1.Enabled := Assigned(C) and (Assigned(GetPropInfo(C, ComboBox2.Text)) or CheckBox1.Checked);
end;

procedure TFormPropChange.FormCreate(Sender: TObject);
var
  I, J: Integer;
begin
  with Constraints do
  begin
    MinHeight := Height;
    MinWidth := Width;
  end;
  with BorlandIDEServices as IOTAPackageServices do
    for I := 0 to PackageCount - 1 do
      for J := 0 to ComponentCount[I] - 1 do
        ComboBox1.Items.Add(ComponentNames[I, J]);
end;

procedure TFormPropChange.ComboBox1Change(Sender: TObject);
var
  C: TPersistentClass;
  PropList: PPropList;
  I: Integer;
begin
  with ComboBox2 do
  begin
    Items.BeginUpdate;
    try
      Clear;
      with Sender as TComboBox do
        C := GetClass(Text);
      if Assigned(C) then
        for I := 0 to GetPropList(C.ClassInfo, PropList) - 1 do
          Items.Add(PropList^[I]^.Name);
    finally
      Items.EndUpdate;
    end;
  end;
  ValidateInput;
end;

procedure TFormPropChange.ComboBox2Change(Sender: TObject);
begin
  ValidateInput;
end;

procedure TFormPropChange.CheckBox1Click(Sender: TObject);
begin
  ValidateInput;
end;

procedure TFormPropChange.ValueListEditor1SetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
begin
  ValidateInput;
end;

procedure TFormPropChange.Edit1Change(Sender: TObject);
begin
  ValidateInput;
end;

procedure Register;
begin
  RegisterPackageWizard(TPropertyChangeWizard.Create);
end;

end.

PropChangeWizard.dfm:

object FormPropChange: TFormPropChange
  Left = 262
  Top = 107
  Width = 333
  Height = 308
  Caption = 'Change properties'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poDesktopCenter
  OnCreate = FormCreate
  DesignSize = (
    325
    281)
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 8
    Top = 8
    Width = 29
    Height = 13
    Caption = '&Class:'
    FocusControl = Button1
  end
  object Label2: TLabel
    Left = 8
    Top = 184
    Width = 86
    Height = 13
    Anchors = [akLeft, akBottom]
    Caption = 'Change &Property:'
    FocusControl = ComboBox2
  end
  object Label3: TLabel
    Left = 8
    Top = 56
    Width = 120
    Height = 13
    Caption = '&Search conditions (AND):'
    FocusControl = ValueListEditor1
  end
  object Label4: TLabel
    Left = 160
    Top = 184
    Width = 54
    Height = 13
    Anchors = [akLeft, akBottom]
    Caption = 'New &Value:'
    FocusControl = Edit1
  end
  object Button1: TButton
    Left = 160
    Top = 248
    Width = 75
    Height = 25
    Anchors = [akRight, akBottom]
    Caption = 'OK'
    Enabled = False
    ModalResult = 1
    TabOrder = 5
  end
  object Button2: TButton
    Left = 240
    Top = 248
    Width = 75
    Height = 25
    Anchors = [akRight, akBottom]
    Cancel = True
    Caption = 'Cancel'
    ModalResult = 2
    TabOrder = 6
  end
  object ComboBox1: TComboBox
    Left = 8
    Top = 24
    Width = 145
    Height = 21
    ItemHeight = 13
    Sorted = True
    TabOrder = 0
    OnChange = ComboBox1Change
  end
  object ComboBox2: TComboBox
    Left = 8
    Top = 200
    Width = 145
    Height = 21
    Anchors = [akLeft, akBottom]
    ItemHeight = 13
    Sorted = True
    TabOrder = 3
    OnChange = ComboBox2Change
  end
  object CheckBox1: TCheckBox
    Left = 160
    Top = 24
    Width = 129
    Height = 17
    Caption = 'Include &Descendants'
    TabOrder = 1
    OnClick = CheckBox1Click
  end
  object ValueListEditor1: TValueListEditor
    Left = 8
    Top = 72
    Width = 306
    Height = 104
    Anchors = [akLeft, akTop, akRight, akBottom]
    KeyOptions = [keyEdit, keyAdd, keyDelete, keyUnique]
    Strings.Strings = (
      '=')
    TabOrder = 2
    TitleCaptions.Strings = (
      'Property'
      'Value')
    OnSetEditText = ValueListEditor1SetEditText
    ColWidths = (
      150
      150)
  end
  object Edit1: TEdit
    Left = 160
    Top = 200
    Width = 153
    Height = 21
    Anchors = [akLeft, akBottom]
    TabOrder = 4
    OnChange = Edit1Change
  end
end

Installation:
Create a new designtime-only package, add this unit, add designide.dcp to the requires clause, compile and install the package.

Under 'Help' menu a new menu item 'Change properties' should appear. When you select it, a modal dialog should appear.
For your specific case, it seems you want to input the following in the dialog:

Class: TStringField
Include descendants: no (not necessary)
Search conditions: FieldName|xxx (only one condition needed)
Change Property: Size
New Value: 35

This will enumerate all modules within the currently active project and set Size property of all TStringField components whose FieldName = 'xxx' to 35.

HTH
TOndrej
0
 
LVL 1

Author Comment

by:adeng
ID: 7112698
Wow what an expert you are, give me a day to learn and create your source code.

Best Regards
Adeng
0
 
LVL 1

Author Comment

by:adeng
ID: 7112705
oops... i used Delphi 3.0 !
It will take to much time for me to convert my application to newer delphi version.

:(

Adeng
0
 
LVL 8

Expert Comment

by:TOndrej
ID: 7112829
Perhaps someone could convert the expert to Delphi 3.
IIRC, D3 used the old-style OpenTools API.
As I've said, I don't have D3 anymore; sorry.
0
 

Expert Comment

by:CleanupPing
ID: 9343162
adeng:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0
 
LVL 5

Expert Comment

by:Lukasz Lach
ID: 9453650
adeng,
No comment has been added lately (17 days), so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area for this question:

RECOMMENDATION: split points between Lee_Nover http:#7108197 and TOndrej http:#7110344

Please leave any comments here within 7 days.

-- Please DO NOT accept this comment as an answer ! --

Thanks,

anAKiN
EE Cleanup Volunteer
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now