(*
    Tux Commander - UCoreClasses - Some useful core classes
    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 UCoreClasses;

interface

uses gdk2pixbuf, gtk2, gdk2, glib2, SysUtils, Classes, ULibc, IniFiles, GTKClasses, GTKStdCtrls, GTKDialogs, GTKPixbuf, UGnome,
     UEngines;

type TSystemUser = class
     public
       UserName, FullName, HomeDir, LoginShell: string;
       UID, GID: Cardinal;
     end;

     TSystemGroup = class
     public
       GroupName: string;
       GID: Cardinal;
       Users: TStrings;
     end;

     TUserManager = class
     private
     public
       UserList, GroupList: TList;
       constructor Create;
       destructor Destroy; override;
       function GetUserName(UID: Cardinal; const ShowNA: boolean = True): string;
       function GetGroupName(GID: Cardinal; const ShowNA: boolean = True): string;
     end;


     TMyIniFile = class(TIniFile)
     private
       FReadOnly: boolean;
     public
       constructor Create(const FileName: string; const ReadOnly: boolean);
       procedure UpdateFile; override;
     end;

     TGTKImageButton = class(TGTKButton)
     private
       FHBox: PGtkWidget;
       FLabel: PGtkWidget;
       FImage: PGtkWidget;
       FEventBoxLeft, FEventBoxRight: PGtkWidget;
       function GetCaption: string;
       procedure SetCaption(Value: string);
       procedure SetIcon(Value: TGDKPixbuf);
       procedure SetSpacing(Value: integer);
     public
       procedure SetFromStock(Stock_ID: string; IconSize: TGTKIconSize);
     published
       constructor Create(AOwner: TComponent); override;
       constructor CreateWithoutLabel(AOwner: TComponent);
       property Caption: string read GetCaption write SetCaption;
       property Icon: TGDKPixbuf write SetIcon;
       property Spacing: integer write SetSpacing;
     end;

     TGTKImageToggleButton = class(TGTKToggleButton)
     private
       FHBox: PGtkWidget;
       FLabel: PGtkWidget;
       FImage: PGtkWidget;
       function GetCaption: string;
       procedure SetCaption(Value: string);
       procedure SetIcon(Value: TGDKPixbuf);
     public
       procedure SetFromStock(Stock_ID: string; IconSize: TGTKIconSize);
     published
       constructor Create(AOwner: TComponent); override;
       constructor CreateWithoutLabel(AOwner: TComponent);
       property Caption: string read GetCaption write SetCaption;
       property Icon: TGDKPixbuf write SetIcon;
     end;


implementation

uses GTKForms, GTKUtils, ULocale, UConfig, UCore, UCoreUtils;



(********************************************************************************************************************************)
(********************************************************************************************************************************)
constructor TUserManager.Create;
var pwd: PPasswd;
    User: TSystemUser;
    grp: PGroup;
    Group: TSystemGroup;
    i: integer;
begin
  inherited Create;
  UserList := TList.Create;
  GroupList := TList.Create;
  //  Load and process /etc/passwd
  try
    setpwent;
    pwd := getpwent;
    while pwd <> nil do begin
      User := TSystemUser.Create;
      User.UserName := String(StrToUTF8(pwd^.pw_name));
      User.FullName := String(StrToUTF8(pwd^.pw_gecos));
      User.HomeDir := String(StrToUTF8(pwd^.pw_dir));
      User.LoginShell := String(StrToUTF8(pwd^.pw_shell));
      User.UID := pwd^.pw_uid;
      User.GID := pwd^.pw_gid;
      UserList.Add(User);
      pwd := getpwent;
    end;
    endpwent;
  except end;
  //  Load and process /etc/group
  try
    setgrent;
    grp := getgrent;
    while grp <> nil do begin
      Group := TSystemGroup.Create;
      Group.GroupName := String(StrToUTF8(grp^.gr_name));
      Group.GID := grp^.gr_gid;
      Group.Users := TStringList.Create;
      {$R-}
      if grp^.gr_mem^ <> nil then begin
        i := 0;
        repeat
          Group.Users.Add(String(StrToUTF8(PCharArray(grp^.gr_mem^)[i])));
          Inc(i);
        until PCharArray(grp^.gr_mem^)[i] = nil;
      end;
      {$R+}
      GroupList.Add(Group);
      grp := getgrent;
    end;
    endgrent;
  except end;
end;

destructor TUserManager.Destroy;
var i: integer;
begin
  if UserList.Count > 0 then
    for i := UserList.Count - 1 downto 0 do begin
      TSystemUser(UserList[i]).Free;
      UserList.Delete(i);
    end;
  UserList.Clear;
  UserList.Free;
  if GroupList.Count > 0 then
    for i := GroupList.Count - 1 downto 0 do begin
      TSystemGroup(GroupList[i]).Users.Clear;
      TSystemGroup(GroupList[i]).Users.Free;
      TSystemGroup(GroupList[i]).Free;
      GroupList.Delete(i);
    end;
  GroupList.Clear;
  GroupList.Free;
  inherited Destroy;
end;

function TUserManager.GetUserName(UID: Cardinal; const ShowNA: boolean = True): string;
var i: integer;
begin
  if ShowNA then Result := 'N/A'
            else Result := IntToStr(UID);
  if UserList.Count > 0 then
    for i := 0 to UserList.Count - 1 do
      if TSystemUser(UserList[i]).UID = UID then begin
        Result := TSystemUser(UserList[i]).UserName;
        Break;
      end;
end;

function TUserManager.GetGroupName(GID: Cardinal; const ShowNA: boolean = True): string;
var i: integer;
begin
  if ShowNA then Result := 'N/A'
            else Result := IntToStr(GID);
  if GroupList.Count > 0 then
    for i := 0 to GroupList.Count - 1 do
      if TSystemGroup(GroupList[i]).GID = GID then begin
        Result := TSystemGroup(GroupList[i]).GroupName;
        Break;
      end;
end;

(********************************************************************************************************************************)
(********************************************************************************************************************************)
constructor TMyIniFile.Create(const FileName: string; const ReadOnly: boolean);
begin
  FReadOnly := ReadOnly;
  inherited Create(FileName);
end;

procedure TMyIniFile.UpdateFile;
begin
  if not FReadOnly then inherited UpdateFile;
end;

(********************************************************************************************************************************)
(********************************************************************************************************************************)
constructor TGTKImageButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWidget := gtk_button_new;
  FLabel := gtk_label_new('');
  FImage := gtk_image_new;
  FHBox := gtk_hbox_new(False, 2);
  FEventBoxLeft := gtk_vbox_new(false, 0);
  FEventBoxRight := gtk_vbox_new(false, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FEventBoxLeft, False, False, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FImage, False, False, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FLabel, True, True, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FEventBoxRight, False, False, 0);
  gtk_container_add(PGtkContainer(FWidget), FHBox);
  g_signal_connect(PGtkObject(FWidget), 'clicked', G_CALLBACK(@TGTKButton_OnClick), Self);
  gtk_widget_show(FLabel);
  gtk_widget_show(FImage);
  gtk_widget_show(FHBox);
  gtk_widget_show(FEventBoxLeft);
  gtk_widget_show(FEventBoxRight);
  Show;
end;

constructor TGTKImageButton.CreateWithoutLabel(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWidget := gtk_button_new;
  FLabel := gtk_label_new('');
  FImage := gtk_image_new;
  FHBox := gtk_hbox_new(False, 2);
  FEventBoxLeft := gtk_vbox_new(false, 0);
  FEventBoxRight := gtk_vbox_new(false, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FEventBoxLeft, False, False, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FImage, False, False, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FEventBoxRight, False, False, 0);
  gtk_container_add(PGtkContainer(FWidget), FHBox);
  g_signal_connect(PGtkObject(FWidget), 'clicked', G_CALLBACK(@TGTKButton_OnClick), Self);
  gtk_widget_show(FLabel);
  gtk_widget_show(FImage);
  gtk_widget_show(FHBox);
  gtk_widget_show(FEventBoxLeft);
  gtk_widget_show(FEventBoxRight);
  Show;
end;

function TGTKImageButton.GetCaption: string;
begin
  Result := gtk_label_get_text(PGtkLabel(FLabel));
end;

procedure TGTKImageButton.SetCaption(Value: string);
begin
  gtk_label_set_text_with_mnemonic(PGtkLabel(FLabel), PChar(Value));
end;

procedure TGTKImageButton.SetIcon(Value: TGDKPixbuf);
begin
  if Assigned(Value) and Assigned(Value.FPixbuf) then
    gtk_image_set_from_pixbuf(PGtkImage(FImage), Value.FPixbuf);
end;

procedure TGTKImageButton.SetFromStock(Stock_ID: string; IconSize: TGTKIconSize);
begin
  gtk_image_set_from_stock(PGtkImage(FImage), PChar(Stock_ID), Ord(IconSize));
end;

procedure TGTKImageButton.SetSpacing(Value: integer);
begin
  gtk_widget_set_size_request(FEventBoxLeft, Value, -1);
  gtk_widget_set_size_request(FEventBoxRight, Value, -1);
end;


(********************************************************************************************************************************)
(********************************************************************************************************************************)
constructor TGTKImageToggleButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWidget := gtk_toggle_button_new;
  FLabel := gtk_label_new('');
  FImage := gtk_image_new;
  FHBox := gtk_hbox_new(False, 2);
  gtk_box_pack_start(PGtkBox(FHBox), FImage, False, False, 0);
  gtk_box_pack_start(PGtkBox(FHBox), FLabel, True, True, 0);
  gtk_container_add(PGtkContainer(FWidget), FHBox);
  g_signal_connect(PGtkObject(FWidget), 'clicked', G_CALLBACK(@TGTKButton_OnClick), Self);
  gtk_widget_show(FLabel);
  gtk_widget_show(FImage);
  gtk_widget_show(FHBox);
  Show;
end;

constructor TGTKImageToggleButton.CreateWithoutLabel(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWidget := gtk_button_new;
  FLabel := gtk_label_new('');
  FImage := gtk_image_new;
  gtk_container_add(PGtkContainer(FWidget), FImage);
  g_signal_connect(PGtkObject(FWidget), 'clicked', G_CALLBACK(@TGTKButton_OnClick), Self);
  gtk_widget_show(FLabel);
  gtk_widget_show(FImage);
  Show;
end;

function TGTKImageToggleButton.GetCaption: string;
begin
  Result := gtk_label_get_text(PGtkLabel(FLabel));
end;

procedure TGTKImageToggleButton.SetCaption(Value: string);
begin
  gtk_label_set_text(PGtkLabel(FLabel), PChar(Value));
end;

procedure TGTKImageToggleButton.SetIcon(Value: TGDKPixbuf);
begin
  if Assigned(Value) and Assigned(Value.FPixbuf) then
    gtk_image_set_from_pixbuf(PGtkImage(FImage), Value.FPixbuf);
end;

procedure TGTKImageToggleButton.SetFromStock(Stock_ID: string; IconSize: TGTKIconSize);
begin
  gtk_image_set_from_stock(PGtkImage(FImage), PChar(Stock_ID), Ord(IconSize));
end;

(********************************************************************************************************************************)


end.
