home *** CD-ROM | disk | FTP | other *** search
/ PC Open 19 / pcopen19.iso / Zipped / CALMIR21.ZIP / SOURCE.ZIP / SRC / FILEPROP.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-02-20  |  16.3 KB  |  570 lines

  1. {**************************************************************************}
  2. {                                                                          }
  3. {    Calmira shell for Microsoft« Windows(TM) 3.1                          }
  4. {    Source Release 2.1                                                    }
  5. {    Copyright (C) 1997-1998 Li-Hsin Huang                                 }
  6. {                                                                          }
  7. {    This program is free software; you can redistribute it and/or modify  }
  8. {    it under the terms of the GNU General Public License as published by  }
  9. {    the Free Software Foundation; either version 2 of the License, or     }
  10. {    (at your option) any later version.                                   }
  11. {                                                                          }
  12. {    This program is distributed in the hope that it will be useful,       }
  13. {    but WITHOUT ANY WARRANTY; without even the implied warranty of        }
  14. {    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         }
  15. {    GNU General Public License for more details.                          }
  16. {                                                                          }
  17. {    You should have received a copy of the GNU General Public License     }
  18. {    along with this program; if not, write to the Free Software           }
  19. {    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             }
  20. {                                                                          }
  21. {**************************************************************************}
  22.  
  23. unit FileProp;
  24.  
  25. { File Properties dialog
  26.  
  27.   Displays details of files (and version information), folders or
  28.   a combination.  The main call is SetItem(), which accepts either
  29.   a TDirItem or a TFileList, and sets up the dialog appropriately.
  30.  
  31.   Translation note: the tabbed notebook page names must match
  32.   the resource file.
  33. }
  34.  
  35. interface
  36.  
  37. uses WinTypes, WinProcs, Classes, Graphics, Forms, Controls, Buttons,
  38.   StdCtrls, ExtCtrls, Directry, TabNotBk, VerInfo, Dialogs,
  39.   LabelSel;
  40.  
  41. type
  42.   TFilePropDlg = class(TForm)
  43.     OKBtn: TBitBtn;
  44.     CancelBtn: TBitBtn;
  45.     Notebook: TTabbedNotebook;
  46.     Notes: TNotebook;
  47.     Label1: TLabel;
  48.     Label2: TLabel;
  49.     Label3: TLabel;
  50.     Label4: TLabel;
  51.     FilenameLab: TLabel;
  52.     LocationLab: TLabel;
  53.     SizeLab: TLabel;
  54.     DateLab: TLabel;
  55.     Label10: TLabel;
  56.     TypeLab: TLabel;
  57.     Label6: TLabel;
  58.     Foldername: TLabel;
  59.     Label8: TLabel;
  60.     FolderLoc: TLabel;
  61.     Label16: TLabel;
  62.     Foldersize: TLabel;
  63.     Label21: TLabel;
  64.     FolderDate: TLabel;
  65.     Label23: TLabel;
  66.     TotalLab: TLabel;
  67.     Label7: TLabel;
  68.     Label9: TLabel;
  69.     Selfiles: TLabel;
  70.     Selsize: TLabel;
  71.     VerinfoList: TListBox;
  72.     Bevel2: TBevel;
  73.     ReadOnly: TCheckBox;
  74.     Hidden: TCheckBox;
  75.     Archive: TCheckBox;
  76.     SystemFile: TCheckBox;
  77.     Label5: TLabel;
  78.     Bevel1: TBevel;
  79.     Header1: THeader;
  80.     Panel1: TPanel;
  81.     ItemImage: TImage;
  82.     HelpBtn: TBitBtn;
  83.     LabelSel: TLabelSelect;
  84.     Bevel3: TBevel;
  85.     AssocList: TComboBox;
  86.     Bevel4: TBevel;
  87.     AssocLabel: TLabel;
  88.     UserCommand: TEdit;
  89.     rbRegistry: TRadioButton;
  90.     rbCommand: TRadioButton;
  91.     rbNothing: TRadioButton;
  92.     OpenDialog: TOpenDialog;
  93.     procedure OKBtnClick(Sender: TObject);
  94.     procedure ReadOnlyClick(Sender: TObject);
  95.     procedure TotalLabClick(Sender: TObject);
  96.     procedure VerinfoListDrawItem(Control: TWinControl; Index: Integer;
  97.       Rect: TRect; State: TOwnerDrawState);
  98.     procedure FormCreate(Sender: TObject);
  99.     procedure Header1Sized(Sender: TObject; ASection, AWidth: Integer);
  100.     procedure NotebookChange(Sender: TObject; NewTab: Integer;
  101.       var AllowChange: Boolean);
  102.     procedure FoldernameMouseDown(Sender: TObject; Button: TMouseButton;
  103.       Shift: TShiftState; X, Y: Integer);
  104.     procedure rbRegistryClick(Sender: TObject);
  105.     procedure FormDestroy(Sender: TObject);
  106.     procedure AssocListChange(Sender: TObject);
  107.     procedure UserCommandDblClick(Sender: TObject);
  108.   private
  109.     { Private declarations }
  110.     Item         : TObject;
  111.     AttrChanged  : Boolean;
  112.     FileExt      : TFileExt;
  113.     AssocChanged : Boolean;
  114.     FileTypes    : TStringList;
  115.     LongDateTime : string[63];
  116.     ComboSaveIndex : Integer;
  117.     procedure SetSingle;
  118.     procedure SetFile;
  119.     procedure SetFolder;
  120.     procedure SetList;
  121.     procedure ExtractVerInfo;
  122.     procedure SetCheckBoxes(attr, gray: Integer);
  123.     procedure SaveAttributes;
  124.     procedure SaveAssociation;
  125.   public
  126.     { Public declarations }
  127.     procedure SetItem(AItem : TObject);
  128.   end;
  129.  
  130. var
  131.   FilePropDlg: TFilePropDlg;
  132.  
  133. implementation
  134.  
  135. {$R *.DFM}
  136.  
  137. uses SysUtils, Files, Strings, Resource, Settings, MiscUtil,
  138.   FileCtrl, FileMan, Alias, FourDOS, ShellAPI, Locale;
  139.  
  140.  
  141. procedure TFilePropDlg.SetCheckboxes(attr, gray: Integer);
  142.  
  143. procedure SetCheckBox(Checkbox: TCheckbox; mask: Integer);
  144. begin
  145.   with Checkbox do begin
  146.     Checked := attr and mask <> 0;
  147.     if gray and mask <> 0 then State := cbGrayed else AllowGrayed := False;
  148.   end;
  149. end;
  150.  
  151. begin
  152.   SetCheckbox(ReadOnly, faReadOnly);
  153.   SetCheckbox(Archive, faArchive);
  154.   SetCheckbox(Hidden, faHidden);
  155.   SetCheckbox(SystemFile, faSysFile);
  156. end;
  157.  
  158.  
  159. procedure TFilePropDlg.SetSingle;
  160. begin
  161.   with Item as TDirItem do begin
  162.     ItemImage.Picture.Icon := Icon;
  163.     SetCheckBoxes(Attr, 0);
  164.   end;
  165. end;
  166.  
  167.  
  168.  
  169. procedure TFilePropDlg.SetFile;
  170. var
  171.   s : string;
  172. begin
  173.   SetSingle;
  174.   with Item as TFileItem do begin
  175.     Notes.PageIndex := 0;
  176.  
  177.     FilenameLab.Caption := Filename;
  178.     LocationLab.Caption := Dir.Fullname;
  179.  
  180.     DateLab.Caption := FormatDateTime(LongDateTime, TimeStamp);
  181.  
  182.     SizeLab.Caption := FormatByte(Size, 2);
  183.     if Size > 1024 then with SizeLab do begin
  184.       Hint := FormatByteLong(Size);
  185.       Caption := Caption + Format('  (%s)', [Hint]);
  186.     end;
  187.  
  188.     FileExt := Extension;
  189.  
  190.     if Item is TAlias then s:= 'Alias'
  191.     else begin
  192.       ini.ReadSectionValues('File Types', FileTypes);
  193.       s := FileTypes.Values[FileExt];
  194.     end;
  195.  
  196.     if s = '' then begin
  197.       { query the registry }
  198.       s := GetRegValue(GetRegValue('.' + FileExt));
  199.       if s = '' then s := LoadStr(SUnknown);
  200.     end;
  201.  
  202.     TypeLab.Caption := s;
  203.  
  204.     ExtractVerInfo;
  205.   end;
  206. end;
  207.  
  208.  
  209. procedure TFilePropDlg.SetFolder;
  210. begin
  211.   SetSingle;
  212.   with Item as TFolder do begin
  213.     Notes.PageIndex := 1;
  214.  
  215.     Foldername.Caption := Filename;
  216.     FolderLoc.Caption := Dir.Fullname;
  217.     FolderDate.Caption := FormatDateTime(LongDateTime, TimeStamp);
  218.  
  219.     with DirInfo(Fullname, False) do begin
  220.       FolderSize.Caption := FmtLoadStr(SFolderContents,
  221.         [FormatByte(size, 2), files, OneItem[files = 1]]);
  222.       if Size > 1024 then
  223.         FolderSize.Hint := FormatByteLong(Size);
  224.     end;
  225.   end;
  226. end;
  227.  
  228.  
  229. procedure TFilePropDlg.SetList;
  230. var
  231.   i, gray, attr : Integer;
  232.   f : TDirItem;
  233. begin
  234.   with Item as TFileList do begin
  235.     Notes.PageIndex := 2;
  236.     ItemImage.Picture.Icon := Icons.Get('MultiFile');
  237.     Selfiles.Caption := FmtLoadStr(SSelectionContents,
  238.       [FileCount, OneItem[FileCount = 1], FolderCount, OneItem[FolderCount = 1]]);;
  239.     Selsize.Caption := FormatByte(FileSize, 2);
  240.     if FileSize > 1024 then
  241.       Selsize.Hint := FormatByteLong(FileSize);
  242.  
  243.     { Determine which checkboxes should be grayed out }
  244.  
  245.     attr := TDirItem(Items[0]).Attr;
  246.     gray := 0;
  247.     for i := 1 to Count-1 do begin
  248.        f := TDirItem(Items[i]);
  249.        gray := gray or (f.Attr xor attr);
  250.        attr := attr or f.Attr;
  251.     end;
  252.     SetCheckBoxes(attr, gray);
  253.   end;
  254. end;
  255.  
  256.  
  257. procedure TFilePropDlg.SetItem(AItem : TObject);
  258. begin
  259.   Item := AItem;
  260.   if Item is TFileItem then SetFile
  261.   else if Item is TFolder then SetFolder
  262.   else SetList;
  263.   Caption := Notes.ActivePage;
  264.  
  265.   with NoteBook.Pages do begin
  266.     if VerInfoList.Items.Count = 0 then Delete(IndexOf(LoadStr(SVersion)));
  267.     if not (Item is TFileItem) or
  268.       (FileExt = '') or ExtensionIn(FileExt, Programs) then
  269.         Delete(IndexOf(LoadStr(SAssociation)));
  270.   end;
  271. end;
  272.  
  273.  
  274. procedure TFilePropDlg.SaveAttributes;
  275. var
  276.   i, attrib, gray : Integer;
  277. begin
  278.   attrib := Integer(ReadOnly.Checked) * faReadOnly or
  279.             Integer(Archive.Checked) * faArchive or
  280.             Integer(Hidden.Checked) * faHidden or
  281.             Integer(SystemFile.Checked) * faSysFile;
  282.  
  283.   if Item is TDirItem then
  284.     (Item as TDirItem).Attr := attrib
  285.   else
  286.     with Item as TFileList do begin
  287.       gray := Integer(ReadOnly.State = cbGrayed) * faReadOnly or
  288.               Integer(Archive.State = cbGrayed) * faArchive or
  289.               Integer(Hidden.State = cbGrayed) * faHidden or
  290.               Integer(SystemFile.State = cbGrayed) * faSysFile;
  291.  
  292.       for i := 0 to Count-1 do
  293.         with TDirItem(Items[i]) do Attr := attrib or (gray and Attr);
  294.     end;
  295. end;
  296.  
  297.  
  298. function SubstExtension(const source, ext: string): string;
  299. var
  300.   p: Integer;
  301. begin
  302.   Result := source;
  303.   p := Pos('%1', Result);
  304.   if p > 0 then begin
  305.     Delete(Result, p, 2);
  306.     Insert('^.' + ext, Result, p);
  307.   end;
  308. end;
  309.  
  310.  
  311. procedure TFilePropDlg.SaveAssociation;
  312. var
  313.   filename   : array[0..79] of Char;
  314.   ext        : array[0..7] of Char;
  315.   subkey     : array[0..7] of Char;
  316.   buf1, buf2 : array[0..79] of Char;
  317.   fileclass  : string[63];
  318. begin
  319.   StrPCopy(filename, WinPath + 'win.ini');
  320.   StrPCopy(ext, FileExt);
  321.   subkey[0] := '.';
  322.   StrCopy(@subkey[1], ext);
  323.  
  324.  
  325.   case GetRadioIndex([rbRegistry, rbCommand, rbNothing]) of
  326.    0: begin
  327.         with AssocList do begin
  328.           if ItemIndex = -1 then Exit;
  329.           fileclass := PString(Items.Objects[ItemIndex])^;
  330.         end;
  331.  
  332.         WritePrivateProfileString('Extensions', ext,
  333.           StrPCopy(buf1, SubstExtension(
  334.             GetRegValue(fileclass + '\shell\open\command'), FileExt)),
  335.           filename);
  336.  
  337.         RegSetValue(HKEY_CLASSES_ROOT, subkey,
  338.           REG_SZ, StrPCopy(buf2, fileclass), 0);
  339.       end;
  340.  
  341.    1: begin
  342.         if UserCommand.Text = '' then Exit;
  343.  
  344.         WritePrivateProfileString('Extensions', ext,
  345.           StrPCopy(buf1, SubstExtension(UserCommand.Text, FileExt)),
  346.           filename);
  347.  
  348.         RegSetValue(HKEY_CLASSES_ROOT, subkey, REG_SZ, '', 0);
  349.  
  350.         RegSetValue(HKEY_CLASSES_ROOT,
  351.           StrPCopy(buf1, Format('.%s\shell\open\command', [FileExt])),
  352.             REG_SZ, StrPCopy(buf2, UserCommand.Text), 0);
  353.       end;
  354.  
  355.    2: begin
  356.         WritePrivateProfileString('Extensions', ext, nil, filename);
  357.         RegDeleteKey(HKEY_CLASSES_ROOT, subkey);
  358.       end;
  359.   end;
  360. end;
  361.  
  362.  
  363. procedure TFilePropDlg.OKBtnClick(Sender: TObject);
  364. begin
  365.   if AttrChanged then SaveAttributes;
  366.   if AssocChanged then SaveAssociation;
  367. end;
  368.  
  369.  
  370. procedure TFilePropDlg.ReadOnlyClick(Sender: TObject);
  371. begin
  372.   AttrChanged := True;
  373. end;
  374.  
  375. procedure TFilePropDlg.TotalLabClick(Sender: TObject);
  376. begin
  377.   ShowHourglass;
  378.   with DirInfo((Item as TFolder).Fullname, True) do begin
  379.     TotalLab.Caption := FmtLoadStr(STotalContents,
  380.      [files, OneItem[files = 1], dirs, OneItem[dirs = 1], FormatByte(size, 2)]);
  381.     TotalLab.Hint := FormatByteLong(Size);
  382.   end;
  383.   with TotalLab do begin
  384.     OnClick := nil;
  385.     OnMouseDown := FolderNameMouseDown;
  386.     Cursor := crIBeam;
  387.   end;
  388. end;
  389.  
  390. procedure TFilePropDlg.ExtractVerInfo;
  391. var Res: TVersion;
  392.  
  393. procedure AddField(FieldIdent : Word; const info: string);
  394. begin
  395.   if info > '' then
  396.     VerInfoList.Items.Add(Format('%s¼%s', [LoadStr(FieldIdent), info]));
  397. end;
  398.  
  399. begin
  400.   try
  401.     Res := TVersion.Create((Item as TFileItem).Fullname);
  402.     if not Res.HasData then Exit;
  403.  
  404.     VerInfoList.Items.BeginUpdate;
  405.     with Res do begin
  406.       AddField(SProductName, ProductName);
  407.       AddField(SLegalCopyright, LegalCopyright);
  408.       AddField(SDescription, FileDescription);
  409.       AddField(SType, FileType);
  410.       AddField(SSubType, FileSubType);
  411.       AddField(SFileOS, FileOS);
  412.       AddField(SComments, Comments);
  413.       AddField(SProductVersion, ProductVersion);
  414.       AddField(SFileVersion, FileVersion);
  415.       AddField(SCompany, CompanyName);
  416.       AddField(SLegalTrademarks, LegalTrademarks);
  417.       AddField(SInternalName, InternalName);
  418.       AddField(SPrivateBuild, PrivateBuild);
  419.       AddField(SSpecialBuild, SpecialBuild);
  420.       AddField(SOriginalFilename, OriginalFilename);
  421.     end;
  422.  
  423.     with VerInfoList do begin
  424.       Canvas.Font := Font;
  425.       Header1.SectionWidth[0] :=
  426.         Canvas.TextWidth(LoadStr(SOriginalFilename)) + 8;
  427.       Items.EndUpdate;
  428.     end;
  429.  
  430.   finally
  431.     Res.Free;
  432.   end;
  433. end;
  434.  
  435. procedure TFilePropDlg.VerinfoListDrawItem(Control: TWinControl; Index: Integer;
  436.   Rect: TRect; State: TOwnerDrawState);
  437. var
  438.   field : string[31];
  439.   value : string;
  440. begin
  441.   with VerInfoList do begin
  442.     Unformat(Items[Index], '%s¼%s', [@field, 31, @value, 255]);
  443.     with Canvas do begin
  444.       FillRect(Rect);
  445.       TextOut(Rect.Left + 2, Rect.Top + 1, field);
  446.       TextOut(Rect.Left + Header1.SectionWidth[0], Rect.Top + 1, value);
  447.     end;
  448.   end;
  449. end;
  450.  
  451. procedure TFilePropDlg.FormCreate(Sender: TObject);
  452. begin
  453.   Notebook.PageIndex := 0;
  454.   VerInfoList.ItemHeight := LineHeight;
  455.   FileTypes := TStringList.Create;
  456.   LongDateTime := ini.ReadString('File System',
  457.     'LongDateTime', 'dddd d mmmm yyyy,  hh:mm am/pm');
  458. end;
  459.  
  460. procedure TFilePropDlg.Header1Sized(Sender: TObject; ASection,
  461.   AWidth: Integer);
  462. begin
  463.   VerInfoList.Invalidate;
  464. end;
  465.  
  466. procedure TFilePropDlg.NotebookChange(Sender: TObject; NewTab: Integer;
  467.   var AllowChange: Boolean);
  468. var
  469.   cb : Longint;
  470.   buf : array[0..79] of Char;
  471.   i, position : Longint;
  472.   FileClass  : string[79];
  473.   ThisClass : string[79];
  474.   OpenCommand : string[79];
  475.   Entry : string[159];
  476. begin
  477.   if (Notebook.Pages[NewTab] = LoadStr(SAssociation)) then begin
  478.     if AssocList.Items.Count = 0 then
  479.     begin
  480.       ShowHourglass;
  481.       AssocLabel.Caption := FmtLoadStr(SAssociateTypeWith, [FileExt]);
  482.       rbNothing.Checked := True;
  483.  
  484.       FileClass := GetRegValue('.' + FileExt);
  485.       if FileClass = '' then begin
  486.         OpenCommand :=
  487.           GetRegValue(Format('.%s\shell\open\command', [FileExt]));
  488.         if OpenCommand > '' then begin
  489.           rbCommand.Checked := True;
  490.           UserCommand.Text := OpenCommand;
  491.         end;
  492.       end;
  493.  
  494.       i := 0;
  495.       cb := Sizeof(buf)-1;
  496.  
  497.       with AssocList do begin
  498.         Items.BeginUpdate;
  499.         while RegEnumKey(HKEY_CLASSES_ROOT, i, buf, cb) = ERROR_SUCCESS do begin
  500.           ThisClass := StrPas(buf);
  501.  
  502.           if (ThisClass > '') and (ThisClass[1] <> '.') then begin
  503.             OpenCommand := GetRegValue(ThisClass + '\shell\open\command');
  504.             Entry := GetRegValue(ThisClass);
  505.             if Entry > '' then begin
  506.               if OpenCommand > '' then
  507.                 Entry := Format('%s   (%s)', [Entry, OpenCommand]);
  508.               position := Items.AddObject(Entry, TObject(NewStr(ThisClass)));
  509.             end;
  510.           end;
  511.  
  512.           Inc(i);
  513.           cb := Sizeof(buf)-1;
  514.         end;
  515.         Items.EndUpdate;
  516.  
  517.         for i := 0 to Items.Count-1 do
  518.           if FileClass = PString(Items.Objects[i])^ then begin
  519.             ItemIndex := i;
  520.             rbRegistry.Checked := True;
  521.             Exit;
  522.           end;
  523.       end;
  524.       AssocChanged := False;
  525.     end
  526.     else AssocList.ItemIndex := ComboSaveIndex;
  527.   end
  528.   else if Notebook.ActivePage = LoadStr(SAssociation) then
  529.     ComboSaveIndex := AssocList.ItemIndex;
  530.  
  531.   FreePageHandles(Notebook);
  532. end;
  533.  
  534. procedure TFilePropDlg.FoldernameMouseDown(Sender: TObject;
  535.   Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  536. begin
  537.   if Button = mbLeft then LabelSel.Overlay(Sender as TLabel);
  538. end;
  539.  
  540. procedure TFilePropDlg.rbRegistryClick(Sender: TObject);
  541. begin
  542.   AssocList.Enabled := rbRegistry.Checked;
  543.   UserCommand.Enabled := rbCommand.Checked;
  544.   AssocChanged := True;
  545. end;
  546.  
  547. procedure TFilePropDlg.FormDestroy(Sender: TObject);
  548. var
  549.   i: Integer;
  550. begin
  551.   FileTypes.Free;
  552.   if NoteBook.Pages.IndexOf(LoadStr(SAssociation)) > -1 then
  553.   with AssocList do
  554.     for i := 0 to Items.Count-1 do
  555.       DisposeStr(PString(Items.Objects[i]));
  556. end;
  557.  
  558. procedure TFilePropDlg.AssocListChange(Sender: TObject);
  559. begin
  560.   AssocChanged := True;
  561. end;
  562.  
  563. procedure TFilePropDlg.UserCommandDblClick(Sender: TObject);
  564. begin
  565.   if OpenDialog.Execute then
  566.     UserCommand.Text := Lowercase(OpenDialog.Filename) + ' %1';
  567. end;
  568.  
  569. end.
  570.