Hi,
> [...]
> Where is the glue located ? :)
>
> grep -R -i "\$INCLUDE" * in interfaces/ doesn't find much, only two
> occurences in gtk2/gtk2int.pas ...
nevermind. It's "$I" :)
attached gtk-filedialog-new.patch, plus two new files:
filedialogutils.inc and filedialogutilsh.inc, both to put into
lcl/interfaces/gtk.
Note, those expose the Extract function public global in the gtkint.pp
module. (not that that's neccessarily bad, just noting)
gtk version is runtime checked now, since the $IFDEF HasGTK... didn't
work for me, and it's nicer that way anyways :)
cheers,
Danny
{------------------------------------------------------------------------------
Function: ExtractFilterList
Params: const Filter: string; var FilterIndex: integer;
var FilterList: TStringList
Returns: -
Converts a Delphi file filter of the form
'description1|mask1|description2|mask2|...'
into a TFPList of PFileSelFilterEntry(s).
Multi masks:
- multi masks like '*.pas;*.pp' are converted into multiple entries.
- if the masks are found in the description they are adjusted
- if the mask is not included in the description it will be concatenated
For example:
'Pascal files (*.pas;*.pp)|*.pas;*.lpr;*.pp;
is converted to three filter entries:
'Pascal files (*.pas)' + '*.pas'
'Pascal files (*.pp)' + '*.pp'
'Pascal files (*.lpr)' + '*.lpr'
------------------------------------------------------------------------------}
procedure ExtractFilterList(const Filter: string; out FilterList: TFPList;
SplitMultiMask: boolean);
var
Masks: TStringList;
CurFilterIndex: integer;
procedure ExtractMasks(const MultiMask: string);
var CurMaskStart, CurMaskEnd: integer;
s: string;
begin
if Masks=nil then
Masks:=TStringList.Create
else
Masks.Clear;
CurMaskStart:=1;
while CurMaskStart<=length(MultiMask) do begin
CurMaskEnd:=CurMaskStart;
if SplitMultiMask then begin
while (CurMaskEnd<=length(MultiMask)) and (MultiMask[CurMaskEnd]<>';')
do
inc(CurMaskEnd);
end else begin
CurMaskEnd:=length(MultiMask)+1;
end;
s:=Trim(copy(MultiMask,CurMaskStart,CurMaskEnd-CurMaskStart));
Masks.Add(s);
CurMaskStart:=CurMaskEnd+1;
end;
end;
procedure AddEntry(const Desc, Mask: string);
var NewFilterEntry: PFileSelFilterEntry;
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);
end;
// remove all but one masks from description string
function RemoveOtherMasks(const Desc: string; MaskIndex: integer): string;
var i, StartPos, EndPos: integer;
begin
Result:=Desc;
for i:=0 to Masks.Count-1 do begin
if i=MaskIndex then continue;
StartPos:=Pos(Masks[i],Result);
EndPos:=StartPos+length(Masks[i]);
if StartPos<1 then continue;
while (StartPos>1) and (Result[StartPos-1] in [' ',#9,';']) do
dec(StartPos);
while (EndPos<=length(Result)) and (Result[EndPos] in [' ',#9]) do
inc(EndPos);
if (StartPos>1) and (Result[StartPos-1]='(')
and (EndPos<=length(Result)) then begin
if (Result[EndPos]=')') then begin
dec(StartPos);
inc(EndPos);
end else if Result[EndPos]=';' then begin
inc(EndPos);
end;
end;
System.Delete(Result,StartPos,EndPos-StartPos);
end;
end;
procedure AddEntries(const Desc: string; MultiMask: string);
var i: integer;
CurDesc: string;
begin
ExtractMasks(MultiMask);
for i:=0 to Masks.Count-1 do begin
CurDesc:=RemoveOtherMasks(Desc,i);
if (Masks.Count>1) and (Pos(Masks[i],CurDesc)<1) then begin
if (CurDesc='') or (CurDesc[length(CurDesc)]<>' ') then
CurDesc:=CurDesc+' ';
CurDesc:=CurDesc+'('+Masks[i]+')';
end;
//debugln('AddEntries ',CurDesc,' ',Masks[i]);
AddEntry(CurDesc,Masks[i]);
end;
inc(CurFilterIndex);
end;
var
CurDescStart, CurDescEnd, CurMultiMaskStart, CurMultiMaskEnd: integer;
CurDesc, CurMultiMask: string;
begin
FilterList:=TFPList.Create;
Masks:=nil;
CurFilterIndex:=0;
CurDescStart:=1;
while CurDescStart<=length(Filter) do begin
// extract next filter description
CurDescEnd:=CurDescStart;
while (CurDescEnd<=length(Filter)) and (Filter[CurDescEnd]<>'|') do
inc(CurDescEnd);
CurDesc:=copy(Filter,CurDescStart,CurDescEnd-CurDescStart);
// extract next filter multi mask
CurMultiMaskStart:=CurDescEnd+1;
CurMultiMaskEnd:=CurMultiMaskStart;
while (CurMultiMaskEnd<=length(Filter)) and (Filter[CurMultiMaskEnd]<>'|')
do
inc(CurMultiMaskEnd);
CurMultiMask:=copy(Filter,CurMultiMaskStart,CurMultiMaskEnd-CurMultiMaskStart);
if CurDesc='' then CurDesc:=CurMultiMask;
// add filter(s)
if (CurMultiMask<>'') or (CurDesc<>'') then
AddEntries(CurDesc,CurMultiMask);
// next filter
CurDescStart:=CurMultiMaskEnd+1;
end;
Masks.Free;
end;
procedure ExtractFilterList(const Filter: string; out FilterList: TFPList;
SplitMultiMask: boolean);
Index: lcl/interfaces/gtk/gtkobject.inc
===================================================================
--- lcl/interfaces/gtk/gtkobject.inc (Revision 8076)
+++ lcl/interfaces/gtk/gtkobject.inc (Arbeitskopie)
@@ -4164,143 +4164,6 @@
end;
{------------------------------------------------------------------------------
- Function: ExtractFilterList
- Params: const Filter: string; var FilterIndex: integer;
- var FilterList: TStringList
- Returns: -
-
- Converts a Delphi file filter of the form
- 'description1|mask1|description2|mask2|...'
- into a TFPList of PFileSelFilterEntry(s).
- Multi masks:
- - multi masks like '*.pas;*.pp' are converted into multiple entries.
- - if the masks are found in the description they are adjusted
- - if the mask is not included in the description it will be concatenated
- For example:
- 'Pascal files (*.pas;*.pp)|*.pas;*.lpr;*.pp;
- is converted to three filter entries:
- 'Pascal files (*.pas)' + '*.pas'
- 'Pascal files (*.pp)' + '*.pp'
- 'Pascal files (*.lpr)' + '*.lpr'
- ------------------------------------------------------------------------------}
-procedure ExtractFilterList(const Filter: string; out FilterList: TFPList;
- SplitMultiMask: boolean);
-var
- Masks: TStringList;
- CurFilterIndex: integer;
-
- procedure ExtractMasks(const MultiMask: string);
- var CurMaskStart, CurMaskEnd: integer;
- s: string;
- begin
- if Masks=nil then
- Masks:=TStringList.Create
- else
- Masks.Clear;
- CurMaskStart:=1;
- while CurMaskStart<=length(MultiMask) do begin
- CurMaskEnd:=CurMaskStart;
- if SplitMultiMask then begin
- while (CurMaskEnd<=length(MultiMask)) and (MultiMask[CurMaskEnd]<>';')
- do
- inc(CurMaskEnd);
- end else begin
- CurMaskEnd:=length(MultiMask)+1;
- end;
- s:=Trim(copy(MultiMask,CurMaskStart,CurMaskEnd-CurMaskStart));
- Masks.Add(s);
- CurMaskStart:=CurMaskEnd+1;
- end;
- end;
-
- procedure AddEntry(const Desc, Mask: string);
- var NewFilterEntry: PFileSelFilterEntry;
- 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);
- end;
-
- // remove all but one masks from description string
- function RemoveOtherMasks(const Desc: string; MaskIndex: integer): string;
- var i, StartPos, EndPos: integer;
- begin
- Result:=Desc;
- for i:=0 to Masks.Count-1 do begin
- if i=MaskIndex then continue;
- StartPos:=Pos(Masks[i],Result);
- EndPos:=StartPos+length(Masks[i]);
- if StartPos<1 then continue;
- while (StartPos>1) and (Result[StartPos-1] in [' ',#9,';']) do
- dec(StartPos);
- while (EndPos<=length(Result)) and (Result[EndPos] in [' ',#9]) do
- inc(EndPos);
- if (StartPos>1) and (Result[StartPos-1]='(')
- and (EndPos<=length(Result)) then begin
- if (Result[EndPos]=')') then begin
- dec(StartPos);
- inc(EndPos);
- end else if Result[EndPos]=';' then begin
- inc(EndPos);
- end;
- end;
- System.Delete(Result,StartPos,EndPos-StartPos);
- end;
- end;
-
- procedure AddEntries(const Desc: string; MultiMask: string);
- var i: integer;
- CurDesc: string;
- begin
- ExtractMasks(MultiMask);
- for i:=0 to Masks.Count-1 do begin
- CurDesc:=RemoveOtherMasks(Desc,i);
- if (Masks.Count>1) and (Pos(Masks[i],CurDesc)<1) then begin
- if (CurDesc='') or (CurDesc[length(CurDesc)]<>' ') then
- CurDesc:=CurDesc+' ';
- CurDesc:=CurDesc+'('+Masks[i]+')';
- end;
- //debugln('AddEntries ',CurDesc,' ',Masks[i]);
- AddEntry(CurDesc,Masks[i]);
- end;
- inc(CurFilterIndex);
- end;
-
-var
- CurDescStart, CurDescEnd, CurMultiMaskStart, CurMultiMaskEnd: integer;
- CurDesc, CurMultiMask: string;
-begin
- FilterList:=TFPList.Create;
- Masks:=nil;
- CurFilterIndex:=0;
- CurDescStart:=1;
- while CurDescStart<=length(Filter) do begin
- // extract next filter description
- CurDescEnd:=CurDescStart;
- while (CurDescEnd<=length(Filter)) and (Filter[CurDescEnd]<>'|') do
- inc(CurDescEnd);
- CurDesc:=copy(Filter,CurDescStart,CurDescEnd-CurDescStart);
- // extract next filter multi mask
- CurMultiMaskStart:=CurDescEnd+1;
- CurMultiMaskEnd:=CurMultiMaskStart;
- while (CurMultiMaskEnd<=length(Filter)) and (Filter[CurMultiMaskEnd]<>'|') do
- inc(CurMultiMaskEnd);
- CurMultiMask:=copy(Filter,CurMultiMaskStart,CurMultiMaskEnd-CurMultiMaskStart);
- if CurDesc='' then CurDesc:=CurMultiMask;
- // add filter(s)
- if (CurMultiMask<>'') or (CurDesc<>'') then
- AddEntries(CurDesc,CurMultiMask);
- // next filter
- CurDescStart:=CurMultiMaskEnd+1;
- end;
- Masks.Free;
-end;
-
-{------------------------------------------------------------------------------
Function: TGtkWidgetSet.CreateOpenDialogFilter
Params: OpenDialog: TOpenDialog; SelWidget: PGtkWidget
Returns: -
Index: lcl/interfaces/gtk/gtkint.pp
===================================================================
--- lcl/interfaces/gtk/gtkint.pp (Revision 8076)
+++ lcl/interfaces/gtk/gtkint.pp (Arbeitskopie)
@@ -218,16 +218,16 @@
AWinControl: TWinControl);virtual;
procedure UntransientWindow(GtkWindow: PGtkWindow);
procedure InitializeFileDialog(FileDialog: TFileDialog;
- var SelWidget: PGtkWidget; Title: PChar);
+ var SelWidget: PGtkWidget; Title: PChar); virtual;
procedure InitializeFontDialog(FontDialog: TFontDialog;
var SelWidget: PGtkWidget; Title: PChar);
procedure InitializeCommonDialog(ADialog: TObject; AWindow: PGtkWidget);
function CreateOpenDialogFilter(OpenDialog: TOpenDialog;
- SelWidget: PGtkWidget): string;
+ SelWidget: PGtkWidget): string; virtual;
procedure CreatePreviewDialogControl(PreviewDialog: TPreviewFileDialog;
- SelWidget: PGtkWidget);
+ SelWidget: PGtkWidget); virtual;
procedure InitializeOpenDialog(OpenDialog: TOpenDialog;
- SelWidget: PGtkWidget);
+ SelWidget: PGtkWidget); virtual;
// misc
Function GetCaption(Sender : TObject) : String; virtual;
@@ -297,6 +297,7 @@
end;
{$I gtklistslh.inc}
+{$I filedialogutilsh.inc}
var
GTKWidgetSet: TGTKWidgetSet;
@@ -344,6 +345,7 @@
GtkNil = nil;
{$I gtklistsl.inc}
+{$I filedialogutils.inc}
{$I gtkobject.inc}
{$I gtkwinapi.inc}
{$I gtklclintf.inc}
Index: lcl/interfaces/gtk2/gtk2int.pas
===================================================================
--- lcl/interfaces/gtk2/gtk2int.pas (Revision 8076)
+++ lcl/interfaces/gtk2/gtk2int.pas (Arbeitskopie)
@@ -67,6 +67,15 @@
MultiSelect, ExtendedSelect: boolean); override;
//function SetTopIndex(Sender: TObject; NewTopIndex: integer): integer; override;
procedure UpdateDCTextMetric(DC: TDeviceContext); override;
+
+ procedure InitializeFileDialog(FileDialog: TFileDialog;
+ var SelWidget: PGtkWidget; Title: PChar); override;
+ function CreateOpenDialogFilter(OpenDialog: TOpenDialog;
+ SelWidget: PGtkWidget): string; override;
+ procedure InitializeOpenDialog(OpenDialog: TOpenDialog;
+ SelWidget: PGtkWidget); override;
+ procedure CreatePreviewDialogControl(
+ PreviewDialog: TPreviewFileDialog; SelWidget: PGtkWidget); override;
public
{$I gtk2winapih.inc}
{$I gtk2lclintfh.inc}
Index: lcl/interfaces/gtk2/gtk2object.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2object.inc (Revision 8076)
+++ lcl/interfaces/gtk2/gtk2object.inc (Arbeitskopie)
@@ -126,6 +126,67 @@
Result := False;
end;
+procedure Gtk2FileChooserResponseCB(widget: PGtkFileChooser; arg1: gint; data: gpointer); cdecl;
+
+ procedure AddFile(List: TStrings; const NewFile: string);
+ var
+ i: Integer;
+ begin
+ for i:=0 to List.Count-1 do
+ if List[i]=NewFile then exit;
+ List.Add(NewFile);
+ end;
+
+var
+ TheDialog: TFileDialog;
+ cFilename: PChar;
+ cFilenames: PGSList;
+ cFilenames1: PGSList;
+ Files: TStringList;
+begin
+ theDialog := TFileDialog(data);
+
+ if arg1 = GTK_RESPONSE_CANCEL then begin
+ TheDialog.UserChoice := mrCancel;
+ Exit;
+ end;
+
+ if theDialog is TOpenDialog then begin
+ if ofAllowMultiSelect in TOpenDialog(theDialog).Options then begin
+ TheDialog.FileName := '';
+ Files := TStringList(TheDialog.Files);
+ Files.Clear;
+
+ cFilenames := gtk_file_chooser_get_filenames(widget);
+ if Assigned(cFilenames) then begin
+
+ cFilenames1 := cFilenames;
+ while Assigned(cFilenames1) do begin
+ cFilename := PChar(cFilenames1^.data);
+
+ if Assigned(cFilename) then begin
+ AddFile(Files, cFilename);
+ g_free(cFilename);
+ end;
+
+ cFilenames1 := cFilenames1^.next;
+ end;
+
+ g_slist_free(cFilenames);
+ end;
+ end;
+ end;
+
+ cFilename := gtk_file_chooser_get_filename(widget);
+ if Assigned(cFilename) then begin
+ TheDialog.FileName := cFilename;
+ g_free(cFilename);
+ end;
+
+ //?? StoreCommonDialogSetup(theDialog);
+ theDialog.UserChoice := mrOK;
+end;
+
Procedure gtk_clb_toggle(cellrenderertoggle : PGtkCellRendererToggle; arg1 : PGChar;
WinControl: TWinControl); cdecl;
var
@@ -1454,6 +1515,199 @@
end;
end;
+{------------------------------------------------------------------------------
+ Function: TGtk2WidgetSet.InitializeOpenDialog
+ Params: OpenDialog: TOpenDialog; SelWidget: PGtkWidget
+ Returns: -
+
+ Adds some functionality to a gtk file selection dialog.
+ - multiselection
+ - range selection
+ - close on escape
+ - file information
+ - history pulldown
+ - filter pulldown
+ - preview control
+
+ requires: gtk+ 2.6
+ ------------------------------------------------------------------------------}
+procedure TGtk2WidgetSet.InitializeOpenDialog(OpenDialog: TOpenDialog;
+ SelWidget: PGtkWidget);
+var
+ FileSelWidget: PGtkFileChooser;
+ HelpButton: PGtkWidget;
+begin
+ if (gtk_major_version < 2) or (gtk_minor_version < 6) then begin
+ inherited;
+ Exit;
+ end;
+
+ FileSelWidget := GTK_FILE_CHOOSER(SelWidget);
+
+ // Help button
+ if (ofShowHelp in OpenDialog.Options) then begin
+ HelpButton := gtk_dialog_add_button(FileSelWidget, GTK_STOCK_HELP, GTK_RESPONSE_NONE);
+
+ g_signal_connect( gtk_object(HelpButton),
+ 'clicked', gtk_signal_func(@gtkDialogHelpclickedCB), OpenDialog);
+ end;
+
+ if ofAllowMultiSelect in OpenDialog.Options then
+ gtk_file_chooser_set_select_multiple(FileSelWidget, True);
+
+{$IFDEF NONO}
+ // History List - a frame with an option menu
+ CreateOpenDialogHistory(OpenDialog, SelWidget);
+
+// // Filter - a frame with an option menu
+ CreateOpenDialogFilter(OpenDialog,SelWidget);
+
+ // Details - a frame with a label
+ if (ofViewDetail in OpenDialog.Options) then begin
+
+ // create the frame around the information
+ FrameWidget:=gtk_frame_new(PChar(rsFileInformation));
+ gtk_box_pack_start(GTK_BOX(FileSelWidget^.main_vbox),
+ FrameWidget,false,false,0);
+ gtk_widget_show(FrameWidget);
+ // create a HBox, so that the information is left justified
+ HBox:=gtk_hbox_new(false,0);
+ gtk_container_add(GTK_CONTAINER(FrameWidget), HBox);
+ // create the label for the file information
+ FileDetailLabel:=gtk_label_new(PChar(rsDefaultFileInfoValue));
+ gtk_box_pack_start(GTK_BOX(HBox),FileDetailLabel,false,false,5);
+ gtk_widget_show_all(HBox);
+ end else
+ FileDetailLabel:=nil;
+ gtk_object_set_data(PGtkObject(SelWidget), 'FileDetailLabel',
+ FileDetailLabel);
+{$ENDIF NONO}
+
+ // preview
+ if (OpenDialog is TPreviewFileDialog) then
+ CreatePreviewDialogControl(TPreviewFileDialog(OpenDialog), SelWidget);
+
+ // set initial filename
+ if OpenDialog.Filename<>'' then
+ gtk_file_chooser_set_filename(FileSelWidget, PChar(OpenDialog.Filename));
+
+ //if InitialFilter <> 'none' then
+ // PopulateFileAndDirectoryLists(FileSelWidget, InitialFilter);
+end;
+
+{------------------------------------------------------------------------------
+ Function: TGtk2WidgetSet.InitializeFileDialog
+ Params: FileDialog: TFileDialog; var SelWidget: PGtkWidget
+ Returns: -
+
+ Creates a new TFile/Open/SaveDialog
+ requires: gtk+ 2.6
+ ------------------------------------------------------------------------------}
+procedure TGtk2WidgetSet.InitializeFileDialog(FileDialog: TFileDialog;
+ var SelWidget: PGtkWidget; Title: PChar);
+var
+ Action: TGtkFileChooserAction;
+ Button1: String;
+begin
+ if (gtk_major_version < 2) or (gtk_minor_version < 6) then begin
+ inherited;
+ Exit;
+ end;
+
+ Action := GTK_FILE_CHOOSER_ACTION_OPEN;
+ Button1 := GTK_STOCK_OPEN;
+
+ if FileDialog is TSaveDialog then begin
+ Action := GTK_FILE_CHOOSER_ACTION_SAVE;
+ Button1 := GTK_STOCK_CANCEL;
+ end;
+
+ SelWidget := gtk_file_chooser_dialog_new(Title, nil, Action,
+ PChar(GTK_STOCK_CANCEL), [GTK_RESPONSE_CANCEL, PChar(Button1), GTK_RESPONSE_OK, nil]);
+
+ g_signal_connect(SelWidget, 'response', gtk_signal_func(@Gtk2FileChooserResponseCB), FileDialog);
+
+(*gtk 2.8
+ if FileDialog is TSaveDialog then begin
+ gtk_file_chooser_set_do_overwrite_confirmation(SelWidget,
+ ofOverwritePrompt in TOpenDialog(theDialog).Options);
+ end;
+*)
+
+ if FileDialog is TOpenDialog then
+ InitializeOpenDialog(TOpenDialog(FileDialog), SelWidget);
+
+ InitializeCommonDialog(TCommonDialog(FileDialog), SelWidget);
+end;
+
+function TGtk2WidgetSet.CreateOpenDialogFilter(OpenDialog: TOpenDialog;
+ SelWidget: PGtkWidget): string;
+var
+ FilterList: TFPList;
+ i, j: integer;
+ s: String;
+ GtkFilter: PGtkFileFilter;
+begin
+ if (gtk_major_version < 2) or (gtk_minor_version < 6) then begin
+ Result := inherited;
+ Exit;
+ end;
+
+ ExtractFilterList(OpenDialog.Filter, FilterList, false);
+ if FilterList.Count > 0 then begin
+ j := 1;
+ for i := 0 to FilterList.Count-1 do begin
+ GtkFilter := gtk_file_filter_new();
+
+{s := PFileSelFilterEntry(FilterList[i])^.Mask;
+Writeln('MASK: ', s);}
+
+ gtk_file_filter_add_pattern(GtkFilter, PFileSelFilterEntry(FilterList[i])^.Mask);
+ gtk_file_filter_set_name(GtkFilter, PFileSelFilterEntry(FilterList[i])^.Description);
+
+ gtk_file_chooser_add_filter(SelWidget, GtkFilter);
+
+ if j = OpenDialog.FilterIndex then
+ gtk_file_chooser_set_filter(SelWidget, GtkFilter);
+
+ Inc(j);
+ GtkFilter := nil;
+ end;
+ end;
+
+ gtk_object_set_data(PGtkObject(SelWidget), 'LCLFilterList', FilterList);
+
+ Result := 'hm'; { Don't use '' as null return as this is used for *.* }
+end;
+
+procedure TGtk2WidgetSet.CreatePreviewDialogControl(
+ PreviewDialog: TPreviewFileDialog; SelWidget: PGtkWidget);
+var
+ PreviewWidget: PGtkWidget;
+ AControl: TPreviewFileControl;
+ FileChooser: PGtkFileChooser;
+begin
+ if (gtk_major_version < 2) or (gtk_minor_version < 6) then begin
+ inherited;
+ Exit;
+ end;
+
+ AControl := PreviewDialog.PreviewFileControl;
+ if AControl = nil then Exit;
+
+ FileChooser := PGtkFileChooser(SelWidget);
+
+ PreviewWidget := PGtkWidget(AControl.Handle);
+
+ gtk_object_set_data(PGtkObject(PreviewWidget),'LCLPreviewFixed',
+ PreviewWidget);
+ gtk_widget_set_size_request(PreviewWidget,AControl.Width,AControl.Height);
+
+ gtk_file_chooser_set_preview_widget(FileChooser, PreviewWidget);
+
+ gtk_widget_show(PreviewWidget);
+end;
+
{$IFDEF ASSERT_IS_ON}
{$UNDEF ASSERT_IS_ON}
{$C-}