(* Tux Commander - UChmod - Change permissions dialog Copyright (C) 2007 Tomas Bzatek 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 UChmod; interface uses SysUtils, Classes, lazgdk3, lazgtk3, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls; type TFChmod = class(TGTKDialog) HBox, HBox2, HBox3: TGTKHBox; VBox: TGTKVBox; PermissionFrame, FileFrame: TGTKFrame; RecursiveCheckButton, cbSUID, cbSGID, cbSticky, cbUSRRead, cbUSRWrite, cbUSRExec, cbGRPRead, cbGRPWrite, cbGRPExec, cbALLRead, cbALLWrite, cbALLExec: TGTKCheckButton; RecursiveComboBox: TGTKComboBoxText; FileLabel, OctalLabel, TextLabel: TGTKLabel; OctalEntry: TGTKEntry; procedure FormCreate(Sender: TObject); override; procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean); procedure RecursiveCheckButtonToggled(Sender: TObject); procedure PermissionsCheckBoxToggle(Sender: TObject); procedure OctalEntryChanged(Sender: TObject); private Busy: boolean; public LastMode: Cardinal; procedure AssignMode(const Mode: Cardinal; const FileName, User, Group: string); end; var FChmod: TFChmod; implementation uses ULibc, ULocale, UCoreUtils; procedure TFChmod.FormCreate(Sender: TObject); begin SetDefaultSize(-1, -1); LastMode := 0; Busy := True; Caption := LANGFChmod_Caption; Buttons := [mbOK, mbCancel]; HBox := TGTKHBox.Create(Self); HBox.Homogeneous := False; HBox.BorderWidth := 6; PermissionFrame := TGTKFrame.Create(Self); PermissionFrame.Caption := LANGFChmod_PermissionFrame; FileFrame := TGTKFrame.Create(Self); FileFrame.Caption := LANGFChmod_FileFrame; HBox.AddControlEx(PermissionFrame, True, True, 5); HBox.AddControlEx(FileFrame, False, False, 5); HBox2 := TGTKHBox.Create(Self); HBox2.Homogeneous := False; HBox2.BorderWidth := 5; RecursiveCheckButton := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_ApplyRecursivelyFor); RecursiveCheckButton.OnToggled := @RecursiveCheckButtonToggled; RecursiveComboBox := TGTKComboBoxText.Create(Self); RecursiveComboBox.AppendItem(LANGFChmod_miAllFiles); RecursiveComboBox.AppendItem(LANGFChmod_miDirectories); RecursiveComboBox.AppendItem(LANGmiFiles_Caption); RecursiveComboBox.ItemIndex := 0; HBox2.AddControlEx(TGTKLabel.Create(Self), False, False, 10); HBox2.AddControlEx(RecursiveCheckButton, False, False, 5); HBox2.AddControlEx(RecursiveComboBox, False, False, 5); HBox3 := TGTKHBox.Create(Self); HBox3.Homogeneous := False; HBox3.BorderWidth := 5; OctalLabel := TGTKLabel.Create(Self); OctalLabel.Caption := LANGFChmod_OctalLabel; OctalEntry := TGTKEntry.Create(Self); OctalEntry.MaxLength := 4; OctalEntry.SetSizeRequest(50, -1); OctalLabel.FocusControl := OctalEntry; OctalLabel.UseUnderline := True; TextLabel := TGTKLabel.Create(Self); TextLabel.Caption := 'Text: rw-rw-r--'; TextLabel.UseMarkup := True; HBox3.AddControlEx(TGTKLabel.Create(Self), False, False, 10); HBox3.AddControlEx(OctalLabel, False, False, 5); HBox3.AddControlEx(OctalEntry, False, False, 5); HBox3.AddControlEx(TGTKVSeparator.Create(Self), False, False, 10); HBox3.AddControlEx(TextLabel, False, False, 10); ClientArea.AddControlEx(HBox, True, True, 0); ClientArea.AddControlEx(TGTKHSeparator.Create(Self), False, False, 5); ClientArea.AddControlEx(HBox3, False, False, 0); ClientArea.AddControlEx(TGTKHSeparator.Create(Self), False, False, 5); ClientArea.AddControlEx(HBox2, False, False, 0); FileLabel := TGTKLabel.Create(Self); FileLabel.XAlign := 0; FileLabel.YAlign := 0; FileLabel.MarginStart := 10; FileLabel.MarginEnd := 10; FileLabel.MarginTop := 5; FileLabel.MarginBottom := 5; FileLabel.UseMarkup := True; // TODO gtk_widget_set_hexpand(FileLabel.FWidget, False); gtk_widget_set_size_request(FileLabel.FWidget, 200, -1); FileFrame.AddControl(FileLabel); VBox := TGTKVBox.Create(Self); VBox.BorderWidth := 5; cbSUID := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_SUID); VBox.AddControlEx(cbSUID, False, False, 0); cbSUID.OnToggled := @PermissionsCheckBoxToggle; cbSGID := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_SGID); VBox.AddControlEx(cbSGID, False, False, 0); cbSGID.OnToggled := @PermissionsCheckBoxToggle; cbSticky := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_Sticky); VBox.AddControlEx(cbSticky, False, False, 0); cbSticky.OnToggled := @PermissionsCheckBoxToggle; VBox.AddControlEx(TGTKHSeparator.Create(Self), False, False, 2); cbUSRRead := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_RUSR); VBox.AddControlEx(cbUSRRead, False, False, 0); cbUSRRead.OnToggled := @PermissionsCheckBoxToggle; cbUSRWrite := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_WUSR); VBox.AddControlEx(cbUSRWrite, False, False, 0); cbUSRWrite.OnToggled := @PermissionsCheckBoxToggle; cbUSRExec := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_XUSR); VBox.AddControlEx(cbUSRExec, False, False, 0); cbUSRExec.OnToggled := @PermissionsCheckBoxToggle; VBox.AddControlEx(TGTKHSeparator.Create(Self), False, False, 2); cbGRPRead := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_RGRP); VBox.AddControlEx(cbGRPRead, False, False, 0); cbGRPRead.OnToggled := @PermissionsCheckBoxToggle; cbGRPWrite := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_WGRP); VBox.AddControlEx(cbGRPWrite, False, False, 0); cbGRPWrite.OnToggled := @PermissionsCheckBoxToggle; cbGRPExec := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_XGRP); VBox.AddControlEx(cbGRPExec, False, False, 0); cbGRPExec.OnToggled := @PermissionsCheckBoxToggle; VBox.AddControlEx(TGTKHSeparator.Create(Self), False, False, 2); cbALLRead := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_ROTH); VBox.AddControlEx(cbALLRead, False, False, 0); cbALLRead.OnToggled := @PermissionsCheckBoxToggle; cbALLWrite := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_WOTH); VBox.AddControlEx(cbALLWrite, False, False, 0); cbALLWrite.OnToggled := @PermissionsCheckBoxToggle; cbALLExec := TGTKCheckButton.CreateWithLabel(Self, LANGFChmod_XOTH); VBox.AddControlEx(cbALLExec, False, False, 0); cbALLExec.OnToggled := @PermissionsCheckBoxToggle; PermissionFrame.AddControl(VBox); Busy := False; OnKeyDown := @FormKeyDown; OctalEntry.OnChanged := @OctalEntryChanged; RecursiveCheckButtonToggled(Self); end; procedure TFChmod.FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean); begin case Key of GDK_KEY_Return, GDK_KEY_KP_Enter: ModalResult := mbOK; GDK_KEY_Escape: ModalResult := mbCancel; end; end; procedure TFChmod.RecursiveCheckButtonToggled(Sender: TObject); begin RecursiveComboBox.Enabled := RecursiveCheckButton.Checked; end; procedure TFChmod.PermissionsCheckBoxToggle(Sender: TObject); var Mode: Cardinal; begin if Busy then Exit; Busy := True; Mode := 0; Mode := Mode or (Cardinal(Ord(cbSUID.Checked)) * __S_ISUID); Mode := Mode or (Cardinal(Ord(cbSGID.Checked)) * __S_ISGID); Mode := Mode or (Cardinal(Ord(cbSticky.Checked)) * __S_ISVTX); Mode := Mode or (Cardinal(Ord(cbUSRRead.Checked)) * S_IRUSR); Mode := Mode or (Cardinal(Ord(cbUSRWrite.Checked)) * S_IWUSR); Mode := Mode or (Cardinal(Ord(cbUSRExec.Checked)) * S_IXUSR); Mode := Mode or (Cardinal(Ord(cbGRPRead.Checked)) * S_IRGRP); Mode := Mode or (Cardinal(Ord(cbGRPWrite.Checked)) * S_IWGRP); Mode := Mode or (Cardinal(Ord(cbGRPExec.Checked)) * S_IXGRP); Mode := Mode or (Cardinal(Ord(cbALLRead.Checked)) * S_IROTH); Mode := Mode or (Cardinal(Ord(cbALLWrite.Checked)) * S_IWOTH); Mode := Mode or (Cardinal(Ord(cbALLExec.Checked)) * S_IXOTH); LastMode := Mode; TextLabel.Caption := Format(LANGFChmod_TextLabel, [AttrToStr(Mode, False)]);; TextLabel.UseMarkup := True; OctalEntry.Text := Format('%.4d', [AttrToOctal(Mode)]); Busy := False; end; procedure TFChmod.OctalEntryChanged(Sender: TObject); var Mode: Cardinal; begin if Busy then Exit; Busy := True; Mode := OctalToAttr(StrToIntDef(OctalEntry.Text, 0)); LastMode := Mode; cbSUID.Checked := Mode and __S_ISUID = __S_ISUID; cbSGID.Checked := Mode and __S_ISGID = __S_ISGID; cbSticky.Checked := Mode and __S_ISVTX = __S_ISVTX; cbUSRRead.Checked := Mode and S_IRUSR = S_IRUSR; cbUSRWrite.Checked := Mode and S_IWUSR = S_IWUSR; cbUSRExec.Checked := Mode and S_IXUSR = S_IXUSR; cbGRPRead.Checked := Mode and S_IRGRP = S_IRGRP; cbGRPWrite.Checked := Mode and S_IWGRP = S_IWGRP; cbGRPExec.Checked := Mode and S_IXGRP = S_IXGRP; cbALLRead.Checked := Mode and S_IROTH = S_IROTH; cbALLWrite.Checked := Mode and S_IWOTH = S_IWOTH; cbALLExec.Checked := Mode and S_IXOTH = S_IXOTH; TextLabel.Caption := Format(LANGFChmod_TextLabel, [AttrToStr(Mode, False)]);; TextLabel.UseMarkup := True; Busy := False; end; procedure TFChmod.AssignMode(const Mode: Cardinal; const FileName, User, Group: string); begin LastMode := Mode mod $1000; OctalEntry.Text := Format('%.4d', [AttrToOctal(LastMode)]); FileLabel.Caption := Format(LANGFChmod_FileLabel, [StrToUTF8(FileName), AttrToStr(Mode), AttrToOctal(Mode), User, Group]); FileLabel.UseMarkup := True; if Length(FileName) > 20 then FileLabel.SetSizeRequest(200, -1); end; end.