Recent

Author Topic: findcaption function  (Read 12220 times)

glober

  • Full Member
  • ***
  • Posts: 130
findcaption function
« on: April 17, 2005, 02:36:21 am »
Hello,

Is there a "findcaption" function for Tlistview in Lazarus like there is in Delphi/Kylix ?

Basicaly I want to be able scroll to a desired location in a Tlistview list.
Any Sugestions?

thankx

matthijs

  • Hero Member
  • *****
  • Posts: 537
findcaption function
« Reply #1 on: April 19, 2005, 06:01:16 pm »
This is not so hard to implement yourself. Try something like
Code: [Select]

function TListView.FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;
var
  I: Integer;
  ItemFound, EndOfList: Boolean;
begin
  Result := nil;
  if Inclusive then I := pred(StartIndex)
               else I := StartIndex;
  EndOfList := False;
  Found := False;
  repeat
    inc(I);
    if I := Items.Count then EndOfList := True;
    if not EndOfList then begin
      if Partial then begin
        ItemFound := (Pos(Value, Items[I].Caption) <> 0);
      end else begin
        ItemFound := (Value = Items[I].Caption);
      end;
    end;
  until ItemFound or EndOfList;
  if ItemFound then Result := Items[I];
end;
What's in a sig? Would my posting look less if it didnot have a sig? (Free after William S.) :)

:( Why cannot I upload my own Avatar? :(

glober

  • Full Member
  • ***
  • Posts: 130
findcaption function
« Reply #2 on: April 20, 2005, 04:32:13 am »
Quote from: "matthijs"
This is not so hard to implement yourself. Try something like
Code: [Select]

function TListView.FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;
var
  I: Integer;
  ItemFound, EndOfList: Boolean;
begin
  Result := nil;
  if Inclusive then I := pred(StartIndex)
               else I := StartIndex;
  EndOfList := False;
  Found := False;
  repeat
    inc(I);
    if I := Items.Count then EndOfList := True;
    if not EndOfList then begin
      if Partial then begin
        ItemFound := (Pos(Value, Items[I].Caption) <> 0);
      end else begin
        ItemFound := (Value = Items[I].Caption);
      end;
    end;
  until ItemFound or EndOfList;
  if ItemFound then Result := Items[I];
end;


well...uhm...Easy for you maybe. I am not as good in coding as I'd like to be.  Programming is a secondary interest to me, not a profession...well not yet anyway. There is still a lot of stuff I need to look up in Docs on regular basis, or that I'm not aware of. References for FPC or Lazarus is sadly lacking. I would dearly love to see a Master Reference for FPC or Lazarus with an Index or a Search Capability. But enough of my whining.  

When I try to implement your code and I use your exact header
Code: [Select]

function TListView.FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;

Lazarus complains with Error: method identifier expected at FindCaption,

so my question would be, How do you define the function, and have it be included as part of the TListView class

If I just define the function like:
Code: [Select]

function FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;

I get  Error: Identifier not found "Items" because you can't reference the TListview that your working with.

BTW,  It does seem like it would be fairly trivial for a developer guy to integrate your code into Lazarus. Maybe this is not desired or there are more important things for those guys to do, I don't know. Personally I think it would be an advantage to Have Lazarus be functionaly more similar to Delphi/Kylix rather than less.

matthijs

  • Hero Member
  • *****
  • Posts: 537
findcaption function
« Reply #3 on: April 20, 2005, 09:33:29 am »
At the moment I'm try-ing to realise this function in Lazarus and hope to send it to the developers as a diff file by tomorrow (got more to do :( ).
But if you want to implement it do something like this in the Interface of your unit:
Code: [Select]

type
  TmyListView = class(TListView)
  public
    function FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;
  end;

then in the implementation part of your unit write the function is posted. (You have to change the first line to read
Code: [Select]

Function TMyListView.FindCaption(StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;

When you want to use the findcaption on a listview placed on your form do
Code: [Select]

var
  aListItem: TListItem;
//...
  aListItem := TMyListView(ListView1).FindCaption(0, 'A caption', false, true, false);

This code presumes the listview on your form is called ListView1.
What's in a sig? Would my posting look less if it didnot have a sig? (Free after William S.) :)

:( Why cannot I upload my own Avatar? :(

glober

  • Full Member
  • ***
  • Posts: 130
findcaption function
« Reply #4 on: April 21, 2005, 03:05:59 am »
Implemented your suggestions and got the function working.  Just a few small problems.  In Delphi, the function only searches at the beggining of the caption, in your example it was finding any match in the whole caption field. Also the "Wrap" variable wasn't being used. Also the function is supposed to return nil, when it doesn't find a match. Without the "Try ... Except" clause I was getting an Access Violation when there was no match.  Here are my suggested changes:

Code: [Select]

function TListview.FindCaption( StartIndex: Integer; Value: string; Partial, Inclusive, Wrap: Boolean): TListItem;
var
  I: Integer;
  ItemFound, EndOfList: Boolean;
begin
  Result := nil;
  if Inclusive then I := pred(StartIndex)
               else I := StartIndex;
  EndOfList := False;
  ItemFound := False;
  try
    repeat
      if ((I = Items.Count) and (Wrap = true)) then I := 0 else inc(I);
      if ((I = Items.Count) and (Wrap = false)) then EndOfList := True else
      if ((I = pred(StartIndex)) and (Inclusive = True)) then EndOfList := True else
      if ((I = StartIndex) and (Inclusive = False)) then EndOfList := True;
      if not EndOfList then begin
        if Partial then begin
          ItemFound := (Pos(Value, Items[I].Caption) = 1); //Search only begining of caption
        end else begin
          ItemFound := (Value = Items[I].Caption);
        end;
      end;
    until ItemFound or EndOfList;
  except
    Result := nil;
  end;
  if ItemFound then Result := Items[I];
end;


Seems to work well.  Don't know if I got the Wrap and Inclusive interaction right.  Don't know if there is anything else lurking in there, Delphi wise. :)
What do you think?

BTW,  I'm kinda puzzled that your first example doesn't work.  I looked at examples on the internet, and it looks like one should be able to add a method to an existing class, without having to make up a descendant class, or mayby this only applies to classes one defines in an application, and not to ones residing in FPC or Lazarus?

Anonymous

  • Guest
findcaption function
« Reply #5 on: April 21, 2005, 09:52:25 am »
If you download latest cvs, FindCaption is implemented, including the wrap function. It is a bit different from the Delphi implementation, if partial is true it checks if the search string is part of the caption (pos(value, caption) <> 0). The first example I gave was code written without any editor or other tool, so the wrap was not implemented.

Anonymous

  • Guest
findcaption function
« Reply #6 on: April 21, 2005, 10:02:32 am »
Quote from: "glober"
BTW,  I'm kinda puzzled that your first example doesn't work.  I looked at examples on the internet, and it looks like one should be able to add a method to an existing class, without having to make up a descendant class, or mayby this only applies to classes one defines in an application, and not to ones residing in FPC or Lazarus?

You cannot add a property to an existing class without defining a descendant or redefining the whole class again. Of course you can when you have the sources. :) So what you can do is change the comctrls.pp and the implementation of it and rebuild lazarus, or download the latest cvs. :)

matthijs

  • Hero Member
  • *****
  • Posts: 537
findcaption function
« Reply #7 on: April 21, 2005, 04:11:12 pm »
Latest cvs doesnot have the implementation yet. But this is what it should be:
Code: [Select]

function TListItems.FindCaption(StartIndex: Integer; Value: string;
  Partial, Inclusive, Wrap: Boolean): TListItem;
var
  I: Integer;
  CaptionFound, AllChecked: Boolean;
begin
  result := nil;
  if (Count = 0) or (StartIndex >= Count) or (not Inclusive and (count = 1)) then Exit;
  CaptionFound := False;
  AllChecked := False;
  if Inclusive then
    I := StartIndex
  else begin
    I := succ(StartIndex);
    if I >= Count then I := 0;
  end;
  if Wrap then Wrap := (StartIndex <> 0);
  repeat
    if not AllChecked then begin
      if Partial then CaptionFound := pos(Value, Item[I].Caption) > 0
                 else CaptionFound := Value = Item[I].Caption;
    end;
    if not CaptionFound then begin
      Inc(I);
      if Wrap then begin
        if I = Count then
          I := 0
        else
          if I = StartIndex then
            AllChecked := True;
      end else begin
        if I >= Count then AllChecked := True;
      end;
    end;
  until CaptionFound or AllChecked;
  if CaptionFound then result := Item[I];
end;

as you can see it is a function of TListItems, which is called from the same function in TListView.
What's in a sig? Would my posting look less if it didnot have a sig? (Free after William S.) :)

:( Why cannot I upload my own Avatar? :(

 

TinyPortal © 2005-2018