PageRenderTime 29ms CodeModel.GetById 19ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

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