gtk2 intf can now optionally use the file chooses, compile with HasGTK2_6

git-svn-id: trunk@8194 -
This commit is contained in:
mattias 2005-11-19 11:55:08 +00:00
parent 00d2646d1b
commit f5ff9d9bd6
4 changed files with 270 additions and 141 deletions

View File

@ -220,16 +220,16 @@ type
AWinControl: TWinControl);virtual; AWinControl: TWinControl);virtual;
procedure UntransientWindow(GtkWindow: PGtkWindow); procedure UntransientWindow(GtkWindow: PGtkWindow);
procedure InitializeFileDialog(FileDialog: TFileDialog; procedure InitializeFileDialog(FileDialog: TFileDialog;
var SelWidget: PGtkWidget; Title: PChar); var SelWidget: PGtkWidget; Title: PChar); virtual;
procedure InitializeFontDialog(FontDialog: TFontDialog; procedure InitializeFontDialog(FontDialog: TFontDialog;
var SelWidget: PGtkWidget; Title: PChar); var SelWidget: PGtkWidget; Title: PChar);
procedure InitializeCommonDialog(ADialog: TObject; AWindow: PGtkWidget); procedure InitializeCommonDialog(ADialog: TObject; AWindow: PGtkWidget);
function CreateOpenDialogFilter(OpenDialog: TOpenDialog; function CreateOpenDialogFilter(OpenDialog: TOpenDialog;
SelWidget: PGtkWidget): string; SelWidget: PGtkWidget): string; virtual;
procedure CreatePreviewDialogControl(PreviewDialog: TPreviewFileDialog; procedure CreatePreviewDialogControl(PreviewDialog: TPreviewFileDialog;
SelWidget: PGtkWidget); SelWidget: PGtkWidget); virtual;
procedure InitializeOpenDialog(OpenDialog: TOpenDialog; procedure InitializeOpenDialog(OpenDialog: TOpenDialog;
SelWidget: PGtkWidget); SelWidget: PGtkWidget); virtual;
// misc // misc
Function GetCaption(Sender : TObject) : String; virtual; Function GetCaption(Sender : TObject) : String; virtual;
@ -299,6 +299,7 @@ type
end; end;
{$I gtklistslh.inc} {$I gtklistslh.inc}
{$I gtkfiledialogutilsh.inc}
var var
GTKWidgetSet: TGTKWidgetSet; GTKWidgetSet: TGTKWidgetSet;
@ -346,6 +347,7 @@ const
GtkNil = nil; GtkNil = nil;
{$I gtklistsl.inc} {$I gtklistsl.inc}
{$I gtkfiledialogutils.inc}
{$I gtkobject.inc} {$I gtkobject.inc}
{$I gtkwinapi.inc} {$I gtkwinapi.inc}
{$I gtklclintf.inc} {$I gtklclintf.inc}

View File

@ -4163,143 +4163,6 @@ begin
gtk_object_set_data(PGtkObject(SelWidget), 'LCLHistoryList', HistoryList); gtk_object_set_data(PGtkObject(SelWidget), 'LCLHistoryList', HistoryList);
end; 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 Function: TGtkWidgetSet.CreateOpenDialogFilter
Params: OpenDialog: TOpenDialog; SelWidget: PGtkWidget Params: OpenDialog: TOpenDialog; SelWidget: PGtkWidget

View File

@ -67,6 +67,15 @@ type
MultiSelect, ExtendedSelect: boolean); override; MultiSelect, ExtendedSelect: boolean); override;
//function SetTopIndex(Sender: TObject; NewTopIndex: integer): integer; override; //function SetTopIndex(Sender: TObject; NewTopIndex: integer): integer; override;
procedure UpdateDCTextMetric(DC: TDeviceContext); 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 public
{$I gtk2winapih.inc} {$I gtk2winapih.inc}
{$I gtk2lclintfh.inc} {$I gtk2lclintfh.inc}

View File

@ -126,6 +126,69 @@ begin
Result := False; Result := False;
end; end;
{$IFDEF HasGTK2_6}
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;
{$ENDIF}
Procedure gtk_clb_toggle(cellrenderertoggle : PGtkCellRendererToggle; arg1 : PGChar; Procedure gtk_clb_toggle(cellrenderertoggle : PGtkCellRendererToggle; arg1 : PGChar;
WinControl: TWinControl); cdecl; WinControl: TWinControl); cdecl;
var var
@ -1454,6 +1517,198 @@ begin
end; end;
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);
{$IFDEF HasGTK2_6}
var
FileSelWidget: PGtkFileChooser;
HelpButton: PGtkWidget;
{$ENDIF}
begin
{$IFDEF HasGTK2_6}
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);
// 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);
// 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);
{$ELSE}
inherited InitializeOpenDialog(OpenDialog,SelWidget);
{$ENDIF NONO}
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);
{$IFDEF HasGTK2_6}
var
Action: TGtkFileChooserAction;
Button1: String;
{$ENDIF}
begin
{$IFDEF HasGTK2_6}
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);
{$ELSE}
inherited InitializeFileDialog(FileDialog,SelWidget,Title);
{$ENDIF}
end;
function TGtk2WidgetSet.CreateOpenDialogFilter(OpenDialog: TOpenDialog;
SelWidget: PGtkWidget): string;
{$IFDEF HasGTK2_6}
var
FilterList: TFPList;
i, j: integer;
s: String;
GtkFilter: PGtkFileFilter;
{$ENDIF}
begin
{$IFDEF HasGTK2_6}
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();
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 *.* }
{$ELSE}
Result:=inherited CreateOpenDialogFilter(OpenDialog,SelWidget);
{$ENDIF}
end;
procedure TGtk2WidgetSet.CreatePreviewDialogControl(
PreviewDialog: TPreviewFileDialog; SelWidget: PGtkWidget);
{$IFDEF HasGTK2_6}
var
PreviewWidget: PGtkWidget;
AControl: TPreviewFileControl;
FileChooser: PGtkFileChooser;
{$ENDIF}
begin
{$IFDEF HasGTK2_6}
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);
{$ELSE}
inherited CreatePreviewDialogControl(PreviewDialog,SelWidget);
{$ENDIF}
end;
{$IFDEF ASSERT_IS_ON} {$IFDEF ASSERT_IS_ON}
{$UNDEF ASSERT_IS_ON} {$UNDEF ASSERT_IS_ON}
{$C-} {$C-}