fixed updating Selected on TListView deletion

git-svn-id: trunk@8478 -
This commit is contained in:
mattias 2006-01-10 14:04:58 +00:00
parent 6edfc6200b
commit f9b6743de3
3 changed files with 90 additions and 50 deletions

View File

@ -775,6 +775,11 @@ type
TListHotTrackStyle = (htHandPoint, htUnderlineCold, htUnderlineHot);
TListHotTrackStyles = set of TListHotTrackStyle;
TListViewFlag = (
lffSelectedValid
);
TListViewFlags = set of TListViewFlag;
{ TCustomListView }
@ -784,11 +789,11 @@ type
FCanvas: TCanvas;
FDefaultItemHeight: integer;
FHotTrackStyles: TListHotTrackStyles;
// FIconOptions: TIconOptions;
FOwnerData: Boolean;
FListItems: TListItems;
FColumns: TListColumns;
FImages: array[TListViewImageList] of TCustomImageList;
FFlags: TListViewFlags;
FViewStyle: TViewStyle;
FSortType: TSortType;
@ -810,7 +815,6 @@ type
FOnInsert: TLVInsertEvent;
FOnSelectItem: TLVSelectItemEvent;
FProperties: TListViewProperties;
// FWorkAreas: TWorkAreas;
function GetBoundingRect: TRect;
function GetColumnFromIndex(AIndex: Integer): TListColumn;
function GetDropTarget: TListItem;
@ -831,7 +835,6 @@ type
procedure SetFocused(const AValue: TListItem);
procedure SetHotTrackStyles(const AValue: TListHotTrackStyles);
procedure SetHoverTime(const AValue: Integer);
// procedure SetIconOptions(const AValue: TIconOptions);
procedure SetImageList(const ALvilOrd: Integer; const AValue: TCustomImageList);
procedure SetItems(const AValue : TListItems);
procedure SetItemVisible(const AValue: TListItem; const APartialOK: Boolean);
@ -847,6 +850,7 @@ type
procedure Sort;
procedure UpdateScrollbars;
procedure CNNotify(var AMessage: TLMNotify); message CN_NOTIFY;
procedure InvalidateSelected;
protected
//called by TListItems
procedure ItemDeleted(const AItem: TListItem);
@ -875,7 +879,6 @@ type
property DefaultItemHeight: integer read FDefaultItemHeight write SetDefaultItemHeight;
property HideSelection: Boolean index Ord(lvpHideSelection) read GetProperty write SetProperty default True;
property HoverTime: Integer read GetHoverTime write SetHoverTime default -1;
// property IconOptions: TIconOptions read FIconOptions write SetIconOptions;
property Items: TListItems read FListItems write SetItems;
property LargeImages: TCustomImageList index Ord(lvilLarge) read GetImageList write SetImageList;
property MultiSelect: Boolean index Ord(lvpMultiselect) read GetProperty write SetProperty default False;
@ -923,7 +926,6 @@ type
property TopItem: TListItem read GetTopItem;
property ViewOrigin: TPoint read GetViewOrigin;
property VisibleRowCount: Integer read GetVisibleRowCount;
// property WorkAreas: TWorkAreas read FWorkAreas;
end;
@ -932,7 +934,6 @@ type
TListView = class(TCustomListView)
published
property Align;
// property AllocBy;
property Anchors;
property BorderSpacing;
// property BorderStyle;
@ -959,7 +960,7 @@ type
// property OwnerData;
// property OwnerDraw;
property PopupMenu;
// property ReadOnly default False;
property ReadOnly;
property RowSelect;
property ScrollBars;
property ShowColumnHeaders;

View File

@ -83,12 +83,15 @@ begin
// LVN_BEGINDRAG:
LVN_DELETEITEM: begin
Item := FListItems[nm^.iItem];
if FSelected = Item then
InvalidateSelected;
if Item = nil then Exit; //? nm^.iItem > Items.Count ?
Exclude(Item.FFlags, lifCreated);
if not (lifDestroying in Item.FFlags)
then Item.Delete;
end;
LVN_DELETEALLITEMS: begin
InvalidateSelected;
for n := FListItems.Count - 1 downto 0 do
begin
Item := FListItems[n];
@ -117,35 +120,45 @@ begin
end;
LVN_ITEMCHANGED: begin
Item := Items[nm^.iItem];
Change(Item, nm^.uChanged);
if (nm^.uChanged = LVIF_STATE)
then begin
// focus
if (nm^.uOldState and LVIS_FOCUSED) <> (nm^.uNewState and LVIS_FOCUSED)
//DebugLn('TCustomListView.CNNotify Count=',dbgs(Items.Count),' nm^.iItem=',dbgs(nm^.iItem),' destroying=',dbgs(lifDestroying in Item.FFlags));
if (lifDestroying in Item.FFlags) then begin
if Item=FFocused then
FFocused:=nil;
if Item=FSelected then
InvalidateSelected;
end else begin
Change(Item, nm^.uChanged);
if (nm^.uChanged = LVIF_STATE)
then begin
// focus state changed
if (nm^.uNewState and LVIS_FOCUSED) = 0
// focus
if (nm^.uOldState and LVIS_FOCUSED) <> (nm^.uNewState and LVIS_FOCUSED)
then begin
if FFocused = Item
then FFocused := nil;
end
else begin
FFocused := Item;
// focus state changed
if (nm^.uNewState and LVIS_FOCUSED) = 0
then begin
if FFocused = Item
then FFocused := nil;
end
else begin
FFocused := Item;
end;
end;
end;
// select
if (nm^.uOldState and LVIS_SELECTED) <> (nm^.uNewState and LVIS_SELECTED)
then begin
// select state changed
if (nm^.uNewState and LVIS_SELECTED) = 0
// select
if (nm^.uOldState and LVIS_SELECTED) <> (nm^.uNewState and LVIS_SELECTED)
then begin
if FSelected = Item
then FSelected := nil;
DoSelectItem(Item, False);
end
else begin
FSelected := Item;
DoSelectItem(Item, True);
// select state changed
if (nm^.uNewState and LVIS_SELECTED) = 0
then begin
if FSelected = Item then
InvalidateSelected;
DoSelectItem(Item, False);
end
else begin
FSelected := Item;
Include(FFlags,lffSelectedValid);
//DebugLn('TCustomListView.CNNotify FSelected=',dbgs(FSelected));
DoSelectItem(Item, True);
end;
end;
end;
end;
@ -156,6 +169,12 @@ begin
end;
end;
procedure TCustomListView.InvalidateSelected;
begin
FSelected:=nil;
Exclude(FFlags,lffSelectedValid);
end;
{------------------------------------------------------------------------------}
{ TCustomListView InitializeWnd }
{------------------------------------------------------------------------------}
@ -231,7 +250,8 @@ end;
{------------------------------------------------------------------------------}
procedure TCustomListView.ItemDeleted(const AItem: TListItem); //called by TListItems
begin
if FSelected = AItem then FSelected := nil;
//DebugLn('TCustomListView.ItemDeleted ',dbgs(AItem),' FSelected=',dbgs(FSelected));
if FSelected = AItem then InvalidateSelected;
if FFocused = AItem then FFocused := nil;
if csDestroying in Componentstate then Exit;
DoDeletion(AItem);
@ -469,11 +489,24 @@ begin
else Result := 0;
end;
{------------------------------------------------------------------------------}
{ TCustomListView GetSelection }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TCustomListView GetSelection
------------------------------------------------------------------------------}
function TCustomListView.GetSelection: TListItem;
var
i: Integer;
begin
if not (lffSelectedValid in FFlags) then begin
FSelected:=nil;
for i:=0 to Items.Count-1 do begin
if Items[i].Selected then begin
FSelected:=Items[i];
DebugLn('TCustomListView.GetSelection ',dbgs(FSelected));
break;
end;
end;
Include(FFlags,lffSelectedValid);
end;
Result := FSelected;
end;
@ -571,15 +604,19 @@ begin
TWSCustomListViewClass(WidgetSetClass).SetImageList(Self, lvil, AValue);
end;
{------------------------------------------------------------------------------}
{ TCustomListView SetSelection }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TCustomListView SetSelection
------------------------------------------------------------------------------}
procedure TCustomListView.SetSelection(const AValue: TListItem);
begin
if (AValue<>nil) and (AValue.ListView<>Self) then
raise Exception.Create('item does not belong to this listview');
if FSelected = AValue then Exit;
FSelected := AValue;
DebugLn('TCustomListView.SetSelection FSelected=',dbgs(FSelected));
if not HandleAllocated then Exit;
TWSCustomListViewClass(WidgetSetClass).ItemSetState(Self, FSelected.Index, FSelected, lisSelected, True);
TWSCustomListViewClass(WidgetSetClass).ItemSetState(Self, FSelected.Index,
FSelected, lisSelected, True);
end;
procedure TCustomListView.SetOwnerData(const AValue: Boolean);
@ -588,7 +625,8 @@ begin
FOwnerData:=AValue;
end;
procedure TCustomListView.SetProperty(const ALvpOrd: Integer; const AIsSet: Boolean);
procedure TCustomListView.SetProperty(const ALvpOrd: Integer;
const AIsSet: Boolean);
var
AProp: TListViewProperty;
begin

View File

@ -163,6 +163,7 @@ var
idx: Integer;
begin
// Don't use IndexOf, it updates the cache, which then will become invalid
//DebugLn('TListItems.ItemDestroying ',dbgs(AItem));
if (FCacheIndex <> -1)
and (FCacheItem = AItem)
then idx := FCacheIndex
@ -187,9 +188,9 @@ begin
FItems.Delete(idx);
end;
{------------------------------------------------------------------------------}
{ TListItems IndexOf }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TListItems IndexOf
------------------------------------------------------------------------------}
function TListItems.IndexOf(const AItem: TListItem): Integer;
begin
if (FCacheIndex <> -1)
@ -206,18 +207,18 @@ begin
FCacheItem := AItem;
end;
{------------------------------------------------------------------------------}
{ TListItems Insert }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TListItems Insert
------------------------------------------------------------------------------}
function TListItems.Insert(const AIndex: Integer): TListItem;
begin
Result := TListItem.Create(self);
InsertItem(Result, AIndex);
end;
{------------------------------------------------------------------------------}
{ TListItems InsertItem }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TListItems InsertItem
------------------------------------------------------------------------------}
procedure TListItems.InsertItem(AItem: TListItem; const AIndex: Integer);
begin
FItems.Insert(AIndex, AItem);