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 addtoprojectdlg.pas

View File

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

View File

@ -370,13 +370,17 @@ type
MenuItem: PGtkWidget; MenuItem: PGtkWidget;
end; end;
PFileSelFilterEntry = ^TFileSelFilterEntry; { TFileSelFilterEntry }
TFileSelFilterEntry = record
Description: PChar; TFileSelFilterEntry = class
Mask: PChar; public
FilterIndex: integer; Description: PChar;
MenuItem: PGtkWidget; Mask: PChar;
end; FilterIndex: integer;
MenuItem: PGtkWidget;
constructor Create(const ADescription, AMask: string);
destructor Destroy; override;
end;
{ Menu } { Menu }
@ -559,6 +563,25 @@ begin
AddCharsetEncoding(FCS_ISO_8859_15, 'iso8859', '15'); AddCharsetEncoding(FCS_ISO_8859_15, 'iso8859', '15');
end; 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 initialization
InternalInit; InternalInit;

View File

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

View File

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

View File

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