Einzelnen Beitrag anzeigen

mytbo

Registriert seit: 8. Jan 2007
461 Beiträge
 
#15

AW: Fragen zu VirtualTreeView

  Alt 5. Okt 2023, 17:09
mir ging es um die einfachste Methode die Datei zu speichern.
Wenn es ganz einfach sein soll:
Delphi-Quellcode:
uses
  mormot.core.base,
  mormot.core.json,
  mormot.core.os;
  
type
  TSeriesItem = packed record
    FileName: String;
    SeriesName: String;
    EpisodeName: String;
    PlaybackCount: Integer;
  end;

  TSeriesItems = array of TSeriesItem;

  TSeriesDB = record
    Items: TSeriesItems;
    function Load(const pmcFileName: String): Boolean;
    procedure Save(const pmcFileName: String);
  end;
  
function TSeriesDB.Load(const pmcFileName: String): Boolean;
var
  json: RawJson;
begin
  Result := False;
  json := StringFromFile(pmcFileName);
  if json <> 'then
    Result := (DynArrayLoadJson(Items, Pointer(json), TypeInfo(TSeriesItems)) <> Nil);
end;

procedure TSeriesDB.Save(const pmcFileName: String);
var
  json: RawJson;
begin
  json := DynArraySaveJson(Items, TypeInfo(TSeriesItems));
  if json <> 'then
    FileFromString(json, pmcFileName);
end;
Im TreeView Knoten "Data" auf ein TSeriesItem zeigen lassen oder den Daten-Index speichern. JSON als DB-Format. Das Serialisieren mit mORMot ist tolerant. Du kannst jeder Zeit dem Daten-Record TSeriesItem Felder hinzufügen oder sie wieder entfernen.

Oder klassisch mit Hilfe von TDynArray umgesetzt:
Delphi-Quellcode:
type
  TSeriesDB = class(TObject)
  private
    FList: TDynArray;
    FItems: TSeriesItems;
    FItemCount: Integer;
    function GetItem(pmIndex: Integer): PSeriesItem;
  public
    constructor Create;
    destructor Destroy; override;
    function Add(const pmcFileName: String; const pmcSeriesName, pmcEpisodeName: String; pmPlaybackCount: Integer = 0): Integer;
    function Delete(pmIndex: Integer): Boolean;
    function LoadFromJsonFile(const pmcFileName: String): Boolean;
    function SaveToJsonFile(const pmcFileName: String): Boolean;
    property Item[pmIndex: Integer]: PSeriesItem
      read GetItem;
    property ItemCount: Integer
      read FItemCount;
  end;

constructor TSeriesDB.Create;
begin
  inherited Create;
  FList.Init(TypeInfo(TSeriesItems), FItems, @FItemCount);
end;

destructor TSeriesDB.Destroy;
begin
  FList.Clear;
  inherited Destroy;
end;

function TSeriesDB.GetItem(pmIndex: Integer): PSeriesItem;
begin
  if (pmIndex >= 0)
    and (pmIndex < FItemCount) then
  begin
    Result := @FItems[pmIndex];
  end
  else
    Result := Nil;
end;

function TSeriesDB.Add(const pmcFileName, pmcSeriesName, pmcEpisodeName: String; pmPlaybackCount: Integer): Integer;
var
  item: PSeriesItem;
begin
  item := FList.NewPtr;
  item.FileName := pmcFileName;
  item.SeriesName := pmcSeriesName;
  item.EpisodeName := pmcEpisodeName;
  item.PlaybackCount := pmPlaybackCount;
  Result := FItemCount - 1;
end;

function TSeriesDB.Delete(pmIndex: Integer): Boolean;
begin
  Result := FList.Delete(pmIndex);
end;

function TSeriesDB.LoadFromJsonFile(const pmcFileName: String): Boolean;
var
  json: RawJson;
begin
  json := StringFromFile(pmcFileName);
  if json <> 'then
    Result := (FList.LoadFromJson(Pointer(json), Nil, Nil, True) <> Nil)
  else
    Result := False;
end;

function TSeriesDB.SaveToJsonFile(const pmcFileName: String): Boolean;
var
  json: RawJson;
begin
  json := FList.SaveToJson(True, jsonHumanReadable);
  if json <> 'then
    Result := FileFromString(json, pmcFileName)
  else
    Result := False;
end;
Anwendung so:
Delphi-Quellcode:
procedure ...DoGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
  item: PSeriesItem;
begin
  item := FSeriesDB.Item[Node.Index];
  if item <> Nil then
  begin
    case Column of
      0: CellText := item.FileName;
      1: CellText := item.SeriesName;
      2: CellText := item.EpisodeName;
      3: Celltext := item.PlaybackCount.ToString;
    end;
  end;
end;

begin
  FSeriesDB := TSeriesDB.Create;
  FSeriesDB.Add('X.mp4', 'X-Men', 'Folge 2');
  FSeriesDB.Add('Y.mp4', 'Akte-Y', 'Folge 456');
  VirtualStringTree.OnGetText := DoGetText;
  VirtualStringTree.RootNodeCount := FSeriesDB.ItemCount;
Bei Verwendung als Grid ohne filternde Funktionen reicht der Zugriff über Node Index auf die Daten aus.

Bis bald...
Thomas

Geändert von mytbo ( 6. Okt 2023 um 14:02 Uhr) Grund: Zweites Beispiel konkretisiert
  Mit Zitat antworten Zitat