/components/macfiles/macapplicationres.pas

http://github.com/graemeg/lazarus · Pascal · 187 lines · 154 code · 11 blank · 22 comment · 0 complexity · 0c3acfdcbffa9dfe1f44b33e3773dda4 MD5 · raw file

  1. {
  2. *****************************************************************************
  3. This file is part of the Lazarus Component Library (LCL)
  4. See the file COPYING.modifiedLGPL.txt, included in this distribution,
  5. for details about the license.
  6. *****************************************************************************
  7. Author: Mattias Gaertner
  8. }
  9. unit MacApplicationRes;
  10. {$mode objfpc}{$H+}
  11. interface
  12. uses
  13. Classes, SysUtils, LazUTF8Classes, LazFileUtils;
  14. type
  15. EMacResourceException = Exception;
  16. procedure CreateMacOSXApplicationResources(const Filename,
  17. ReadmeTitle, ReadmeDescription: string);
  18. function GetMacOSXExecutableFilename(const BaseDir, ShortExeName: string): string;
  19. procedure CreateDirectoryInteractive(const Directory: string);
  20. implementation
  21. procedure CreateMacOSXApplicationResources(const Filename,
  22. ReadmeTitle, ReadmeDescription: string);
  23. {
  24. Filename.app/
  25. Contents/
  26. MacOS/
  27. Executable
  28. Resources/
  29. README.rtf
  30. PkgInfo
  31. Info.plist
  32. }
  33. procedure WriteInfoPlistFile(const Directory: string);
  34. var
  35. sl: TStringListUTF8;
  36. ExeName: String;
  37. PLInfoListFilename: String;
  38. begin
  39. ExeName:=ExtractFileName(Filename);
  40. PLInfoListFilename:=Directory+'Info.plist';
  41. sl:=TStringListUTF8.Create;
  42. try
  43. sl.Add('<?xml version="1.0" encoding="UTF-8"?>');
  44. sl.Add('<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">');
  45. sl.Add('<plist version="1.0">');
  46. sl.Add('<dict>');
  47. sl.Add(' <key>CFBundleDevelopmentRegion</key>');
  48. sl.Add(' <string>English</string>');
  49. sl.Add(' <key>CFBundleExecutable</key>');
  50. sl.Add(' <string>'+ExeName+'</string>');
  51. sl.Add(' <key>CFBundleInfoDictionaryVersion</key>');
  52. sl.Add(' <string>6.0</string>');
  53. sl.Add(' <key>CFBundlePackageType</key>');
  54. sl.Add(' <string>APPL</string>');
  55. sl.Add(' <key>CFBundleSignature</key>');
  56. sl.Add(' <string>????</string>');
  57. sl.Add(' <key>CFBundleVersion</key>');
  58. sl.Add(' <string>1.0</string>');
  59. sl.Add(' <key>CSResourcesFileMapped</key>');
  60. sl.Add(' <true/>');
  61. // for accepting files dropped on the dock icon:
  62. sl.Add(' <key>CFBundleDocumentTypes</key>');
  63. sl.Add(' <array>');
  64. sl.Add(' <dict>');
  65. sl.Add(' <key>CFBundleTypeRole</key>');
  66. sl.Add(' <string>Viewer</string>');
  67. sl.Add(' <key>CFBundleTypeExtensions</key>');
  68. sl.Add(' <array>');
  69. sl.Add(' <string>*</string>');
  70. sl.Add(' </array>');
  71. sl.Add(' <key>CFBundleTypeOSTypes</key>');
  72. sl.Add(' <array>');
  73. sl.Add(' <string>fold</string>');
  74. sl.Add(' <string>disk</string>');
  75. sl.Add(' <string>****</string>');
  76. sl.Add(' </array>');
  77. sl.Add(' </dict>');
  78. sl.Add(' </array>');
  79. sl.Add('</dict>');
  80. sl.Add('</plist>');
  81. sl.SaveToFile(PLInfoListFilename);
  82. finally
  83. sl.Free;
  84. end;
  85. end;
  86. procedure WritePkgInfoFile(const Directory: string);
  87. var
  88. sl: TStringListUTF8;
  89. PkgInfoFilename: String;
  90. begin
  91. PkgInfoFilename:=Directory+'PkgInfo';
  92. sl:=TStringListUTF8.Create;
  93. try
  94. sl.Add('APPL????');
  95. sl.SaveToFile(PkgInfoFilename);
  96. finally
  97. sl.Free;
  98. end;
  99. end;
  100. procedure WriteREADMErtfFile(const Directory, Title, Description: string);
  101. var
  102. sl: TStringListUTF8;
  103. ReadmeFilename: String;
  104. begin
  105. ReadmeFilename:=Directory+'README.rtf';
  106. sl:=TStringListUTF8.Create;
  107. try
  108. sl.Add('{\rtf1\mac\ansicpg10000\cocoartf102');
  109. sl.Add('{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;}');
  110. sl.Add('{\colortbl;\red255\green255\blue255;}');
  111. sl.Add('\margl1440\margr1440\vieww9000\viewh9000\viewkind0');
  112. sl.Add('\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural');
  113. sl.Add('');
  114. sl.Add('\f0\b\fs24 \cf0 '+Title);
  115. sl.Add('\f1\b0 \');
  116. sl.Add('\');
  117. sl.Add(Description);
  118. sl.Add('\');
  119. sl.Add('');
  120. sl.Add('}');
  121. sl.SaveToFile(ReadmeFilename);
  122. finally
  123. sl.Free;
  124. end;
  125. end;
  126. var
  127. AppDir: String;
  128. ContentsDir: String;
  129. MacOSDir: String;
  130. ResourcesDir: String;
  131. begin
  132. // create 'applicationname.app/' directory
  133. AppDir:=Filename+'.app'+PathDelim;
  134. CreateDirectoryInteractive(AppDir);
  135. begin
  136. // create 'applicationname.app/Contents/' directory
  137. ContentsDir:=AppDir+'Contents'+PathDelim;
  138. CreateDirectoryInteractive(ContentsDir);
  139. begin
  140. // create 'applicationname.app/Contents/MacOS/' directory
  141. MacOSDir:=ContentsDir+'MacOS'+PathDelim;
  142. CreateDirectoryInteractive(MacOSDir);
  143. // create Info.plist file
  144. WriteInfoPlistFile(ContentsDir);
  145. // create PkgInfo file
  146. WritePkgInfoFile(ContentsDir);
  147. // create 'applicationname.app/Contents/Resources/' directory
  148. ResourcesDir:=ContentsDir+'Resources'+PathDelim;
  149. CreateDirectoryInteractive(ResourcesDir);
  150. // create README.rtf file
  151. WriteREADMErtfFile(ResourcesDir,ReadmeTitle,ReadmeDescription);
  152. end;
  153. end;
  154. end;
  155. function GetMacOSXExecutableFilename(const BaseDir, ShortExeName: string
  156. ): string;
  157. begin
  158. Result:=AppendPathDelim(BaseDir)+ShortExeName+'.app'+PathDelim
  159. +'Contents'+PathDelim+'MacOS'+ShortExeName;
  160. end;
  161. procedure CreateDirectoryInteractive(const Directory: string);
  162. begin
  163. if not CreateDirUTF8(Directory) then
  164. raise EMacResourceException.Create('creating directory '+Directory+' failed');
  165. end;
  166. end.