unit _TemplateFileList;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, _TemplateFile, StdCtrls, ExtCtrls, Menus, Buttons,
  ComCtrls, TypeDefs, VirtualTrees;

type
  TForm_TemplateFileList = class(TForm_TemplateFile)
    panel_files: TPanel;
    splitter_content: TSplitter;
    panel_content: TPanel;
    filepopup: TPopupMenu;
    popup_separator2: TMenuItem;
    popup_linkshere: TMenuItem;
    popup_separator: TMenuItem;
    popup_import: TMenuItem;
    popup_export: TMenuItem;
    importd: TOpenDialog;
    exportd: TSaveDialog;
    FilePages: TPageControl;
    tab_files: TTabSheet;
    panel_extension: TPanel;
    label_sort2: TLabel;
    label_sort1: TLabel;
    label_extension: TLabel;
    btn_sort_id_asc: TSpeedButton;
    btn_sort_id_desc: TSpeedButton;
    btn_sort_name_asc: TSpeedButton;
    btn_sort_name_desc: TSpeedButton;
    btn_sort_ext_asc: TSpeedButton;
    btn_sort_ext_desc: TSpeedButton;
    combo_extension: TComboBox;
    check_zerobyte: TCheckBox;
    edit_filtername: TEdit;
    check_filtername: TCheckBox;
    filelist: TListBox;
    tab_meta: TTabSheet;
    filelist_meta: TVirtualStringTree;
    procedure NewCon(ID: Integer);

    procedure check_filternameClick(Sender: TObject);
    procedure check_zerobyteClick(Sender: TObject);
    procedure combo_extensionClick(Sender: TObject);
    procedure btn_sortClick(Sender: TObject);
    procedure listClick(Sender: TObject);
    procedure listMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);

    procedure popup_importClick(Sender: TObject);
    procedure popup_exportClick(Sender: TObject);
    procedure popup_opentool(Sender: TObject);
    procedure popup_linkshereClick(Sender: TObject);
    procedure filepopupPopup(Sender: TObject);
  private
    FSortBy: TSortType;
    FAllowedExts: String;
    FAllowMultiSelect: Boolean;
    procedure SetAllowedExts(exts: String);
    procedure SetMultiSelect(allow: Boolean);
  public
    constructor Create(AOwner: TComponent); override;
    procedure RecreateExtList;
    procedure LoadFileNames;
    procedure SetFileFilters(pattern, extension: String; zerobytes: Boolean);
    property AllowedExts: String read FAllowedExts write SetAllowedExts;
    property AllowMultiSelect: Boolean read FAllowMultiSelect write SetMultiSelect;
  end;

implementation
{$R *.dfm}
uses ConnectionManager, Exporters, Functions, StrUtils, WhatLinksHere, Main,
  _BaseTemplate;


procedure TForm_TemplateFileList.RecreateExtList;
var
  i:    Integer;
  exts: TStrings;
begin
  combo_extension.Items.Clear;
  if FConnectionID > -1 then
  begin
    combo_extension.Items.Add('_All files_ (' +
      IntToStr(ConManager.Connection[FConnectionID].GetFileCount) + ')');
    exts := nil;
    exts := ConManager.Connection[FConnectionID].GetExtensionsList(EF_ExtCount);
    for i := 0 to exts.Count - 1 do
      if Length(FAllowedExts) > 0 then
      begin
        if Pos(MidStr(exts.Strings[i],1,4), FAllowedExts) > 0 then
          combo_extension.Items.Add(exts.Strings[i]);
      end
      else
        combo_extension.Items.Add(exts.Strings[i]);
    combo_extension.ItemIndex := 0;
    combo_extensionClick(Self);
    exts.Free;
  end;
end;

procedure TForm_TemplateFileList.LoadFileNames;
var
  Extension: String;
  no_zero_bytes: Boolean;
  pattern: String;
  files: TStrings;
begin
  if FConnectionID > -1 then
  begin
    Extension := MidStr(combo_extension.Items.Strings[combo_extension.ItemIndex], 1, 4);
    no_zero_bytes := not check_zerobyte.Checked;
    pattern := '';
    if check_filtername.Checked then
      pattern := edit_filtername.Text;
    if Extension = '_All' then
      if Length(FAllowedExts) > 0 then
        Extension := FAllowedExts
      else
        Extension := '';

    files := nil;
    files := ConManager.Connection[FConnectionID].GetFilesList(extension, pattern, no_zero_bytes, FSortBy);

    filelist.Visible := False;
    filelist.Items.Clear;
    if files.Count > 0 then
      filelist.Items.AddStrings(files);
    filelist.Visible := True;
  end;
end;


procedure TForm_TemplateFileList.NewCon(ID: Integer);
begin
  RecreateExtList;
end;

procedure TForm_TemplateFileList.popup_exportClick(Sender: TObject);
var
  id: Integer;
  ext: String;
begin
  id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
  exportd.Filter := 'Files of matching extension (*.' + ext + ')|*.' + ext + '|All files|*.*';
  exportd.DefaultExt := ext;
  if exportd.Execute then
    ExportDatFile(FConnectionID, id, exportd.FileName);
end;

procedure TForm_TemplateFileList.popup_importClick(Sender: TObject);
var
  id: Integer;
  finfo: TFileInfo;
  fs: TFileStream;
begin
  if CR_EditDat in ConManager.Connection[FConnectionID].ChangeRights then
  begin
    id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
    finfo := ConManager.Connection[FConnectionID].GetFileInfo(id);

    importd.Filter := 'Files of matching extension (*.' + finfo.Extension + ')|*.' +
          finfo.Extension + '|All files|*.*';
    if importd.Execute then
    begin
      fs := TFileStream.Create(importd.FileName, fmOpenRead);
      if fs.Size <> finfo.Size then
      begin
        if not (CR_ResizeDat in ConManager.Connection[FConnectionID].ChangeRights) then
        begin
          ShowMessage('Can''t import ' + ExtractFilename(importd.FileName) +
            ', file has to have same size as file in .dat with this backend.' + CrLf +
            'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
            'Size of chosen file: ' + FormatFileSize(fs.Size));
          Exit;
        end else begin
          if MessageBox(Self.Handle,
              PChar('File has different size from the file in the .dat.' + CrLf +
                    'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
                    'Size of chosen file: ' + FormatFileSize(fs.Size) + CrLf +
                    'Replace anyway?'), PChar('Different size'), MB_YESNO + MB_ICONWARNING) = ID_NO then
          begin
            Exit;
          end;
        end;
      end;
      ConManager.Connection[FConnectionID].UpdateDatFile(id, fs);
      Self.listClick(Self);
      fs.Free;
    end;
  end else begin
    ShowMessage('Editing .dat-contents not allowed with this backend.');
  end;
end;


procedure TForm_TemplateFileList.popup_linkshereClick(Sender: TObject);
begin
  Form_WhatLinksHere.ConID := FConnectionID;
  Form_WhatLinksHere.FileID := FSelectedFile.ID;
  Form_WhatLinksHere.SenderForm := Self;
  Form_WhatLinksHere.Show;
end;

procedure TForm_TemplateFileList.popup_opentool(Sender: TObject);
var
  sender_name, context: String;
  id: Integer;
begin
  sender_name := TComponent(Sender).Name;
  id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
  context := MidStr(sender_name, Pos('_', sender_name) + 1, Length(sender_name) - Pos('_', sender_name));
  Form_Main.open_child(context, FConnectionID, id);
end;

procedure TForm_TemplateFileList.filepopupPopup(Sender: TObject);
var
  ext: String;
  i: Integer;
begin
  ext := RightStr(filelist.Items.Strings[filelist.ItemIndex], 4);
  for i := 0 to High(ToolList) do
  begin
    filepopup.Items.Items[i].Enabled := True;
    if Length(ToolList[i].exts) > 0 then
      if Pos(ext, ToolList[i].exts) = 0 then
        filepopup.Items.Items[i].Enabled := False;
  end;
end;


procedure TForm_TemplateFileList.check_zerobyteClick(Sender: TObject);
begin
  LoadFileNames;
end;

procedure TForm_TemplateFileList.btn_sortClick(Sender: TObject);
begin
  if btn_sort_id_asc.Down then
    FSortBy := ST_IDAsc
  else if btn_sort_id_desc.Down then
    FSortBy := ST_IDDesc
  else if btn_sort_name_asc.Down then
    FSortBy := ST_NameAsc
  else if btn_sort_name_desc.Down then
    FSortBy := ST_NameDesc
  else if btn_sort_ext_asc.Down then
    FSortBy := ST_ExtAsc
  else if btn_sort_ext_desc.Down then
    FSortBy := ST_ExtDesc;
  LoadFileNames;
end;

procedure TForm_TemplateFileList.check_filternameClick(Sender: TObject);
begin
  edit_filtername.Enabled := not check_filtername.Checked;
  LoadFileNames;
end;

procedure TForm_TemplateFileList.combo_extensionClick(Sender: TObject);
begin
  LoadFileNames;
end;

procedure TForm_TemplateFileList.listClick(Sender: TObject);
var
  fileid: Integer;
begin
  if filelist.ItemIndex > -1 then
  begin
    fileid := ConManager.Connection[FConnectionID].ExtractFileIDOfName(
          filelist.Items.Strings[filelist.ItemIndex]);
    FSelectedFile := ConManager.Connection[FConnectionID].GetFileInfo(fileid);
    if Assigned(FOnNewFileSelected) then
      FOnNewFileSelected(FSelectedFile);
  end;
end;

procedure TForm_TemplateFileList.listMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  pt: TPoint;
begin
  pt.X := x;
  pt.Y := y;
  if Shift = [ssRight] then
  begin
    filelist.ItemIndex := filelist.ItemAtPos(pt, true);
    Self.listClick(Self);
  end;
end;



procedure TForm_TemplateFileList.SetAllowedExts(exts: String);
begin
  FAllowedExts := exts;
  RecreateExtList;
end;

procedure TForm_TemplateFileList.SetFileFilters(pattern, extension: String;
  zerobytes: Boolean);
var
  i: Integer;
begin
  if Length(pattern) > 0 then
    Self.edit_filtername.Text := pattern;
  Self.check_filtername.Checked := Length(pattern) > 0;
  if Length(extension) > 0 then
  begin
    for i := 0 to Self.combo_extension.Items.Count - 1 do
      if Pos(extension, Self.combo_extension.Items.Strings[i]) > 0 then
        Break;
    if i < Self.combo_extension.Items.Count then
      Self.combo_extension.ItemIndex := i
    else
      Self.combo_extension.ItemIndex := -1;
  end;
  Self.check_zerobyte.Checked := zerobytes;
  Self.LoadFileNames;
end;

procedure TForm_TemplateFileList.SetMultiSelect(allow: Boolean);
begin
  FAllowMultiSelect := allow;
  filelist.MultiSelect := allow;
end;



constructor TForm_TemplateFileList.Create(AOwner: TComponent);
var
  i: Integer;
  item: TMenuItem;
begin
  inherited;
  FAllowedExts := '';
  FAllowMultiSelect := False;
  FOnNewConnection := NewCon;
  UpdateConList;
  if Length(ToolList) > 0 then
  begin
    for i := 0 to High(ToolList) do
    begin
      item := TMenuItem.Create(filepopup);
      item.Name := 'popup_' + ToolList[i].context;
      item.Caption := 'Open with ' + ToolList[i].name;
      item.OnClick := Self.popup_opentool;
      filepopup.Items.Insert(i, item);
    end;
  end;
end;


end.
