Main.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. unit Main;
  2. interface
  3. uses
  4. Winapi.Windows,
  5. System.SysUtils,
  6. System.Classes,
  7. System.ImageList,
  8. Vcl.Graphics,
  9. Vcl.Controls,
  10. Vcl.Forms,
  11. Vcl.Dialogs,
  12. StrUtils,
  13. Vcl.Menus,
  14. Vcl.ImgList,
  15. Vcl.ExtCtrls,
  16. Vcl.ComCtrls,
  17. GLS.FileVfsPAK;
  18. type
  19. TForm1 = class(TForm)
  20. MainMenu1: TMainMenu;
  21. TreeView: TTreeView;
  22. OpenDialog1: TOpenDialog;
  23. SaveDialog1: TSaveDialog;
  24. ImageList1: TImageList;
  25. ListView: TListView;
  26. File1: TMenuItem;
  27. New1: TMenuItem;
  28. Open1: TMenuItem;
  29. Exit1: TMenuItem;
  30. Bevel1: TBevel;
  31. Edit1: TMenuItem;
  32. Createfolder1: TMenuItem;
  33. Addfiles1: TMenuItem;
  34. Deleteselectedfile1: TMenuItem;
  35. Deleteselectedfolder1: TMenuItem;
  36. N2: TMenuItem;
  37. Extractselectedfiles1: TMenuItem;
  38. N3: TMenuItem;
  39. N4: TMenuItem;
  40. N1: TMenuItem;
  41. Converttocompressed: TMenuItem;
  42. Converttouncompressed: TMenuItem;
  43. procedure FormCreate(Sender: TObject);
  44. procedure TreeViewRefresh;
  45. procedure FileListRefresh;
  46. procedure AddNode(text: string; node: TTreeNode);
  47. function TreeIndexOf(s: string; node: TTreeNode): integer;
  48. function ListIndexOf(s: string): integer;
  49. procedure TreeViewCollapsing(Sender: TObject; node: TTreeNode;
  50. var AllowCollapse: Boolean);
  51. procedure ListViewClick(Sender: TObject);
  52. procedure ListViewDblClick(Sender: TObject);
  53. procedure TreeViewChange(Sender: TObject; node: TTreeNode);
  54. procedure ListViewKeyDown(Sender: TObject; var Key: Word;
  55. Shift: TShiftState);
  56. procedure ListViewChange(Sender: TObject; Item: TListItem;
  57. Change: TItemChange);
  58. procedure New1Click(Sender: TObject);
  59. procedure Open1Click(Sender: TObject);
  60. procedure Createfolder1Click(Sender: TObject);
  61. procedure Addfiles1Click(Sender: TObject);
  62. procedure Deleteselectedfile1Click(Sender: TObject);
  63. procedure Deleteselectedfolder1Click(Sender: TObject);
  64. procedure TreeViewKeyDown(Sender: TObject; var Key: Word;
  65. Shift: TShiftState);
  66. procedure Extractselectedfiles1Click(Sender: TObject);
  67. procedure Exit1Click(Sender: TObject);
  68. procedure FormDestroy(Sender: TObject);
  69. procedure ConverttocompressedClick(Sender: TObject);
  70. procedure ConverttouncompressedClick(Sender: TObject);
  71. private
  72. public
  73. procedure RefreshMenu;
  74. end;
  75. var
  76. Form1: TForm1;
  77. CurPath, Selection: string;
  78. Pak: TGLVfsPak;
  79. implementation
  80. uses
  81. FolderDialog, FolderSelect, Frm_CompressionRatio, ShellApi;
  82. {$R *.dfm}
  83. {$R icons.res}
  84. procedure TForm1.AddNode(text: string; node: TTreeNode);
  85. var
  86. s: string;
  87. c: integer;
  88. begin
  89. c := Pos('/', text);
  90. if c = 0 then
  91. exit;
  92. s := Copy(text, 1, c - 1);
  93. Delete(text, 1, c);
  94. if TreeIndexOf(s, node) = -1 then
  95. AddNode(text, TreeView.Items.AddChild(node, s))
  96. else
  97. AddNode(text, node[TreeIndexOf(s, node)]);
  98. end;
  99. function TForm1.TreeIndexOf(s: string; node: TTreeNode): integer;
  100. var
  101. i: integer;
  102. begin
  103. Result := -1;
  104. for i := 0 to node.Count - 1 do
  105. if node[i].text = s then
  106. Result := i;
  107. end;
  108. function TForm1.ListIndexOf(s: string): integer;
  109. var
  110. i: integer;
  111. begin
  112. Result := -1;
  113. for i := 0 to ListView.Items.Count - 1 do
  114. if ListView.Items[i].Caption = s then
  115. Result := i;
  116. end;
  117. procedure TForm1.TreeViewRefresh;
  118. var
  119. i: integer;
  120. begin
  121. with TreeView do
  122. begin
  123. Items.Clear;
  124. Items.AddChild(Items.GetFirstNode, ExtractFileName(Pak.PakFileName));
  125. for i := 0 to Pak.Files.Count - 1 do
  126. AddNode(Pak.Files[i], Items.GetFirstNode);
  127. Items[0].Expanded := True;
  128. Items[0].SelectedIndex := 1;
  129. Items[0].ImageIndex := 1;
  130. end;
  131. TreeView.Selected := TreeView.Items.GetFirstNode;
  132. end;
  133. function MakeMemSize(size: integer): string;
  134. const
  135. kb = 1024;
  136. mb = kb * kb;
  137. gb = mb * kb;
  138. begin
  139. case size of
  140. 0 .. kb - 1:
  141. Result := IntToStr(size) + ' B';
  142. kb .. mb - 1:
  143. Result := Format('%.2f KB', [size / kb]);
  144. mb .. gb - 1:
  145. Result := Format('%.2f MB', [size / mb]);
  146. else
  147. Result := Format('%.2f GB', [size / gb]);
  148. end;
  149. end;
  150. procedure TForm1.FileListRefresh;
  151. var
  152. i, j: integer;
  153. s, name: string;
  154. n: TTreeNode;
  155. dir: Boolean;
  156. begin
  157. n := TreeView.Selected;
  158. s := n.text;
  159. if s = ExtractFileName(Pak.PakFileName) then
  160. s := '';
  161. while Assigned(n.parent) do
  162. begin
  163. n := n.parent;
  164. if n.AbsoluteIndex <> 0 then
  165. s := n.text + '/' + s;
  166. end;
  167. if s <> '' then
  168. s := s + '/';
  169. CurPath := s;
  170. ListView.Clear;
  171. for i := 0 to Pak.Files.Count - 1 do
  172. if Copy(Pak.Files[i], 1, Length(s)) = s then
  173. begin
  174. name := RightStr(Pak.Files[i], Length(Pak.Files[i]) - Length(s));
  175. j := Pos('/', name);
  176. if j = 0 then
  177. dir := False
  178. else
  179. dir := True;
  180. if dir = True then
  181. name := Copy(name, 1, j - 1);
  182. if ListIndexOf(name) = -1 then
  183. with ListView.Items.Add do
  184. begin
  185. Caption := Name;
  186. if dir = True then
  187. begin
  188. SubItems.Add('-');
  189. SubItems.Add('-')
  190. end
  191. else
  192. begin
  193. SubItems.Add(MakeMemSize(Pak.GetFileSize(i)));
  194. SubItems.Add(MakeMemSize(Pak.GetFileSize(i)))
  195. end;
  196. if dir = True then
  197. ImageIndex := 0
  198. else
  199. ImageIndex := 2;
  200. end;
  201. end;
  202. end;
  203. procedure TForm1.FormCreate(Sender: TObject);
  204. var
  205. Bmp: TBitmap;
  206. begin
  207. Pak := TGLVfsPak.Create(nil);
  208. Bmp := TBitmap.Create;
  209. Bmp.LoadFromResourceName(HInstance, 'ICONS');
  210. ImageList1.AddMasked(Bmp, clWhite);
  211. Bmp.Free;
  212. RefreshMenu;
  213. end;
  214. procedure TForm1.TreeViewCollapsing(Sender: TObject; node: TTreeNode;
  215. var AllowCollapse: Boolean);
  216. begin
  217. if node.AbsoluteIndex = 0 then
  218. AllowCollapse := False
  219. else
  220. AllowCollapse := True;
  221. end;
  222. procedure TForm1.ListViewClick(Sender: TObject);
  223. var
  224. s: string;
  225. begin
  226. if not Assigned(ListView.Selected) then
  227. exit;
  228. s := ListView.Selected.Caption;
  229. Selection := CurPath + s;
  230. end;
  231. procedure TForm1.ListViewDblClick(Sender: TObject);
  232. var
  233. s: string;
  234. n: TTreeNode;
  235. begin
  236. if not Assigned(ListView.Selected) then
  237. exit;
  238. if ListView.Selected.ImageIndex = 2 then
  239. exit;
  240. s := ListView.Selected.Caption;
  241. n := TreeView.Selected;
  242. TreeView.Selected := n[TreeIndexOf(s, n)];
  243. end;
  244. procedure TForm1.TreeViewChange(Sender: TObject; node: TTreeNode);
  245. begin
  246. FileListRefresh;
  247. end;
  248. procedure TForm1.ListViewKeyDown(Sender: TObject; var Key: Word;
  249. Shift: TShiftState);
  250. begin
  251. if ListView.Enabled = False then
  252. exit;
  253. ListViewClick(Sender);
  254. if Key = VK_RETURN then
  255. ListViewDblClick(Sender);
  256. if Key = VK_DELETE then
  257. Deleteselectedfile1Click(Self);
  258. end;
  259. procedure TForm1.ListViewChange(Sender: TObject; Item: TListItem;
  260. Change: TItemChange);
  261. begin
  262. ListViewClick(Sender);
  263. end;
  264. procedure TForm1.New1Click(Sender: TObject);
  265. begin
  266. if SaveDialog1.Execute then
  267. begin
  268. Pak.ClearPakFiles;
  269. Pak.LoadFromFile(SaveDialog1.FileName, fmCreate or fmShareDenyWrite);
  270. TreeViewRefresh;
  271. ListView.Enabled := True;
  272. RefreshMenu;
  273. end;
  274. end;
  275. procedure TForm1.Open1Click(Sender: TObject);
  276. begin
  277. OpenDialog1.DefaultExt := SaveDialog1.DefaultExt;
  278. OpenDialog1.Filter := SaveDialog1.Filter;
  279. OpenDialog1.Options := OpenDialog1.Options - [ofAllowMultiSelect];
  280. if OpenDialog1.Execute then
  281. begin
  282. Pak.ClearPakFiles;
  283. Pak.LoadFromFile(OpenDialog1.FileName, fmOpenReadWrite or fmShareDenyWrite);
  284. TreeViewRefresh;
  285. ListView.Enabled := True;
  286. RefreshMenu;
  287. end;
  288. end;
  289. procedure TForm1.Createfolder1Click(Sender: TObject);
  290. begin
  291. if not Assigned(Pak) then
  292. exit;
  293. if FDialog.ShowModal = mrOk then
  294. begin
  295. Pak.AddEmptyFile('temp.tmp', CurPath + FDialog.Edit1.text + '/');
  296. TreeViewRefresh;
  297. end;
  298. end;
  299. procedure TForm1.Addfiles1Click(Sender: TObject);
  300. var
  301. i: integer;
  302. begin
  303. if not Assigned(Pak) then
  304. exit;
  305. OpenDialog1.DefaultExt := '';
  306. OpenDialog1.Filter := 'All Files|*.*';
  307. OpenDialog1.Options := OpenDialog1.Options + [ofAllowMultiSelect];
  308. if OpenDialog1.Execute then
  309. begin
  310. for i := 0 to OpenDialog1.Files.Count - 1 do
  311. if ExtractFileName(OpenDialog1.Files[i]) <> '' then
  312. Pak.AddFromFile(OpenDialog1.Files[i], CurPath);
  313. TreeViewRefresh;
  314. end;
  315. end;
  316. procedure TForm1.Deleteselectedfile1Click(Sender: TObject);
  317. var
  318. i: integer;
  319. s: TStrings;
  320. begin
  321. if ListView.SelCount = 0 then
  322. exit;
  323. s := TStringList.Create;
  324. for i := 0 to ListView.Items.Count - 1 do
  325. if ListView.Items[i].Selected then
  326. s.Add(CurPath + ListView.Items[i].Caption);
  327. for i := 0 to s.Count - 1 do
  328. Pak.RemoveFile(s[i]);
  329. s.Free;
  330. FileListRefresh;
  331. if ListView.Items.Count = 0 then
  332. TreeViewRefresh;
  333. end;
  334. procedure TForm1.Deleteselectedfolder1Click(Sender: TObject);
  335. var
  336. i, l: integer;
  337. s: TStrings;
  338. begin
  339. s := TStringList.Create;
  340. s.AddStrings(Pak.Files);
  341. l := Length(CurPath);
  342. for i := 0 to s.Count - 1 do
  343. if Copy(s[i], 1, l) = CurPath then
  344. Pak.RemoveFile(s[i]);
  345. s.Free;
  346. TreeViewRefresh;
  347. end;
  348. procedure TForm1.TreeViewKeyDown(Sender: TObject; var Key: Word;
  349. Shift: TShiftState);
  350. begin
  351. if ListView.Enabled = False then
  352. exit;
  353. if Key = VK_DELETE then
  354. Deleteselectedfolder1Click(Self);
  355. end;
  356. procedure TForm1.Extractselectedfiles1Click(Sender: TObject);
  357. var
  358. i: integer;
  359. begin
  360. if ListView.SelCount = 0 then
  361. exit;
  362. if FolderSel.ShowModal = mrOk then
  363. begin
  364. for i := 0 to ListView.Items.Count - 1 do
  365. if ListView.Items[i].Selected then
  366. Pak.Extract(CurPath + ListView.Items[i].Caption,
  367. FolderSel.ShellView.Path + '\' + ListView.Items[i].Caption);
  368. end;
  369. end;
  370. procedure TForm1.Exit1Click(Sender: TObject);
  371. begin
  372. Application.Terminate;
  373. end;
  374. procedure TForm1.FormDestroy(Sender: TObject);
  375. begin
  376. if Assigned(Pak) then
  377. Pak.Free;
  378. end;
  379. // TForm1.ConverttocompressedClick
  380. //
  381. procedure TForm1.ConverttocompressedClick(Sender: TObject);
  382. var
  383. cbrRatio: TZCompressedMode;
  384. newPak, oldPak: TGLVfsPak;
  385. i: integer;
  386. oldFileName, newFileName: String;
  387. begin
  388. cbrRatio := SelectCompressionRatio;
  389. if cbrRatio <> None then
  390. begin
  391. oldFileName := Pak.PakFileName;
  392. Pak.Free;
  393. Pak := nil;
  394. newFileName := ChangeFileExt(oldFileName, '.bak');
  395. if FileExists(newFileName) then
  396. DeleteFile(newFileName);
  397. RenameFile(oldFileName, newFileName);
  398. newPak := TGLVfsPak.Create(nil, cbrRatio);
  399. newPak.LoadFromFile(oldFileName, fmCreate or fmShareDenyWrite);
  400. oldPak := TGLVfsPak.Create(nil);
  401. oldPak.LoadFromFile(newFileName, fmOpenRead or fmShareDenyWrite);
  402. for i := 0 to oldPak.FileCount - 1 do
  403. begin
  404. newPak.AddFromStream(ExtractFileName(oldPak.Files[i]),
  405. ExtractFilePath(oldPak.Files[i]), oldPak.GetFile(i));
  406. end;
  407. oldPak.Free;
  408. oldPak := nil;
  409. Pak := newPak;
  410. TreeViewRefresh;
  411. ListView.Enabled := True;
  412. RefreshMenu;
  413. end;
  414. end;
  415. // TForm1.ConverttouncompressedClick
  416. //
  417. procedure TForm1.ConverttouncompressedClick(Sender: TObject);
  418. var
  419. newPak, oldPak: TGLVfsPak;
  420. i: integer;
  421. oldFileName, newFileName: String;
  422. begin
  423. if not Pak.Compressed then
  424. exit;
  425. oldFileName := Pak.PakFileName;
  426. Pak.Free;
  427. Pak := nil;
  428. newFileName := ChangeFileExt(oldFileName, '.bak');
  429. if FileExists(newFileName) then
  430. DeleteFile(newFileName);
  431. RenameFile(oldFileName, newFileName);
  432. newPak := TGLVfsPak.Create(nil);
  433. newPak.LoadFromFile(oldFileName, fmCreate or fmShareDenyWrite);
  434. oldPak := TGLVfsPak.Create(nil);
  435. oldPak.LoadFromFile(newFileName, fmOpenRead or fmShareDenyWrite);
  436. for i := 0 to oldPak.FileCount - 1 do
  437. begin
  438. newPak.AddFromStream(ExtractFileName(oldPak.Files[i]),
  439. ExtractFilePath(oldPak.Files[i]), oldPak.GetFile(i));
  440. end;
  441. oldPak.Free;
  442. oldPak := nil;
  443. Pak := newPak;
  444. TreeViewRefresh;
  445. ListView.Enabled := True;
  446. RefreshMenu;
  447. end;
  448. // TForm1.RefreshMenu
  449. //
  450. procedure TForm1.RefreshMenu;
  451. begin
  452. Converttocompressed.Visible := not Pak.Compressed;
  453. Converttouncompressed.Visible := Pak.Compressed;
  454. end;
  455. end.