{ ***************************************************************************** This file is part of the Lazarus Component Library (LCL) See the file COPYING.modifiedLGPL.txt, included in this distribution, for details about the license. ***************************************************************************** Author: Mattias Gaertner } unit MacApplicationRes; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LazUTF8Classes, LazFileUtils; type EMacResourceException = Exception; procedure CreateMacOSXApplicationResources(const Filename, ReadmeTitle, ReadmeDescription: string); function GetMacOSXExecutableFilename(const BaseDir, ShortExeName: string): string; procedure CreateDirectoryInteractive(const Directory: string); implementation procedure CreateMacOSXApplicationResources(const Filename, ReadmeTitle, ReadmeDescription: string); { Filename.app/ Contents/ MacOS/ Executable Resources/ README.rtf PkgInfo Info.plist } procedure WriteInfoPlistFile(const Directory: string); var sl: TStringListUTF8; ExeName: String; PLInfoListFilename: String; begin ExeName:=ExtractFileName(Filename); PLInfoListFilename:=Directory+'Info.plist'; sl:=TStringListUTF8.Create; try sl.Add(''); sl.Add(''); sl.Add(''); sl.Add(''); sl.Add(' CFBundleDevelopmentRegion'); sl.Add(' English'); sl.Add(' CFBundleExecutable'); sl.Add(' '+ExeName+''); sl.Add(' CFBundleInfoDictionaryVersion'); sl.Add(' 6.0'); sl.Add(' CFBundlePackageType'); sl.Add(' APPL'); sl.Add(' CFBundleSignature'); sl.Add(' ????'); sl.Add(' CFBundleVersion'); sl.Add(' 1.0'); sl.Add(' CSResourcesFileMapped'); sl.Add(' '); // for accepting files dropped on the dock icon: sl.Add(' CFBundleDocumentTypes'); sl.Add(' '); sl.Add(' '); sl.Add(' CFBundleTypeRole'); sl.Add(' Viewer'); sl.Add(' CFBundleTypeExtensions'); sl.Add(' '); sl.Add(' *'); sl.Add(' '); sl.Add(' CFBundleTypeOSTypes'); sl.Add(' '); sl.Add(' fold'); sl.Add(' disk'); sl.Add(' ****'); sl.Add(' '); sl.Add(' '); sl.Add(' '); sl.Add(''); sl.Add(''); sl.SaveToFile(PLInfoListFilename); finally sl.Free; end; end; procedure WritePkgInfoFile(const Directory: string); var sl: TStringListUTF8; PkgInfoFilename: String; begin PkgInfoFilename:=Directory+'PkgInfo'; sl:=TStringListUTF8.Create; try sl.Add('APPL????'); sl.SaveToFile(PkgInfoFilename); finally sl.Free; end; end; procedure WriteREADMErtfFile(const Directory, Title, Description: string); var sl: TStringListUTF8; ReadmeFilename: String; begin ReadmeFilename:=Directory+'README.rtf'; sl:=TStringListUTF8.Create; try sl.Add('{\rtf1\mac\ansicpg10000\cocoartf102'); sl.Add('{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;}'); sl.Add('{\colortbl;\red255\green255\blue255;}'); sl.Add('\margl1440\margr1440\vieww9000\viewh9000\viewkind0'); sl.Add('\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural'); sl.Add(''); sl.Add('\f0\b\fs24 \cf0 '+Title); sl.Add('\f1\b0 \'); sl.Add('\'); sl.Add(Description); sl.Add('\'); sl.Add(''); sl.Add('}'); sl.SaveToFile(ReadmeFilename); finally sl.Free; end; end; var AppDir: String; ContentsDir: String; MacOSDir: String; ResourcesDir: String; begin // create 'applicationname.app/' directory AppDir:=Filename+'.app'+PathDelim; CreateDirectoryInteractive(AppDir); begin // create 'applicationname.app/Contents/' directory ContentsDir:=AppDir+'Contents'+PathDelim; CreateDirectoryInteractive(ContentsDir); begin // create 'applicationname.app/Contents/MacOS/' directory MacOSDir:=ContentsDir+'MacOS'+PathDelim; CreateDirectoryInteractive(MacOSDir); // create Info.plist file WriteInfoPlistFile(ContentsDir); // create PkgInfo file WritePkgInfoFile(ContentsDir); // create 'applicationname.app/Contents/Resources/' directory ResourcesDir:=ContentsDir+'Resources'+PathDelim; CreateDirectoryInteractive(ResourcesDir); // create README.rtf file WriteREADMErtfFile(ResourcesDir,ReadmeTitle,ReadmeDescription); end; end; end; function GetMacOSXExecutableFilename(const BaseDir, ShortExeName: string ): string; begin Result:=AppendPathDelim(BaseDir)+ShortExeName+'.app'+PathDelim +'Contents'+PathDelim+'MacOS'+ShortExeName; end; procedure CreateDirectoryInteractive(const Directory: string); begin if not CreateDirUTF8(Directory) then raise EMacResourceException.Create('creating directory '+Directory+' failed'); end; end.