gtk2 intf: fixed mem leak OpenDialog filter list

git-svn-id: trunk@14978 -
This commit is contained in:
mattias 2008-04-25 22:09:23 +00:00
parent 982e77ff6a
commit 961e74cd37
7 changed files with 99 additions and 73 deletions

View File

@ -1,4 +1,3 @@
{ $Id$ }
{
/***************************************************************************
addtoprojectdlg.pas

View File

@ -3,7 +3,7 @@
{------------------------------------------------------------------------------
Function: ExtractFilterList
Params: const Filter: string; var FilterIndex: integer;
var FilterList: TStringList
var ListOfPFileSelFilterEntry: TStringList
Returns: -
Converts a Delphi file filter of the form
@ -20,7 +20,8 @@
'Pascal files (*.pp)' + '*.pp'
'Pascal files (*.lpr)' + '*.lpr'
------------------------------------------------------------------------------}
procedure ExtractFilterList(const Filter: string; out FilterList: TFPList;
procedure ExtractFilterList(const Filter: string;
out ListOfFileSelFilterEntry: TFPList;
SplitMultiMask: boolean);
var
Masks: TStringList;
@ -51,15 +52,11 @@ var
end;
procedure AddEntry(const Desc, Mask: string);
var NewFilterEntry: PFileSelFilterEntry;
var NewFilterEntry: TFileSelFilterEntry;
begin
New(NewFilterEntry);
NewFilterEntry^.Description:= StrAlloc(length(Desc)+1);
StrPCopy(NewFilterEntry^.Description, Desc);
NewFilterEntry^.Mask:= StrAlloc(length(Mask)+1);
StrPCopy(NewFilterEntry^.Mask, Mask);
NewFilterEntry^.FilterIndex:=CurFilterIndex;
FilterList.Add(NewFilterEntry);
NewFilterEntry:=TFileSelFilterEntry.Create(Desc,Mask);
NewFilterEntry.FilterIndex:=CurFilterIndex;
ListOfFileSelFilterEntry.Add(NewFilterEntry);
end;
// remove all but one masks from description string
@ -111,7 +108,7 @@ var
CurDescStart, CurDescEnd, CurMultiMaskStart, CurMultiMaskEnd: integer;
CurDesc, CurMultiMask: string;
begin
FilterList:=TFPList.Create;
ListOfFileSelFilterEntry:=TFPList.Create;
Masks:=nil;
CurFilterIndex:=0;
CurDescStart:=1;
@ -137,3 +134,12 @@ begin
Masks.Free;
end;
procedure FreeListOfFileSelFilterEntry(ListOfFileSelFilterEntry: TFPList);
var
i: Integer;
begin
if ListOfFileSelFilterEntry=nil then exit;
for i:=0 to ListOfFileSelFilterEntry.Count-1 do
TObject(ListOfFileSelFilterEntry[i]).Free;
ListOfFileSelFilterEntry.Free;
end;

View File

@ -1,5 +1,5 @@
{%MainUnit GtkInt.pp}
procedure ExtractFilterList(const Filter: string; out FilterList: TFPList;
SplitMultiMask: boolean);
procedure ExtractFilterList(const Filter: string;
out ListOfFileSelFilterEntry: TFPList; SplitMultiMask: boolean);
procedure FreeListOfFileSelFilterEntry(ListOfFileSelFilterEntry: TFPList);

View File

@ -370,13 +370,17 @@ type
MenuItem: PGtkWidget;
end;
PFileSelFilterEntry = ^TFileSelFilterEntry;
TFileSelFilterEntry = record
Description: PChar;
Mask: PChar;
FilterIndex: integer;
MenuItem: PGtkWidget;
end;
{ TFileSelFilterEntry }
TFileSelFilterEntry = class
public
Description: PChar;
Mask: PChar;
FilterIndex: integer;
MenuItem: PGtkWidget;
constructor Create(const ADescription, AMask: string);
destructor Destroy; override;
end;
{ Menu }
@ -559,6 +563,25 @@ begin
AddCharsetEncoding(FCS_ISO_8859_15, 'iso8859', '15');
end;
{ TFileSelFilterEntry }
constructor TFileSelFilterEntry.Create(const ADescription, AMask: string);
begin
Description:=StrAlloc(length(ADescription)+1);
StrPCopy(Description, ADescription);
Mask:=StrAlloc(length(AMask)+1);
StrPCopy(Mask, AMask);
end;
destructor TFileSelFilterEntry.Destroy;
begin
StrDispose(Description);
Description:=nil;
StrDispose(Mask);
Mask:=nil;
inherited Destroy;
end;
initialization
InternalInit;

View File

@ -1238,8 +1238,10 @@ var
ImageHeight: Integer;
WindowWidth, WindowHeight: integer;
DestDC: HDC;
FixedWidget: PGtkWidget;
Offset: TPoint;
{$ifdef gtk2}
FixedWidget: PGtkWidget;
{$ENDIF}
begin
if ImgList=nil then exit;
if (Index<0) or (Index>=ImgList.Count) then exit;
@ -1254,8 +1256,7 @@ begin
WindowHeight := DestWidget^.allocation.height;
Offset := Point(0, 0);
{$ifndef gtk1}
{$ifdef gtk2}
// if our widget is placed on non-window fixed then we should substract its allocation here
// since in GetDC we will get this difference in offset
FixedWidget := GetFixedWidget(DestWidget);
@ -3429,12 +3430,11 @@ var
FileSelWidget: PGtkFileSelection;
LCLHistoryMenu: PGTKWidget;
{$IFDEF Gtk1}
AFilterEntry: PFileSelFilterEntry;
AFilterEntry: TFileSelFilterEntry;
FilterList: TFPList; // list of TFileSelFilterListEntry
LCLFilterMenu: PGTKWidget;
{$ENDIF}
begin
if (ADialog=nil) or (not ADialog.HandleAllocated) then exit;
DlgWindow:=PGtkWidget(ADialog.Handle);
{$IFDEF VerboseTransient}
@ -3476,14 +3476,8 @@ begin
FilterList:=TFPList(gtk_object_get_data(PGtkObject(DlgWindow),
'LCLFilterList'));
if FilterList<>nil then begin
for i:=0 to FilterList.Count-1 do begin
AFilterEntry:=PFileSelFilterEntry(FilterList[i]);
StrDispose(AFilterEntry^.Description);
AFilterEntry^.Description:=nil;
StrDispose(AFilterEntry^.Mask);
AFilterEntry^.Mask:=nil;
Dispose(AFilterEntry);
end;
for i:=0 to FilterList.Count-1 do
TObject(FilterList[i]).Free;
FilterList.Free;
gtk_object_set_data(PGtkObject(DlgWindow),'LCLFilterList',nil);
end;

View File

@ -182,7 +182,7 @@ function gtkDialogSelectRowCB(widget: PGtkWidget; Row, Column: gInt;
var
theDialog: TCommonDialog;
MenuWidget: PGtkWidget;
AFilterEntry: PFileSelFilterEntry;
AFilterEntry: TFileSelFilterEntry;
FileSelWidget: PGtkFileSelection;
ShiftState: TShiftState;
loop : gint;
@ -203,10 +203,10 @@ begin
MenuWidget := gtk_object_get_data(PGtkObject(FileSelWidget),
'LCLFilterMenu');
if MenuWidget <> nil then begin
AFilterEntry := gtk_object_get_data(PGtkObject(
gtk_menu_get_active(PGtkMenu(MenuWidget))), 'LCLIsFilterMenuItem');
if (AFilterEntry<>nil) and (AFilterEntry^.Mask<>nil) then
PopulateFileAndDirectoryLists(FileSelWidget,AFilterEntry^.Mask);
AFilterEntry := TFileSelFilterEntry(gtk_object_get_data(PGtkObject(
gtk_menu_get_active(PGtkMenu(MenuWidget))), 'LCLIsFilterMenuItem'));
if (AFilterEntry<>nil) and (AFilterEntry.Mask<>nil) then
PopulateFileAndDirectoryLists(FileSelWidget,AFilterEntry.Mask);
end;
end
else if (bevent <> nil)
@ -349,7 +349,7 @@ var
{$IFDEF GTK1}
var
MenuWidget: PGtkWidget;
AFilterEntry: PFileSelFilterEntry;
AFilterEntry: TFileSelFilterEntry;
{$ENDIF}
begin
Result:=true;
@ -373,10 +373,10 @@ var
// populate file list
MenuWidget := gtk_object_get_data(PGtkObject(PGtkFileSelection(FPointer)), 'LCLFilterMenu');
if (MenuWidget <> nil) then begin
AFilterEntry := gtk_object_get_data(PGtkObject(gtk_menu_get_active(
PGtkMenu(MenuWidget))), 'LCLIsFilterMenuItem');
if ((AFilterEntry<>nil) and (AFilterEntry^.Mask<>nil)) then
PopulateFileAndDirectoryLists(PGtkFileSelection(FPointer), AFilterEntry^.Mask);
AFilterEntry := TFileSelFilterEntry(gtk_object_get_data(PGtkObject(gtk_menu_get_active(
PGtkMenu(MenuWidget))), 'LCLIsFilterMenuItem'));
if ((AFilterEntry<>nil) and (AFilterEntry.Mask<>nil)) then
PopulateFileAndDirectoryLists(PGtkFileSelection(FPointer), AFilterEntry.Mask);
end;
end;
// wait for correct input
@ -718,16 +718,16 @@ var
procedure CheckFilterActivated(FilterWidget: PGtkWidget);
var
AFilterEntry: PFileSelFilterEntry;
AFilterEntry: TFileSelFilterEntry;
begin
if FilterWidget=nil then exit;
AFilterEntry:=gtk_object_get_data(PGtkObject(FilterWidget),
'LCLIsFilterMenuItem');
if (AFilterEntry<>nil) and (AFilterEntry^.Mask<>nil) then
AFilterEntry:=TFileSelFilterEntry(gtk_object_get_data(PGtkObject(FilterWidget),
'LCLIsFilterMenuItem'));
if (AFilterEntry<>nil) and (AFilterEntry.Mask<>nil) then
begin
PopulateFileAndDirectoryLists(PGtkFileSelection(theDialog.Handle),
AFilterEntry^.Mask);
TFileDialog(TheDialog).IntfFileTypeChanged(AFilterEntry^.FilterIndex + 1);
AFilterEntry.Mask);
TFileDialog(TheDialog).IntfFileTypeChanged(AFilterEntry.FilterIndex + 1);
UpdateDetailView(TOpenDialog(theDialog));
end;
end;
@ -947,7 +947,8 @@ end;
Adds a Filter pulldown to a gtk file selection dialog. Returns the
inital filter mask.
------------------------------------------------------------------------------}
class function TGtkWSOpenDialog.CreateOpenDialogFilter(OpenDialog: TOpenDialog; SelWidget: PGtkWidget): string;
class function TGtkWSOpenDialog.CreateOpenDialogFilter(OpenDialog: TOpenDialog;
SelWidget: PGtkWidget): string;
var
FilterList: TFPList;
HBox, LabelWidget, FilterPullDownWidget,
@ -984,7 +985,7 @@ begin
for i:=0 to FilterList.Count-1 do begin
// create the menu items in the filter menu
MenuItemWidget:=gtk_menu_item_new_with_label(
PFileSelFilterEntry(FilterList[i])^.Description);
TFileSelFilterEntry(FilterList[i]).Description);
// connect the new MenuItem to the FilterList entry
gtk_object_set_data(PGtkObject(MenuItemWidget), 'LCLIsFilterMenuItem',
FilterList[i]);
@ -1012,14 +1013,14 @@ begin
if j<0 then j:=0;
CurMask:=0;
while (i<FilterList.Count) do begin
if PFileSelFilterEntry(FilterList[i])^.FilterIndex=j
if TFileSelFilterEntry(FilterList[i]).FilterIndex=j
then begin
CurMask:=i;
break;
end;
inc(i);
end;
Result := PFileSelFilterEntry(FilterList[CurMask])^.Mask;
Result := TFileSelFilterEntry(FilterList[CurMask]).Mask;
gtk_option_menu_set_history(GTK_OPTION_MENU(FilterPullDownWidget), CurMask);
end;
end;

View File

@ -282,7 +282,7 @@ function gtkDialogSelectRowCB(widget: PGtkWidget; Row, Column: gInt;
var
theDialog: TCommonDialog;
MenuWidget: PGtkWidget;
AFilterEntry: PFileSelFilterEntry;
AFilterEntry: TFileSelFilterEntry;
FileSelWidget: PGtkFileSelection;
ShiftState: TShiftState;
loop : gint;
@ -303,10 +303,10 @@ begin
MenuWidget := gtk_object_get_data(PGtkObject(FileSelWidget),
'LCLFilterMenu');
if MenuWidget <> nil then begin
AFilterEntry := gtk_object_get_data(PGtkObject(
gtk_menu_get_active(PGtkMenu(MenuWidget))), 'LCLIsFilterMenuItem');
if (AFilterEntry<>nil) and (AFilterEntry^.Mask<>nil) then
PopulateFileAndDirectoryLists(FileSelWidget,AFilterEntry^.Mask);
AFilterEntry := TFileSelFilterEntry(gtk_object_get_data(PGtkObject(
gtk_menu_get_active(PGtkMenu(MenuWidget))), 'LCLIsFilterMenuItem'));
if (AFilterEntry<>nil) and (AFilterEntry.Mask<>nil) then
PopulateFileAndDirectoryLists(FileSelWidget,AFilterEntry.Mask);
end;
end
else if (bevent <> nil)
@ -728,16 +728,16 @@ var
procedure CheckFilterActivated(FilterWidget: PGtkWidget);
var
AFilterEntry: PFileSelFilterEntry;
AFilterEntry: TFileSelFilterEntry;
begin
if FilterWidget=nil then exit;
AFilterEntry:=gtk_object_get_data(PGtkObject(FilterWidget),
'LCLIsFilterMenuItem');
if (AFilterEntry<>nil) and (AFilterEntry^.Mask<>nil) then
AFilterEntry:=TFileSelFilterEntry(gtk_object_get_data(PGtkObject(FilterWidget),
'LCLIsFilterMenuItem'));
if (AFilterEntry<>nil) and (AFilterEntry.Mask<>nil) then
begin
PopulateFileAndDirectoryLists(PGtkFileSelection(theDialog.Handle),
AFilterEntry^.Mask);
TFileDialog(TheDialog).IntfFileTypeChanged(AFilterEntry^.FilterIndex + 1);
AFilterEntry.Mask);
TFileDialog(TheDialog).IntfFileTypeChanged(AFilterEntry.FilterIndex + 1);
UpdateDetailView(TOpenDialog(theDialog));
end;
end;
@ -769,27 +769,29 @@ end;
class function TGtk2WSOpenDialog.CreateOpenDialogFilter(
OpenDialog: TOpenDialog; SelWidget: PGtkWidget): string;
var
FilterList: TFPList;
ListOfFileSelFilterEntry: TFPList;
i, j, k: integer;
GtkFilter: PGtkFileFilter;
MaskList: TStringList;
FilterEntry: TFileSelFilterEntry;
begin
ExtractFilterList(OpenDialog.Filter, FilterList, false);
if FilterList.Count > 0 then
ExtractFilterList(OpenDialog.Filter, ListOfFileSelFilterEntry, false);
if ListOfFileSelFilterEntry.Count > 0 then
begin
j := 1;
MaskList := TStringList.Create;
MaskList.Delimiter := ';';
for i := 0 to FilterList.Count-1 do
for i := 0 to ListOfFileSelFilterEntry.Count-1 do
begin
GtkFilter := gtk_file_filter_new();
MaskList.DelimitedText := PFileSelFilterEntry(FilterList[i])^.Mask;
FilterEntry:=TFileSelFilterEntry(ListOfFileSelFilterEntry[i]);
MaskList.DelimitedText := FilterEntry.Mask;
for k := 0 to MaskList.Count-1 do
gtk_file_filter_add_pattern(GtkFilter, PChar(MaskList.Strings[k]));
gtk_file_filter_set_name(GtkFilter, PFileSelFilterEntry(FilterList[i])^.Description);
gtk_file_filter_set_name(GtkFilter, FilterEntry.Description);
gtk_file_chooser_add_filter(SelWidget, GtkFilter);
@ -802,7 +804,8 @@ begin
MaskList.Free;
end;
gtk_object_set_data(PGtkObject(SelWidget), 'LCLFilterList', FilterList);
FreeListOfFileSelFilterEntry(ListOfFileSelFilterEntry);
//gtk_object_set_data(PGtkObject(SelWidget), 'LCLFilterList', ListOfFileSelFilterEntry);
Result := 'hm'; { Don't use '' as null return as this is used for *.* }
end;