mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 01:29:08 +02:00
gtk2 intf: fixed mem leak OpenDialog filter list
git-svn-id: trunk@14978 -
This commit is contained in:
parent
982e77ff6a
commit
961e74cd37
@ -1,4 +1,3 @@
|
||||
{ $Id$ }
|
||||
{
|
||||
/***************************************************************************
|
||||
addtoprojectdlg.pas
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user