(*
    Tux Commander - UFileTypeSettings - The filetype settings dialog
    Copyright (C) 2007 Tomas Bzatek <tbzatek@users.sourceforge.net>
    Check for updates on tuxcmd.sourceforge.net

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*)
unit UFileTypeSettings;

interface

uses
  gtk2, SysUtils, Types, Classes, Variants, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView, GTKUtils, GTKDialogs,
  GTKPixbuf, GTKClasses,
  UCoreClasses, UGnome;

type
  TFFileTypeSettings = class(TGTKDialog)
    TitleFrame: TGTKFrame;
    TitleLabel: TGTKLabel;
    TitleEventBox: TGTKEventBox;
    TitleIcon: TGTKImage;
    TitleHBox: TGTKHBox;
    ListView, FNameExtListView, ActionsListView: TGTKListView;
    ListViewScrolledWindow, FNameExtListViewScrolledWindow, ActionsListViewScrolledWindow: TGTKScrolledWindow;
    AssocListFrame, IconFrame: TGTKFrame;
    FNameExtLabel, CommandLabel, DescriptionLabel, AssocDescriptionLabel, IconLabel, ColorLabel: TGTKLabel;
    AssocListButtonBox, FNameExtButtonBox, ActionsButtonBox, ActionsButtonBox2: TGTKHButtonBox;
    AssocListVBox, FNameExtVBox, FNameExtVBox2, FNameExtVBox3, ActionsVBox: TGTKVBox;
    AssocListHBox, FNameExtHBox, FNameExtHBox2, ActionsHBox, ActionsHBox2, AssocDescriptionHBox, ColorHBox: TGTKHBox;
    AddFiletypeButton, RemoveFiletypeButton, AddExtButton, RemoveExtButton, AddActionButton, RemoveActionButton,
    SetDefaultActionButton, BrowseButton, BrowseIconButton: TGTKButton;
    ColorButton: TGnomeColorButton;
    FNameExtEntry, CommandEntry, DescriptionEntry, AssocDescriptionEntry, IconEntry: TGTKEntry;
    RunInTerminalCheckBox, AutodetectCheckBox, DefaultColorCheckBox: TGTKCheckButton;
    Notebook: TGTKNotebook;
    Table, Table2: TGTKTable;
    Icon: TGTKImage;
    GnomeIconButton: TGnomeIconEntry;
    procedure FormCreate(Sender: TObject); override;
    procedure FormDestroy(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
    procedure AddFiletypeButtonClick(Sender: TObject);
    procedure RemoveFiletypeButtonClick(Sender: TObject);
    procedure ListViewSelectionChanged(Sender: TObject);
    procedure AddExtButtonClick(Sender: TObject);
    procedure RemoveExtButtonClick(Sender: TObject);
    procedure FNameExtEntryKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
    procedure FNameExtListViewSelectionChanged(Sender: TObject);
    procedure AssocDescriptionEntryChanged(Sender: TObject);
    procedure ActionsListViewSelectionChanged(Sender: TObject);
    procedure AddActionButtonClick(Sender: TObject);
    procedure RemoveActionButtonClick(Sender: TObject);
    procedure DescriptionEntryChanged(Sender: TObject);
    procedure CommandEntryChanged(Sender: TObject);
    procedure RunInTerminalCheckBoxToggled(Sender: TObject);
    procedure AutodetectCheckBoxToggled(Sender: TObject);
    procedure SetDefaultActionButtonClick(Sender: TObject);
    procedure BrowseButtonClick(Sender: TObject);
    procedure IconEntryChanged(Sender: TObject);
    procedure BrowseIconButtonClick(Sender: TObject);
    procedure ColorButtonColorChanged(Sender: TObject);
    procedure DefaultColorCheckBoxToggled(Sender: TObject);
    procedure ListViewCellDataFunc(Sender: TObject; tree_view: PGtkTreeView; tree_column : PGtkTreeViewColumn; cell : PGtkCellRenderer; tree_model : PGtkTreeModel; iter : PGtkTreeIter);
    procedure ActionsListViewCellDataFunc(Sender: TObject; tree_view: PGtkTreeView; tree_column : PGtkTreeViewColumn; cell : PGtkCellRenderer; tree_model : PGtkTreeModel; iter : PGtkTreeIter);
    procedure GnomeIconButtonIconChanged(Sender: TObject);
  public
    IntAssocList: TList;
    procedure AssignAssocList(List: TList);
    procedure FillList;
    procedure CleanItems;
  private
    FUseGnomeIconEntry: boolean;
  end;

var
  FFileTypeSettings: TFFileTypeSettings;

implementation

uses glib2, ULocale, UFileAssoc, UCoreUtils, UConfig;


procedure TFFileTypeSettings.FormCreate(Sender: TObject);
var Column: TGTKTreeViewColumn;
    l: TGTKLabel;
begin
  FUseGnomeIconEntry := Assigned(gnome_icon_entry_new) and Assigned(gnome_icon_entry_get_filename) and Assigned(gnome_icon_entry_set_filename);
  SetDefaultSize(450, 620);
  Caption := LANGEditFileTypesCaption;
  Buttons := [mbOK, mbCancel];
  ShowSeparator := False;
  TitleEventBox := TGTKEventBox.Create(Self);
  TitleLabel := TGTKLabel.Create(Self);
  TitleLabel.Caption := LANGTitleLabel_Caption;
  TitleLabel.UseMarkup := True;
  TitleLabel.XAlign := 0;
  TitleLabel.XPadding := 0;
  TitleLabel.YPadding := 3;
  TitleEventBox.ControlState := csPrelight;
  TitleFrame := TGTKFrame.CreateWithoutLabel(Self);
  TitleFrame.ShadowType := stShadowOut;
  TitleIcon := TGTKImage.Create(Self);
  TitleIcon.SetFromStock('gtk-copy', isLargeToolbar);
  TitleHBox := TGTKHBox.Create(Self);
  TitleHBox.Homogeneous := False;
  TitleHBox.AddControlEx(TGTKEventBox.Create(Self), False, False, 5);
  TitleHBox.AddControlEx(TitleIcon, False, False, 0);
  TitleHBox.AddControlEx(TitleLabel, True, True, 10);
  TitleEventBox.AddControl(TitleHBox);
  TitleFrame.AddControl(TitleEventBox);
  ClientArea.AddControlEx(TitleFrame, False, True, 0);

  ListView := TGTKListView.CreateTyped(Self, Application.GTKVersion_2_0_5_Up, [lcText, lcText, lcPointer, lcPixbuf]);
  ListView.RulesHint := True;
  Column := ListView.Columns.AddTyped(ctImageText);;
  Column.Caption := LANGExtensionsColumn;
  Column.AddImageAttribute('pixbuf', 3);
  Column.AddAttribute('text', 0);
  if Application.GTKVersion_2_0_5_Up then Column.SortID := 0;
  Column.Resizable := True;
  g_object_set(G_OBJECT(Column.FColumn), 'sizing', 2, 'fixed-width', 150, nil);
{  Column.FixedWidth := 300;
  Column.SizingMode := smFixed; }
  if Application.GTKVersion_2_6_0_Up then Column.SetProperty('ellipsize', 3);
  Column := ListView.Columns.Add;
  Column.Caption := LANGDescriptionColumn;
  Column.AddAttribute('text', 1);
  if Application.GTKVersion_2_0_5_Up then Column.SortID := 1;
  Column.Resizable := True;
  ListViewScrolledWindow := TGTKScrolledWindow.Create(Self);
  ListViewScrolledWindow.AddControl(ListView);
  ListViewScrolledWindow.HorizScrollBarPolicy := sbAutomatic;
  ListViewScrolledWindow.VertScrollBarPolicy := sbAutomatic;
  ListViewScrolledWindow.ShadowType := stShadowIn;
  AssocListHBox := TGTKHBox.Create(Self);
  AssocListVBox := TGTKVBox.Create(Self);
  AssocListVBox.AddControlEx(ListViewScrolledWindow, True, True, 4);
  AssocListButtonBox := TGTKHButtonBox.Create(Self);
  AssocListButtonBox.Layout := blEnd;
  AssocListButtonBox.Spacing := 2;
  AddFiletypeButton := TGTKButton.CreateFromStock(Self, 'gtk-add');
  RemoveFiletypeButton := TGTKButton.CreateFromStock(Self, 'gtk-remove');
  AssocListButtonBox.AddControlEx(AddFiletypeButton, False, False, 0);
  AssocListButtonBox.AddControlEx(RemoveFiletypeButton, False, False, 0);
  AssocListVBox.AddControlEx(AssocListButtonBox, False, False, 5);
  AssocListFrame := TGTKFrame.Create(Self);
  AssocListFrame.Caption := LANGFileTypesList;
  AssocListHBox.AddControlEx(AssocListVBox, True, True, 10);
  AssocListFrame.AddControl(AssocListHBox);
  AssocListFrame.BorderWidth := 7;
  ClientArea.AddControlEx(AssocListFrame, True, True, 0);

  Notebook := TGTKNotebook.Create(Self);
  Notebook.BorderWidth := 8;
  ClientArea.AddControlEx(Notebook, False, False, 0);

  ActionsListViewScrolledWindow := TGTKScrolledWindow.Create(Self);
  ActionsListView := TGTKListView.CreateTyped(Self, Application.GTKVersion_2_0_5_Up, [lcText, lcText, lcPointer]);
  ActionsListView.RulesHint := True;
  Column := ActionsListView.Columns.Add;
  Column.Caption := LANGActionName;
  Column.AddAttribute('text', 0);
  if Application.GTKVersion_2_0_5_Up then Column.SortID := 0;
  Column.Resizable := True;
  Column.FixedWidth := 180;
  Column.SizingMode := smFixed;
  Column := ActionsListView.Columns.Add;
  Column.Caption := LANGCommand;
  Column.AddAttribute('text', 1);
  if Application.GTKVersion_2_0_5_Up then Column.SortID := 1;
  Column.Resizable := True;
  ActionsListViewScrolledWindow.AddControl(ActionsListView);
  ActionsListViewScrolledWindow.VertScrollBarPolicy := sbAutomatic;
  ActionsListViewScrolledWindow.HorizScrollBarPolicy := sbAutomatic;
  ActionsListViewScrolledWindow.ShadowType := stShadowIn;
  ActionsListViewScrolledWindow.SetSizeRequest(-1, 95);
  ActionsVBox := TGTKVBox.Create(Self);
  ActionsButtonBox := TGTKHButtonBox.Create(Self);
  ActionsButtonBox.Spacing := 2;
  ActionsButtonBox.Layout := blEnd;
  ActionsButtonBox2 := TGTKHButtonBox.Create(Self);
  ActionsButtonBox2.Layout := blStart;
  ActionsHBox := TGTKHBox.Create(Self);
  ActionsHBox2 := TGTKHBox.Create(Self);
  AddActionButton := TGTKButton.CreateFromStock(Self, 'gtk-add');
  RemoveActionButton := TGTKButton.CreateFromStock(Self, 'gtk-remove');
  SetDefaultActionButton := TGTKButton.Create(Self);
  SetDefaultActionButton.Caption := LANGSetDefaultActionButton_Caption;
  RunInTerminalCheckBox := TGTKCheckButton.CreateWithLabel(Self, LANGRunInTerminalCheckBox_Caption);
  RunInTerminalCheckBox.Enabled := False;
  AutodetectCheckBox := TGTKCheckButton.CreateWithLabel(Self, LANGAutodetectCheckBox_Caption);
  AutodetectCheckBox.Checked := True;
  ActionsButtonBox.AddControl(AddActionButton);
  ActionsButtonBox.AddControl(RemoveActionButton);
  ActionsButtonBox2.AddControl(SetDefaultActionButton);
  ActionsHBox.AddControlEx(ActionsButtonBox2, True, True, 5);
  ActionsHBox.AddControlEx(ActionsButtonBox, True, True, 0);
  ActionsVBox.AddControlEx(ActionsListViewScrolledWindow, True, True, 3);
  CommandEntry := TGTKEntry.Create(Self);
  CommandEntry.Tooltip := LANGCommandEntry_Tooltip;
  DescriptionEntry := TGTKEntry.Create(Self);
  BrowseButton := TGTKButton.Create(Self);
  BrowseButton.Caption := LANGBrowseButton_Caption;
  CommandLabel := TGTKLabel.Create(Self);
  CommandLabel.Caption := LANGCommandLabel_Caption;
  CommandLabel.XAlign := 0;
  CommandLabel.FocusControl := CommandEntry;
  CommandLabel.UseUnderline := True;
  DescriptionLabel := TGTKLabel.Create(Self);
  DescriptionLabel.Caption := LANGDescriptionLabel_Caption;
  DescriptionLabel.XAlign := 0;
  DescriptionLabel.FocusControl := DescriptionEntry;
  DescriptionLabel.UseUnderline := True;
  Table := TGTKTable.Create(Self);
  Table.SetRowColCount(4, 2);
  Table.Homogeneous := False;
  Table.RowSpacing := 1;
  Table.AddControl(0, 0, 1, 1, DescriptionLabel, 0, 0);
  Table.AddControl(1, 0, 3, 1, DescriptionEntry, 0, 0);
  Table.AddControl(0, 1, 1, 1, CommandLabel, 0, 0);
  Table.AddControl(1, 1, 3, 1, CommandEntry, 0, 0);
  ActionsHBox2.Homogeneous := False;
  ActionsHBox2.AddControlEx(AutodetectCheckBox, True, True, 5);
  ActionsHBox2.AddControlEx(RunInTerminalCheckBox, True, True, 5);
  ActionsHBox2.AddControlEx(BrowseButton, False, False, 0);
  ActionsVBox.AddControlEx(Table, False, False, 1);
  ActionsVBox.AddControlEx(ActionsHBox2, False, False, 0);
  l := TGTKLabel.Create(Self);
  l.SetSizeRequest(0, 4);
  ActionsVBox.AddControlEx(l, False, False, 0);
  ActionsVBox.AddControlEx(ActionsHBox, False, False, 0);
  ActionsVBox.BorderWidth := 8;

  AssocDescriptionLabel := TGTKLabel.Create(Self);
  AssocDescriptionLabel.Caption := LANGDescriptionLabel_Caption;
  AssocDescriptionEntry := TGTKEntry.Create(Self);
  AssocDescriptionLabel.FocusControl := AssocDescriptionEntry;
  AssocDescriptionLabel.UseUnderline := True;
  AssocDescriptionHBox := TGTKHBox.Create(Self);
  AssocDescriptionHBox.Homogeneous := False;
  AssocDescriptionHBox.AddControlEx(AssocDescriptionLabel, False, False, 10);
  AssocDescriptionHBox.AddControlEx(AssocDescriptionEntry, True, True, 10);
  FNameExtListViewScrolledWindow := TGTKScrolledWindow.Create(Self);
  FNameExtListViewScrolledWindow.HorizScrollBarPolicy := sbAutomatic;
  FNameExtListViewScrolledWindow.VertScrollBarPolicy := sbAutomatic;
  FNameExtListViewScrolledWindow.ShadowType := stShadowIn;
  FNameExtListView := TGTKListView.CreateTyped(Self, False, [lcText]);
  FNameExtListView.ShowHeaders := False;
  Column := FNameExtListView.Columns.Add;
  Column.AddAttribute('text', 0);
  FNameExtListViewScrolledWindow.AddControl(FNameExtListView);
  FNameExtVBox2 := TGTKVBox.Create(Self);
  FNameExtVBox2.AddControlEx(FNameExtListViewScrolledWindow, True, True, 4);
  FNameExtHBox := TGTKHBox.Create(Self);
  FNameExtVBox := TGTKVBox.Create(Self);
  FNameExtLabel := TGTKLabel.Create(Self);
  FNameExtLabel.Caption := LANGFNameExtLabel_Caption;
  AddExtButton := TGTKButton.CreateFromStock(Self, 'gtk-add');
  RemoveExtButton := TGTKButton.CreateFromStock(Self, 'gtk-remove');
  FNameExtEntry := TGTKEntry.Create(Self);
  FNameExtEntry.SetSizeRequest(0, -1);
  FNameExtLabel.FocusControl := FNameExtEntry;
  FNameExtLabel.UseUnderline := True;
  FNameExtHBox.AddControlEx(FNameExtVBox, True, True, 5);
  FNameExtHBox.AddControlEx(FNameExtVBox2, True, True, 10);
  FNameExtHBox2 := TGTKHBox.Create(Self);
  FNameExtHBox2.Homogeneous := False;
  FNameExtHBox2.AddControlEx(FNameExtLabel, False, False, 4);
  FNameExtHBox2.AddControlEx(FNameExtEntry, True, True, 1);
  FNameExtHBox2.BorderWidth := 2;
  FNameExtButtonBox := TGTKHButtonBox.Create(Self);
  FNameExtButtonBox.Layout := blEnd;
  FNameExtButtonBox.AddControl(AddExtButton);
  FNameExtButtonBox.AddControl(RemoveExtButton);
  FNameExtButtonBox.BorderWidth := 3;
  FNameExtVBox.AddControlEx(FNameExtHBox2, False, False, 2);
  FNameExtVBox.AddControlEx(FNameExtButtonBox, False, False, 2);
  FNameExtVBox.AddControlEx(TGTKHSeparator.Create(Self), False, False, 2);
  ColorHBox := TGTKHBox.Create(Self);
  ColorHBox.Homogeneous := False;
  ColorHBox.BorderWidth := 2;
  ColorLabel := TGTKLabel.Create(Self);
  ColorLabel.Caption := LANGColor;
  ColorLabel.UseUnderline := True;
  ColorButton := TGnomeColorButton.Create(Self);
  ColorButton.SetSizeRequest(40, -1);
  ColorButton.OnColorChanged := ColorButtonColorChanged;
  ColorLabel.FocusControl := ColorButton;
  DefaultColorCheckBox := TGTKCheckButton.CreateWithLabel(Self, LANGDefaultColor);
  DefaultColorCheckBox.OnToggled := DefaultColorCheckBoxToggled;
  ColorHBox.AddControlEx(ColorLabel, False, False, 4);
  ColorHBox.AddControlEx(ColorButton, False, False, 5);
  ColorHBox.AddControlEx(DefaultColorCheckBox, False, False, 5);
  FNameExtVBox.AddControlEx(ColorHBox, False, False, 2);
  FNameExtVBox.AddControlEx(TGTKLabel.Create(Self), True, True, 0);
  IconLabel := TGTKLabel.Create(Self);
  IconLabel.Caption := LANGIcon;
  IconLabel.UseUnderline := True;
  IconEntry := TGTKEntry.Create(Self);
  IconEntry.OnChanged := IconEntryChanged;
  IconLabel.FocusControl := IconEntry;
  BrowseIconButton := TGTKButton.Create(Self);
  BrowseIconButton.Caption := LANGBrowseButton_Caption;
  BrowseIconButton.OnClick := BrowseIconButtonClick;
  Icon := TGTKImage.Create(Self);
  Icon.SetSizeRequest(24, 24);
  IconFrame := TGTKFrame.CreateWithoutLabel(Self);
  IconFrame.ShadowType := stEtchedIn;
  IconFrame.AddControl(Icon);
  if FUseGnomeIconEntry then begin
    GnomeIconButton := TGnomeIconEntry.Create(Self);
    GnomeIconButton.Filename := '';
    GnomeIconButton.OnIconChanged := GnomeIconButtonIconChanged;
  end;

  Table2 := TGTKTable.Create(Self);
  Table2.SetRowColCount(8, 3);
  Table2.AddControl(0, 1, 1, 1, IconLabel, 10, 0);
  if FUseGnomeIconEntry then Table2.AddControl(1, 0, 1, 3, GnomeIconButton, 0, 0);
  Table2.AddControl(2, 1, 1, 1, IconFrame, 10, 0);
  Table2.AddControl(3, 1, 4, 1, IconEntry, 0, 0);
  Table2.AddControl(7, 1, 1, 1, BrowseIconButton, 10, 0);
  if FUseGnomeIconEntry then begin
    Table2.AddControl(2, 0, 6, 1, TGTKLabel.Create(Self), 0, 0);
    Table2.AddControl(2, 2, 6, 1, TGTKLabel.Create(Self), 0, 0);
  end;
  FNameExtVBox3 := TGTKVBox.Create(Self);
  FNameExtVBox3.BorderWidth := 10;
  FNameExtVBox3.AddControlEx(AssocDescriptionHBox, False, False, 5);
  FNameExtVBox3.AddControlEx(TGTKHSeparator.Create(Self), False, False, 3);
  FNameExtVBox3.AddControlEx(Table2, False, False, 1);
  FNameExtVBox3.AddControlEx(TGTKHSeparator.Create(Self), False, False, 3);
  FNameExtVBox3.AddControlEx(FNameExtHBox, True, True, 5);
  Notebook.AppendPage(FNameExtVBox3, LANGNotebookPageExtensions);
  Notebook.AppendPage(ActionsVBox, LANGNotebookPageActions);

  OnKeyDown := FormKeyDown;
  OnDestroy := FormDestroy;
  AddFiletypeButton.OnClick := AddFiletypeButtonClick;
  RemoveFiletypeButton.OnClick := RemoveFiletypeButtonClick;
  ListView.OnSelectionChanged := ListViewSelectionChanged;
  AddExtButton.OnClick := AddExtButtonClick;
  RemoveExtButton.OnClick := RemoveExtButtonClick;
  FNameExtEntry.OnKeyDown := FNameExtEntryKeyDown;
  FNameExtListView.OnSelectionChanged := FNameExtListViewSelectionChanged;
  AssocDescriptionEntry.OnChanged := AssocDescriptionEntryChanged;
  ActionsListView.OnSelectionChanged := ActionsListViewSelectionChanged;
  AddActionButton.OnClick := AddActionButtonClick;
  RemoveActionButton.OnClick := RemoveActionButtonClick;
  DescriptionEntry.OnChanged := DescriptionEntryChanged;
  CommandEntry.OnChanged := CommandEntryChanged;
  RunInTerminalCheckBox.OnToggled := RunInTerminalCheckBoxToggled;
  AutodetectCheckBox.OnToggled := AutodetectCheckBoxToggled;
  SetDefaultActionButton.OnClick := SetDefaultActionButtonClick;
  BrowseButton.OnClick := BrowseButtonClick;

  ListView.CellDataFunc := ListViewCellDataFunc;
  ActionsListView.CellDataFunc := ActionsListViewCellDataFunc;
  ListViewSelectionChanged(Self);
  ListView.SetFocus;
end;

procedure TFFileTypeSettings.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
begin
//  if Key = GDK_ESCAPE then ModalResult := mbCancel;
end;

procedure TFFileTypeSettings.FormDestroy(Sender: TObject);
var i: integer;
begin
  if Assigned(IntAssocList) then begin
    if IntAssocList.Count > 0 then
      for i := 0 to IntAssocList.Count - 1 do
        if Assigned(IntAssocList[i]) then TFileAssoc(IntAssocList[i]).Free;
    IntAssocList.Clear;
    IntAssocList.Free;
  end;
end;

(********************************************************************************************************************************)
procedure TFFileTypeSettings.AssignAssocList(List: TList);
var i, j: integer;
    Item: TFileAssoc;
    Action: TAssocAction;
begin
  IntAssocList := TList.Create;
  if List.Count > 0 then
    for i := 0 to List.Count - 1 do begin
      Item := TFileAssoc.Create;
      with Item do begin
        CopyArray(TFileAssoc(List[i]).Extensions, Extensions);
        FileTypeName := TFileAssoc(List[i]).FileTypeName;
        DefaultAction := TFileAssoc(List[i]).DefaultAction;
        FileTypeIcon := TFileAssoc(List[i]).FileTypeIcon;
        ColorString := TFileAssoc(List[i]).ColorString;
        Pixmap := TGDKPixbuf.Create(Self);
        Pixmap.FPixbuf := TFileAssoc(List[i]).Pixmap.Copy;
        if TFileAssoc(List[i]).ActionList.Count > 0 then
          for j := 0 to TFileAssoc(List[i]).ActionList.Count - 1 do begin
            Action := TAssocAction.Create;
            with Action do begin
              ActionName := TAssocAction(TFileAssoc(List[i]).ActionList[j]).ActionName;
              ActionCommand := TAssocAction(TFileAssoc(List[i]).ActionList[j]).ActionCommand;
              RunInTerminal := TAssocAction(TFileAssoc(List[i]).ActionList[j]).RunInTerminal;
              AutodetectGUI := TAssocAction(TFileAssoc(List[i]).ActionList[j]).AutodetectGUI;
            end;
            Item.ActionList.Add(Action)
          end;
      end;
      IntAssocList.Add(Item);    
    end;
end;

procedure TFFileTypeSettings.FillList;

  procedure InternalAddItem(index: integer);
  var ListItem: TGTKListItem;
  begin
    with TFileAssoc(IntAssocList[index]) do begin
      ListItem := ListView.Items.Add;
      if FileTypeName = ConstFTAMetaDirectory then ListItem.SetValue(0, LANGFileTypeDirectory) else
      if FileTypeName = ConstFTAMetaFile then ListItem.SetValue(0, LANGFileTypeFile) else
      ListItem.SetValue(0, MakeString(';', Extensions));
      if (FileTypeName = ConstFTAMetaDirectory) or (FileTypeName = ConstFTAMetaFile)
        then ListItem.SetValue(1, LANGFileTypeMetafile)
        else ListItem.SetValue(1, FileTypeName);
      ListItem.SetValue(2, IntAssocList[index]);
      ListItem.SetValue(3, Pixmap.FPixbuf);
    end;
  end;

var i: integer;
begin
  if Assigned(IntAssocList) and (IntAssocList.Count > 0) then begin
    //  Directory metaitem first
    for i := 0 to IntAssocList.Count - 1 do
      if TFileAssoc(IntAssocList[i]).FileTypeName = ConstFTAMetaDirectory then begin
        InternalAddItem(i);
        Break;
      end;
    //  Then the file metaitem
    for i := 0 to IntAssocList.Count - 1 do
      if TFileAssoc(IntAssocList[i]).FileTypeName = ConstFTAMetaFile then begin
        InternalAddItem(i);
        Break;
      end;
    //  ... and the rest
    for i := 0 to IntAssocList.Count - 1 do
      if (TFileAssoc(IntAssocList[i]).FileTypeName <> ConstFTAMetaDirectory) and
         (TFileAssoc(IntAssocList[i]).FileTypeName <> ConstFTAMetaFile)
        then InternalAddItem(i);    
  end;
end;

procedure TFFileTypeSettings.CleanItems;
var i: integer;
begin
  try
  if IntAssocList.Count > 0 then
    for i := IntAssocList.Count - 1 downto 0 do
      with TFileAssoc(IntAssocList[i]) do begin
{        if Length(Trim(Extensions)) = 0 then begin
          TFileAssoc(IntAssocList[i]).Free;
          IntAssocList.Delete(i);
          Continue;
        end;
        if ActionList.Count > 0 then
          for j := ActionList.Count - 1 downto 0 do
            if Length(Trim(TAssocAction(ActionList[j]).ActionCommand)) = 0 then begin
              TAssocAction(ActionList[j]).Free;
              ActionList.Delete(j);
              if DefaultAction = j then DefaultAction := 0;
              if DefaultAction > j then Dec(DefaultAction);
            end; }
        if DefaultAction > ActionList.Count - 1 then DefaultAction := 0;
      end;
  except end;
end;

(********************************************************************************************************************************)
procedure TFFileTypeSettings.AddFiletypeButtonClick(Sender: TObject);
var Item: TFileAssoc;
    ListItem: TGTKListItem;
begin
  Notebook.PageIndex := 0;
  Item := TFileAssoc.Create;
  IntAssocList.Add(Item);
  ListItem := ListView.Items.Add;
  ListItem.SetValue(2, Item);
  ListItem.Selected := True;
  ListItem.SetCursor(0, False, not Application.GTKVersion_2_2_0_Up, 0.5, 0);
  ListViewSelectionChanged(Self);
  AssocDescriptionEntry.SetFocus;
end;

procedure TFFileTypeSettings.RemoveFiletypeButtonClick(Sender: TObject);
var Item: TFileAssoc;
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) then begin
    Item := ListView.Selected.AsPointer(2);
    Item.Free;
    IntAssocList.Remove(Item);
    ListView.Items.Delete(ListView.Selected.Index);
  end;
end;

procedure TFFileTypeSettings.ListViewSelectionChanged(Sender: TObject);
var b: boolean;
    Item: TFileAssoc;
    i: integer;
    ListItem: TGTKListItem;
    Color: TGDKColor;
begin
  b := Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2));
  RemoveFiletypeButton.Enabled := b and (TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName <> ConstFTAMetaDirectory) and
                                        (TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName <> ConstFTAMetaFile);
  AssocDescriptionEntry.Enabled := RemoveFiletypeButton.Enabled;
  FNameExtEntry.Enabled := RemoveFiletypeButton.Enabled;
  FNameExtListView.Enabled := RemoveFiletypeButton.Enabled;
  AddExtButton.Enabled := RemoveFiletypeButton.Enabled;
  RemoveExtButton.Enabled := RemoveFiletypeButton.Enabled;
  FNameExtLabel.Enabled := RemoveFiletypeButton.Enabled;
  ColorButton.Enabled := RemoveFiletypeButton.Enabled;
  DefaultColorCheckBox.Enabled := RemoveFiletypeButton.Enabled;
  ColorLabel.Enabled := RemoveFiletypeButton.Enabled;
  FNameExtVBox3.Enabled := b;
  ActionsVBox.Enabled := b;
  if not b then begin
    //  Visually clean all the fields
    DescriptionEntry.Text := '';
    CommandEntry.Text := '';
    AssocDescriptionEntry.Text := '';
    FNameExtListView.Items.Clear;
    FNameExtEntry.Text := '';
    IconEntry.Text := '';
    ActionsListView.Items.Clear;
    ColorButton.SetDefaultColor;
    ColorButton.Color := PGdkColorToGDKColor(GetDefaultBackgroundColor(0)); 
    DefaultColorCheckBox.Checked := True;
    Exit;
  end;
  Item := ListView.Selected.AsPointer(2);
  FNameExtListView.Items.Clear;
  if Length(Item.Extensions) > 0 then
    for i := 0 to Length(Item.Extensions) - 1 do
      FNameExtListView.Items.Add.SetValue(0, Item.Extensions[i]);
  IconEntry.Text := Item.FileTypeIcon;
  IconEntryChanged(Self);
  if (TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName = ConstFTAMetaDirectory) or
     (TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName = ConstFTAMetaFile)
    then AssocDescriptionEntry.Text := ListView.Selected.AsString(0)
    else AssocDescriptionEntry.Text := ListView.Selected.AsString(1);
  DefaultColorCheckBox.Checked := not StringToGDKColor(Item.ColorString, Color);
  if DefaultColorCheckBox.Checked then ColorButton.SetDefaultColor
  else begin
         ColorButton.UnsetDefaultColor;
         ColorButton.Color := Color;
       end;
  //  Actions
  ActionsListView.Items.Clear;
  if Item.ActionList.Count > 0 then
    for i := 0 to Item.ActionList.Count - 1 do
      with TAssocAction(Item.ActionList[i]) do begin
        ListItem := ActionsListView.Items.Add;
        if Item.DefaultAction = i
          then begin
            ListItem.SetValue(0, ActionName + LANGDefault);
            ListItem.SetValue(1, ActionCommand);
          end else begin
            ListItem.SetValue(0, ActionName);
            ListItem.SetValue(1, ActionCommand);
          end;
        ListItem.SetValue(2, Item.ActionList[i]);
      end;
  if ActionsListView.Items.Count > 0 then ActionsListView.Items[0].Selected := True; 
  ActionsListViewSelectionChanged(Sender);
end;

procedure TFFileTypeSettings.AddExtButtonClick(Sender: TObject);
var i: integer;
    sx: string;
    Assoc: TFileAssoc;
begin
  if Length(Trim(FNameExtEntry.Text)) = 0 then Exit;
  if FNameExtListView.Items.Count > 0 then
    for i := 0 to FNameExtListView.Items.Count - 1 do
      if WideUpperCase(FNameExtListView.Items[i].AsString(0)) = WideUpperCase(Trim(FNameExtEntry.Text)) then Exit;
  sx := WideLowerCase(Trim(FNameExtEntry.Text));
  if sx[1] = '.' then Delete(sx, 1, 1);
  FNameExtListView.Items.Add.SetValue(0, sx);

  Assoc := TFileAssoc(ListView.Selected.AsPointer(2));
  SetLength(Assoc.Extensions, Length(Assoc.Extensions) + 1);
  Assoc.Extensions[Length(Assoc.Extensions) - 1] := sx;
  ListView.Selected.SetValue(0, MakeString(';', Assoc.Extensions));

  FNameExtEntry.Text := '';
end;

procedure TFFileTypeSettings.RemoveExtButtonClick(Sender: TObject);
var i: integer;
    Assoc: TFileAssoc;
begin
  try
    if (FNameExtListView.Items.Count = 0) or (not Assigned(FNameExtListView.Selected)) or
       (not Assigned(ListView.Selected)) or (not Assigned(ListView.Selected.AsPointer(2))) then Exit;
    Assoc := TFileAssoc(ListView.Selected.AsPointer(2));
    if Length(Assoc.Extensions) > 0 then
      for i := Length(Assoc.Extensions) - 1 downto 0 do
        if Assoc.Extensions[i] = FNameExtListView.Selected.AsString(0) then
          DeleteFromArray(i, Assoc.Extensions);
    ListView.Selected.SetValue(0, MakeString(';', Assoc.Extensions));
    FNameExtListView.Items.Delete(FNameExtListView.Selected.Index);
  except
  end;
end;

procedure TFFileTypeSettings.FNameExtEntryKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
begin
  if (Key = GDK_RETURN) or (Key = GDK_KP_ENTER) then AddExtButtonClick(Sender);
end;

procedure TFFileTypeSettings.FNameExtListViewSelectionChanged(Sender: TObject);
begin
  RemoveExtButton.Enabled := (FNameExtListView.Items.Count > 0) and Assigned(FNameExtListView.Selected);
end;

procedure TFFileTypeSettings.AssocDescriptionEntryChanged(Sender: TObject);
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) and
     (TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName <> ConstFTAMetaDirectory) and
     (TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName <> ConstFTAMetaFile) then 
  begin
    TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName := AssocDescriptionEntry.Text;
    ListView.Selected.SetValue(1, AssocDescriptionEntry.Text);
  end;
end;

procedure TFFileTypeSettings.ActionsListViewSelectionChanged(Sender: TObject);
var b: boolean;
    Action: TAssocAction;
begin
  b := (ActionsListView.Items.Count > 0) and Assigned(ActionsListView.Selected) and Assigned(ActionsListView.Selected.AsPointer(2));
  RemoveActionButton.Enabled := b;
  SetDefaultActionButton.Enabled := b;
  Table.Enabled := b;
  BrowseButton.Enabled := b;
  RunInTerminalCheckBox.Enabled := b;
  AutodetectCheckBox.Enabled := b;
  if not b then begin
    //  Visually clean all the fields
    DescriptionEntry.Text := '';
    CommandEntry.Text := '';
    Exit;
  end;
  Action := ActionsListView.Selected.AsPointer(2);
  DescriptionEntry.Text := Action.ActionName;
  CommandEntry.Text := Action.ActionCommand;
  RunInTerminalCheckBox.Checked := Action.RunInTerminal;
  AutodetectCheckBox.Checked := Action.AutodetectGUI;
  RunInTerminalCheckBox.Enabled := not AutodetectCheckBox.Checked;
end;

procedure TFFileTypeSettings.AddActionButtonClick(Sender: TObject);
var Action: TAssocAction;
    ListItem: TGTKListItem;
begin
  if (not Assigned(ListView.Selected)) or (not Assigned(ListView.Selected.AsPointer(2))) then Exit;
  Action := TAssocAction.Create;
  TFileAssoc(ListView.Selected.AsPointer(2)).ActionList.Add(Action);
  ListItem := ActionsListView.Items.Add;
  ListItem.SetValue(2, Action);
  ListItem.Selected := True;
  ActionsListViewSelectionChanged(Self);
  DescriptionEntry.SetFocus;
end;

procedure TFFileTypeSettings.RemoveActionButtonClick(Sender: TObject);
var Action: TAssocAction;
    Item: TFileAssoc;
begin
  try
  if (ActionsListView.Items.Count = 0) or (not Assigned(ActionsListView.Selected)) or
     (not Assigned(ListView.Selected)) or (not Assigned(ListView.Selected.AsPointer(2))) then Exit;
  Item := ListView.Selected.AsPointer(2);
  Action := ActionsListView.Selected.AsPointer(2);
  if (Item.DefaultAction > Item.ActionList.Count - 1) or (Item.ActionList[Item.DefaultAction] = Action)
    then Item.DefaultAction := 0;
  if Item.DefaultAction > ActionsListView.Selected.Index then Dec(Item.DefaultAction);  
  Action.Free;
  Item.ActionList.Remove(Action);
  ActionsListView.Items.Delete(ActionsListView.Selected.Index);
  ListViewSelectionChanged(Sender);
  except end;
end;

procedure TFFileTypeSettings.DescriptionEntryChanged(Sender: TObject);
var Item: TFileAssoc;
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) and
     Assigned(ActionsListView.Selected) and Assigned(ActionsListView.Selected.AsPointer(2)) then
  begin
    TAssocAction(ActionsListView.Selected.AsPointer(2)).ActionName := DescriptionEntry.Text;
    Item := ListView.Selected.AsPointer(2);
    if (Item.ActionList.Count - 1 >= Item.DefaultAction) and (ActionsListView.Selected.AsPointer(2) = Item.ActionList[Item.DefaultAction])
      then ActionsListView.Selected.SetValue(0, DescriptionEntry.Text + LANGDefault)    
      else ActionsListView.Selected.SetValue(0, DescriptionEntry.Text);
  end;
end;

procedure TFFileTypeSettings.CommandEntryChanged(Sender: TObject);
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) and
     Assigned(ActionsListView.Selected) and Assigned(ActionsListView.Selected.AsPointer(2)) then
  begin
    TAssocAction(ActionsListView.Selected.AsPointer(2)).ActionCommand := CommandEntry.Text;
    ActionsListView.Selected.SetValue(1, CommandEntry.Text);
  end;
end;

procedure TFFileTypeSettings.RunInTerminalCheckBoxToggled(Sender: TObject);
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) and
     Assigned(ActionsListView.Selected) and Assigned(ActionsListView.Selected.AsPointer(2))
    then TAssocAction(ActionsListView.Selected.AsPointer(2)).RunInTerminal := RunInTerminalCheckBox.Checked;
end;

procedure TFFileTypeSettings.AutodetectCheckBoxToggled(Sender: TObject);
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) and
     Assigned(ActionsListView.Selected) and Assigned(ActionsListView.Selected.AsPointer(2)) then
  begin
    TAssocAction(ActionsListView.Selected.AsPointer(2)).AutodetectGUI := AutodetectCheckBox.Checked;
    RunInTerminalCheckBox.Enabled := not AutodetectCheckBox.Checked;
  end;
end;

procedure TFFileTypeSettings.SetDefaultActionButtonClick(Sender: TObject);
var SelIdx: integer;
begin
  if (ActionsListView.Items.Count = 0) or (not Assigned(ActionsListView.Selected)) or
     (not Assigned(ListView.Selected)) or (not Assigned(ListView.Selected.AsPointer(2))) then Exit;
  SelIdx := ActionsListView.Selected.Index;
  TFileAssoc(ListView.Selected.AsPointer(2)).DefaultAction := SelIdx;
  ListViewSelectionChanged(Sender);
  ActionsListView.Items[SelIdx].Selected := True;
end;

procedure TFFileTypeSettings.BrowseButtonClick(Sender: TObject);
var Dialog: TGTKFileSelectionDialog;
begin
  if (ActionsListView.Items.Count = 0) or (not Assigned(ActionsListView.Selected)) or
     (not Assigned(ListView.Selected)) or (not Assigned(ListView.Selected.AsPointer(2))) then Exit;
  Dialog := TGTKFileSelectionDialog.Create(Self);
  try
    Dialog.ShowFileOpButtons := False;
    Dialog.FileName := AppPath;
    if Byte(Dialog.Run) = 251 then CommandEntry.Text := Dialog.FileName;
    AppPath := IncludeTrailingPathDelimiter(ExtractFilePath(Dialog.FileName));
  finally
    Dialog.Free;
  end;
end;

(********************************************************************************************************************************)
procedure TFFileTypeSettings.IconEntryChanged(Sender: TObject);
var Pixmap, DefIcon: TGDKPixbuf;
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) then begin
    if TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeName = ConstFTAMetaDirectory
      then DefIcon := FolderIconCached
      else DefIcon := FileIconCached;
    TFileAssoc(ListView.Selected.AsPointer(2)).FileTypeIcon := IconEntry.Text;
    if not FileExists(IconEntry.Text) then Icon.CopyFromPixbuf(DefIcon) else
    begin
      Pixmap := TGDKPixbuf.Create(Self);
      Pixmap.LoadFromFile(IconEntry.Text);
      if Pixmap.FPixbuf <> nil then begin
        Pixmap.ScaleSimple(ConfRowHeightReal, ConfRowHeightReal);
        Icon.SetFromPixbuf(Pixmap);
      end else Icon.CopyFromPixbuf(DefIcon);
      Pixmap.FPixbuf := nil;
      Pixmap.Free;
    end;
    ListView.Selected.SetValue(3, Icon.GetPixbuf);
    if FUseGnomeIconEntry then
      if FileExists(IconEntry.Text) then GnomeIconButton.Filename := IconEntry.Text
                                    else GnomeIconButton.Filename := '';
  end;
end;

procedure TFFileTypeSettings.BrowseIconButtonClick(Sender: TObject);
var Dialog: TGTKFileSelectionDialog;
begin
  if (not Assigned(ListView.Selected)) or (not Assigned(ListView.Selected.AsPointer(2))) then Exit;
  Dialog := TGTKFileSelectionDialog.CreateWithTitle(Self, LANGBrowseForIcon);
  try
    Dialog.ShowFileOpButtons := False;
    if FileExists(IconEntry.Text) then Dialog.FileName := IconEntry.Text
                                  else Dialog.FileName := IconPath;
    if Byte(Dialog.Run) = 251 then IconEntry.Text := Dialog.FileName;
    IconPath := IncludeTrailingPathDelimiter(ExtractFilePath(Dialog.FileName));
  finally
    Dialog.Free;
  end;
end;

procedure TFFileTypeSettings.ColorButtonColorChanged(Sender: TObject);
begin
  if Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2)) then
    TFileAssoc(ListView.Selected.AsPointer(2)).ColorString := GDKColorToString(ColorButton.Color);
end;

procedure TFFileTypeSettings.DefaultColorCheckBoxToggled(Sender: TObject);
begin
  if DefaultColorCheckBox.Checked then ColorButton.SetDefaultColor
                                  else ColorButton.UnsetDefaultColor;
  if DefaultColorCheckBox.Checked and Assigned(ListView.Selected) and Assigned(ListView.Selected.AsPointer(2))
    then TFileAssoc(ListView.Selected.AsPointer(2)).ColorString := '';
end;


(********************************************************************************************************************************)
(********************************************************************************************************************************)
procedure TFFileTypeSettings.ListViewCellDataFunc(Sender: TObject; tree_view: PGtkTreeView; tree_column : PGtkTreeViewColumn; cell : PGtkCellRenderer; tree_model : PGtkTreeModel; iter : PGtkTreeIter);
var ColumnID: integer;
    ImageCol: boolean;
    Data: TFileAssoc;
    s: Pointer;
begin
  if not Application.GTKVersion_2_0_5_Up then Exit;
  ColumnID := gtk_tree_view_column_get_sort_column_id(tree_column);
  ImageCol := False;
  if ColumnID = 0 then ImageCol := GTK_IS_CELL_RENDERER_PIXBUF(cell);
  if ImageCol then Exit;
  Data := nil;
  gtk_tree_model_get(tree_model, iter, 2, @Data, -1);
  gtk_tree_model_get(tree_model, iter, ColumnID, @s, -1);

  if Assigned(Data) and (Data is TFileAssoc) and ((Data.FileTypeName = ConstFTAMetaDirectory) or (Data.FileTypeName = ConstFTAMetaFile))
    then
      case ColumnID of
        0: g_object_set(cell, 'markup', g_strconcat('<span weight="bold" underline="single">', s, '</span>', nil), nil);
        1: g_object_set(cell, 'markup', g_strconcat('<span style="italic">', s, '</span>', nil), nil);
      end
    else g_object_set(cell, 'markup', s, nil);
end;


procedure TFFileTypeSettings.ActionsListViewCellDataFunc(Sender: TObject; tree_view: PGtkTreeView; tree_column : PGtkTreeViewColumn; cell : PGtkCellRenderer; tree_model : PGtkTreeModel; iter : PGtkTreeIter);
var ColumnID: integer;
    ImageCol: boolean;
    Data: TAssocAction;
    s: Pointer;
    Item: TFileAssoc;
begin
  if not Application.GTKVersion_2_0_5_Up then Exit;
  ColumnID := gtk_tree_view_column_get_sort_column_id(tree_column);
  ImageCol := False;
  if ColumnID = 0 then ImageCol := GTK_IS_CELL_RENDERER_PIXBUF(cell);
  if ImageCol then Exit;
  Item := ListView.Selected.AsPointer(2);
  if Item = nil then Exit;
  Data := nil;
  gtk_tree_model_get(tree_model, iter, 2, @Data, -1);
  gtk_tree_model_get(tree_model, iter, ColumnID, @s, -1);

  if Assigned(Data) and (Data is TAssocAction) and (Item.ActionList.IndexOf(Data) = Item.DefaultAction)
    then g_object_set(cell, 'markup', g_strconcat('<span weight="bold">', s, '</span>', nil), nil)
    else g_object_set(cell, 'markup', s, nil);
end;

(********************************************************************************************************************************)
procedure TFFileTypeSettings.GnomeIconButtonIconChanged(Sender: TObject);
begin
  IconEntry.Text := GnomeIconButton.Filename;
end;




end.

