unit Template; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, StrUtils, Data, TypeDefs, Menus, Buttons; type TNewFileSelectedEvent = procedure(FileInfo: TFileInfo) of object; TNewConnectionEvent = procedure(Connection: Integer) of object; TCheckCloseableEvent = function: Boolean of object; TForm_ToolTemplate = class(TForm) panel_files: TPanel; filelist: TListBox; panel_extension: TPanel; label_ext: TLabel; combo_extension: TComboBox; check_zerobyte: TCheckBox; edit_filtername: TEdit; check_filtername: TCheckBox; Splitter1: TSplitter; content: TPanel; filepopup: TPopupMenu; popup_import: TMenuItem; popup_export: TMenuItem; popup_separator: TMenuItem; importd: TOpenDialog; exportd: TSaveDialog; 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; Label1: TLabel; Label2: TLabel; Label3: TLabel; combo_connection: TComboBox; Bevel1: TBevel; popup_linkshere: TMenuItem; popup_separator2: TMenuItem; procedure RecreateExtList; procedure UpdateConList; procedure LoadFileNames; procedure SelectFileName(ConnectionID: Integer; FileName: String); procedure SelectFileID(ConnectionID, FileID: Integer); procedure SelectConnection(ConnectionID: Integer); procedure check_filternameClick(Sender: TObject); procedure check_zerobyteClick(Sender: TObject); procedure combo_extensionClick(Sender: TObject); procedure listClick(Sender: TObject); procedure listMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure popup_importClick(Sender: TObject); procedure popup_exportClick(Sender: TObject); procedure popup_opentool(Sender: TObject); procedure filepopupPopup(Sender: TObject); procedure btn_sortClick(Sender: TObject); procedure FormActivate(Sender: TObject); procedure combo_connectionChange(Sender: TObject); procedure popup_linkshereClick(Sender: TObject); private FSortBy: TSortType; FOnNewFileSelected: TNewFileSelectedEvent; FOnNewConnection: TNewConnectionEvent; FOnCheckCloseable: TCheckCloseableEvent; FAllowedExts: String; FAllowMultiSelect: Boolean; FSelectedFile: TFileInfo; FConnectionID: Integer; procedure SetAllowedExts(exts: String); procedure SetMultiSelect(allow: Boolean); function GetToolCloseable: Boolean; public constructor Create(AOwner: TComponent); override; procedure SetFileFilters(pattern, extension: String; zerobytes: Boolean); published property OnNewFileSelected: TNewFileSelectedEvent read FOnNewFileSelected write FOnNewFileSelected; property OnNewConnection: TNewConnectionEvent read FOnNewConnection write FOnNewConnection; property OnCheckCloseable: TCheckCloseableEvent read FOnCheckCloseable write FOnCheckCloseable; property AllowedExts: String read FAllowedExts write SetAllowedExts; property AllowMultiSelect: Boolean read FAllowMultiSelect write SetMultiSelect; property SelectedFile: TFileInfo read FSelectedFile; property ConnectionID: Integer read FConnectionID; property Closeable: Boolean read GetToolCloseable; end; var ToolList: TToolList; procedure AddToolListEntry(context, name, exts: String); implementation {$R *.dfm} uses Main, ConnectionManager, Exporters, Functions, WhatLinksHere; procedure TForm_ToolTemplate.UpdateConList; var i: Integer; fn, datatype, boxstring: String; level: Integer; begin combo_connection.ItemIndex := -1; combo_connection.Items.Clear; if ConManager.Count > 0 then begin for i := 0 to ConManager.Count - 1 do begin level := ConManager.ConnectionByIndex[i].LevelNumber; fn := ExtractFileName(ConManager.ConnectionByIndex[i].FileName); if ConManager.ConnectionByIndex[i].Backend = DB_ONI then datatype := 'ONI-.dat: ' else if ConManager.ConnectionByIndex[i].Backend = DB_ADB then datatype := 'OUP-DB: ' else datatype := 'Unknown: '; boxstring := datatype + fn + ' (Level: ' + IntToStr(level) + ') [' + IntToStr(ConManager.ConnectionByIndex[i].ConnectionID) + ']'; combo_connection.Items.Add(boxstring); if ConManager.ConnectionByIndex[i].ConnectionID = FConnectionID then combo_connection.ItemIndex := combo_connection.Items.Count - 1; end; if combo_connection.ItemIndex = -1 then begin combo_connection.ItemIndex := 0; combo_connectionChange(Self); end; end else begin FConnectionID := 0; filelist.Items.Clear; combo_extension.Items.Clear; combo_connectionChange(Self); FSelectedFile.ID := -1; if Assigned(FOnNewFileSelected) then FOnNewFileSelected(FSelectedFile); end; end; procedure TForm_ToolTemplate.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_ToolTemplate.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_ToolTemplate.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_ToolTemplate.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_ToolTemplate.popup_linkshereClick(Sender: TObject); begin Form_WhatLinksHere.ConID := FConnectionID; Form_WhatLinksHere.FileID := FSelectedFile.ID; Form_WhatLinksHere.SenderForm := Self; Form_WhatLinksHere.Show; end; procedure TForm_ToolTemplate.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_ToolTemplate.combo_connectionChange(Sender: TObject); var name: String; begin if combo_connection.ItemIndex >= 0 then begin name := combo_connection.Items.Strings[combo_connection.ItemIndex]; FConnectionID := StrToInt(MidStr(name, Pos('[', name) + 1, Pos(']', name) - Pos('[', name) - 1)); end else FConnectionID := -1; RecreateExtList; if Assigned(FOnNewConnection) then FOnNewConnection(FConnectionID); end; procedure TForm_ToolTemplate.combo_extensionClick(Sender: TObject); begin LoadFileNames; end; constructor TForm_ToolTemplate.Create(AOwner: TComponent); var i: Integer; item: TMenuItem; begin inherited; Self.Width := 260; Self.Height := 300; FAllowedExts := ''; FAllowMultiSelect := False; FOnNewFileSelected := nil; FOnNewConnection := nil; FOnCheckCloseable := nil; FConnectionID := -1; FSelectedFile.ID := -1; 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; procedure TForm_ToolTemplate.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; filepopup.Items.Find('What links here?').Enabled := ConManager.Connection[FConnectionID].Backend = DB_ADB; end; procedure TForm_ToolTemplate.check_zerobyteClick(Sender: TObject); begin LoadFileNames; end; procedure TForm_ToolTemplate.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_ToolTemplate.check_filternameClick(Sender: TObject); begin edit_filtername.Enabled := not check_filtername.Checked; LoadFileNames; end; procedure TForm_ToolTemplate.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_ToolTemplate.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_ToolTemplate.SelectConnection(ConnectionID: Integer); begin if FConnectionID <> ConnectionID then begin combo_connection.ItemIndex := ConManager.ConnectionIndexByID[ConnectionID]; combo_connectionChange(Self); end; end; procedure TForm_ToolTemplate.SelectFileID(ConnectionID, FileID: Integer); var i: Integer; begin if FConnectionID <> ConnectionID then SelectConnection(ConnectionID); filelist.ItemIndex := -1; if filelist.Items.Count > 0 then for i := 0 to filelist.Items.Count - 1 do if ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[i]) = FileID then begin filelist.ItemIndex := i; Break; end; Self.listClick(Self); end; procedure TForm_ToolTemplate.SelectFileName(ConnectionID: Integer; filename: String); var i: Integer; begin if FConnectionID <> ConnectionID then SelectConnection(ConnectionID); filelist.ItemIndex := -1; if filelist.Items.Count > 0 then for i := 0 to filelist.Items.Count - 1 do if filelist.Items.Strings[i] = filename then filelist.ItemIndex := i; Self.listClick(Self); end; procedure TForm_ToolTemplate.SetAllowedExts(exts: String); begin FAllowedExts := exts; RecreateExtList; end; procedure TForm_ToolTemplate.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_ToolTemplate.SetMultiSelect(allow: Boolean); begin FAllowMultiSelect := allow; filelist.MultiSelect := allow; end; function TForm_ToolTemplate.GetToolCloseable: Boolean; begin if Assigned(FOnCheckCloseable) then Result := FOnCheckCloseable else Result := True; end; procedure TForm_ToolTemplate.FormActivate(Sender: TObject); begin if edit_filtername.CanFocus then edit_filtername.SetFocus else if content.CanFocus then content.SetFocus; end; procedure TForm_ToolTemplate.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; procedure AddToolListEntryExt(context, ext: String); var i: Integer; begin for i := 0 to High(ToolList) do if ToolList[i].context = context then begin if Pos(ext, ToolList[i].exts) = 0 then begin if Length(ToolList[i].exts) = 0 then ToolList[i].exts := ext else ToolList[i].exts := ToolList[i].exts + ',' + ext; end; Exit; end; end; procedure AddToolListEntry(context, name, exts: String); var i: Integer; begin if Length(ToolList) > 0 then begin for i := 0 to High(ToolList) do if ToolList[i].context = context then begin if (Length(ToolList[i].name) = 0) and (Length(name) > 0) then ToolList[i].name := name; if Length(exts) > 0 then AddToolListEntryExt(context, exts); Exit; end; end; SetLength(ToolList, Length(ToolList) + 1); for i := High(ToolList) downto 1 do if ToolList[i - 1].name > name then ToolList[i] := ToolList[i - 1] else Break; ToolList[i].context := context; ToolList[i].name := name; ToolList[i].exts := exts; end; end.