You've already forked lazarus-ccr
iphonelazext: implemented creating/deleting xib files from inside of project options
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1214 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -50,7 +50,7 @@ type
|
||||
public
|
||||
//isiPhoneMenu :TIDEMenuCommand;
|
||||
constructor Create;
|
||||
procedure UpdateXCode(Sender: TObject);
|
||||
procedure UpdateXcode(Sender: TObject);
|
||||
procedure SimRun(Sender: TObject);
|
||||
//procedure isProjectClicked(Sender: TObject);
|
||||
end;
|
||||
@ -339,7 +339,7 @@ begin
|
||||
//isiPhoneMenu.Checked:=ProjOptions.isIPhoneApp;
|
||||
end;
|
||||
|
||||
procedure TiPhoneExtension.UpdateXCode(Sender: TObject);
|
||||
procedure TiPhoneExtension.UpdateXcode(Sender: TObject);
|
||||
var
|
||||
templates : TStringList;
|
||||
build : TStringList;
|
||||
|
@ -20,7 +20,8 @@ unit iPhoneExtOptions;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, iPhoneBundle, DOM, XMLRead, XMLConf, PlistFile;
|
||||
Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf,
|
||||
iPhoneBundle, DOM, XMLRead, XMLConf, XcodeUtils;
|
||||
|
||||
const
|
||||
DefaultResourceDir = 'Resources';
|
||||
@ -112,12 +113,6 @@ function EnvOptions: TiPhoneEnvironmentOptions;
|
||||
function ProjOptions: TiPhoneProjectOptions;
|
||||
|
||||
|
||||
type
|
||||
TSDKFoundEvent = procedure (const Version: String;
|
||||
const DeviceSDKName, DeviceSDKPath, SimSDKName, SimSDKPath: String) of object;
|
||||
|
||||
function ScanForSDK(const PlatformDir: String; FoundProc: TSDKFoundEvent): Boolean;
|
||||
|
||||
var
|
||||
iPhoneEnvGroup : Integer;
|
||||
iPhonePrjGroup : Integer;
|
||||
@ -409,101 +404,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
type
|
||||
TSDKDescription = record
|
||||
FullPath : String; {full SDK path}
|
||||
Name : String;
|
||||
Alternate : String; {alternate SDK -> iphonesimulator for iphoneos}
|
||||
Version : String;
|
||||
isSim : Boolean; {true for real iPhoneOS, false for iPhoneSimulator}
|
||||
end;
|
||||
|
||||
// todo: implement reading .plist via OSX functions! (in case a .plist format changes)
|
||||
function ReadSDKSettings(const FileName: String; var Descr: TSDKDescription): Boolean;
|
||||
var
|
||||
plist : TPListFile;
|
||||
begin
|
||||
Result:=False;
|
||||
plist:=TPListFile.Create(FileName);
|
||||
|
||||
Descr.Name:=plist.GetStrValue('CanonicalName');
|
||||
Descr.Alternate:=plist.GetStrValue('AlternateSDK');
|
||||
Descr.Version:=plist.GetStrValue('Version');
|
||||
|
||||
plist.Free;
|
||||
end;
|
||||
|
||||
function isSDKDir(const SDKDir: String; var d: TSDKDescription): Boolean;
|
||||
var
|
||||
plist : String;
|
||||
begin
|
||||
plist := IncludeTrailingPathDelimiter(SDKDir)+'SDKSettings.plist';
|
||||
Result:=FileExists(plist);
|
||||
if not Result then Exit;
|
||||
ReadSDKSettings(plist, d);
|
||||
d.FullPath:=SDKDir;
|
||||
end;
|
||||
|
||||
function ScanForSDK(const PlatformDir: String; FoundProc: TSDKFoundEvent): Boolean;
|
||||
const
|
||||
PlatformName: array [Boolean] of String = ('iPhoneOS.platform','iPhoneSimulator.platform');
|
||||
SDKSubDir = PathDelim+'Developer'+PathDelim+'SDKs'+PathDelim;
|
||||
var
|
||||
isSim : Boolean;
|
||||
dir : String;
|
||||
sr : TSearchRec;
|
||||
sdks : array of TSDKDescription;
|
||||
descr : TSDKDescription;
|
||||
cnt : Integer;
|
||||
simname : String;
|
||||
simpath : String;
|
||||
i,j : Integer;
|
||||
|
||||
procedure AddDescription(const d: TSDKDescription);
|
||||
begin
|
||||
if cnt = length(sdks) then begin
|
||||
if cnt = 0 then SetLength(sdks, 16)
|
||||
else SetLength(sdks, cnt*2);
|
||||
end;
|
||||
sdks[cnt]:=d;
|
||||
inc(cnt);
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=Assigned(FoundProc);
|
||||
if not Result then Exit;
|
||||
|
||||
cnt:=0;
|
||||
|
||||
for isSim:=false to true do begin
|
||||
dir := IncludeTrailingPathDelimiter(PlatformDir) + PlatformName[isSim] + SDKSubDir;
|
||||
if FindFirst(dir+'*', faAnyFile, sr)=0 then begin
|
||||
repeat
|
||||
if (sr.Attr and faDirectory>0) and (ExtractFileExt(sr.Name) = '.sdk') then
|
||||
if isSDKDir( dir + sr.Name, descr) then begin
|
||||
descr.isSim:=isSim;
|
||||
AddDescription(descr);
|
||||
end;
|
||||
until FindNext(sr)<>0;
|
||||
FindClose(sr);
|
||||
end;
|
||||
end;
|
||||
|
||||
for i:=0 to cnt-1 do
|
||||
if not sdks[i].isSim then begin
|
||||
simname:='';
|
||||
simpath:='';
|
||||
for j:=0 to cnt-1 do
|
||||
if (sdks[j].isSim) and (sdks[i].Alternate=sdks[j].Name) then begin
|
||||
simname:=sdks[j].Name;
|
||||
simpath:=sdks[j].FullPath;
|
||||
end;
|
||||
FoundProc(sdks[i].Version, sdks[i].Name, sdks[i].FullPath, simname, simpath);
|
||||
end;
|
||||
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
initialization
|
||||
InitOptions;
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
<Description Value="iPhone Development Lazarus extension"/>
|
||||
<License Value="LGPL"/>
|
||||
<Version Minor="6"/>
|
||||
<Files Count="11">
|
||||
<Files Count="13">
|
||||
<Item1>
|
||||
<Filename Value="ideext.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
@ -64,6 +64,14 @@
|
||||
<Filename Value="lazfilesutils.pas"/>
|
||||
<UnitName Value="lazfilesutils"/>
|
||||
</Item11>
|
||||
<Item12>
|
||||
<Filename Value="xcodeutils.pas"/>
|
||||
<UnitName Value="xcodeutils"/>
|
||||
</Item12>
|
||||
<Item13>
|
||||
<Filename Value="newxibdialog.pas"/>
|
||||
<UnitName Value="newxibdialog"/>
|
||||
</Item13>
|
||||
</Files>
|
||||
<Type Value="RunAndDesignTime"/>
|
||||
<RequiredPkgs Count="3">
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ This file was automatically created by Lazarus. do not edit!
|
||||
{ This file was automatically created by Lazarus. Do not edit!
|
||||
This source is only used to compile and install the package.
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ interface
|
||||
uses
|
||||
ideext, iPhoneExtStr, iPhoneBundle, XCodeProject,
|
||||
environment_iphone_options, project_iphone_options, iPhoneExtOptions,
|
||||
xcodetemplate, lazfilesutils, LazarusPackageIntf;
|
||||
xcodetemplate, LazFilesUtils, XcodeUtils, newXibDialog, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
* *
|
||||
*****************************************************************************
|
||||
}
|
||||
unit lazfilesutils;
|
||||
unit LazFilesUtils;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
@ -21,8 +21,7 @@ interface
|
||||
uses
|
||||
{$ifdef Unix}BaseUnix,{$endif}
|
||||
Classes, SysUtils, FileUtil, Masks,
|
||||
LazIDEIntf,ProjectIntf;
|
||||
|
||||
LazIDEIntf, ProjectIntf, process;
|
||||
|
||||
function ResolveProjectPath(const path: string; project: TLazProject = nil): string;
|
||||
|
||||
@ -33,6 +32,10 @@ function NeedQuotes(const path: string): Boolean;
|
||||
|
||||
function CopySymLinks(const SrcDir, DstDir, FilterMask: string): Boolean;
|
||||
|
||||
procedure EnumFilesAtDir(const PathUtf8 : AnsiString; Dst: TStrings);
|
||||
procedure EnumFilesAtDir(const PathUtf8, AMask : AnsiString; Dst: TStrings);
|
||||
procedure ExecCmdLineNoWait(const CmdLineUtf8: AnsiString);
|
||||
|
||||
implementation
|
||||
|
||||
{$ifdef Unix}
|
||||
@ -177,5 +180,47 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure EnumFilesAtDir(const PathUtf8, AMask : AnsiString; Dst: TStrings);
|
||||
var
|
||||
mask : TMask;
|
||||
sr : TSearchRec;
|
||||
path : AnsiString;
|
||||
begin
|
||||
if (AMask='') or (trim(AMask)='*') then mask:=nil else mask:=TMask.Create(AMask);
|
||||
try
|
||||
path:=IncludeTrailingPathDelimiter(PathUtf8);
|
||||
if FindFirstUTF8(path+AllFilesMask, faAnyFile, sr) = 0 then begin
|
||||
repeat
|
||||
if (sr.Name<>'.') and (sr.Name<>'..') then
|
||||
if not Assigned(mask) or mask.Matches(sr.Name) then
|
||||
Dst.Add(path+sr.Name);
|
||||
until FindNextUTF8(sr)<>0;
|
||||
FindCloseUTF8(sr);
|
||||
end;
|
||||
finally
|
||||
mask.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure EnumFilesAtDir(const PathUtf8 : AnsiString; Dst: TStrings);
|
||||
begin
|
||||
EnumFilesAtDir(PathUTF8, AllFilesMask, Dst);
|
||||
end;
|
||||
|
||||
procedure ExecCmdLineNoWait(const CmdLineUtf8: AnsiString);
|
||||
var
|
||||
proc : TProcess;
|
||||
begin
|
||||
proc:=TProcess.Create(nil);
|
||||
try
|
||||
proc.CommandLine:=CmdLineUtf8;
|
||||
//proc.WaitOnExit:=WaitExit;
|
||||
proc.Execute;
|
||||
finally
|
||||
proc.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
81
components/iphonelazext/newxibdialog.lfm
Normal file
81
components/iphonelazext/newxibdialog.lfm
Normal file
@ -0,0 +1,81 @@
|
||||
object newXibForm: TnewXibForm
|
||||
Left = 583
|
||||
Height = 447
|
||||
Top = 195
|
||||
Width = 477
|
||||
BorderIcons = [biSystemMenu]
|
||||
BorderStyle = bsDialog
|
||||
Caption = 'Choose a template'
|
||||
ClientHeight = 447
|
||||
ClientWidth = 477
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
LCLVersion = '0.9.29'
|
||||
object Edit1: TEdit
|
||||
Left = 94
|
||||
Height = 22
|
||||
Top = 24
|
||||
Width = 370
|
||||
OnKeyPress = Edit1KeyPress
|
||||
TabOrder = 0
|
||||
Text = 'Edit1'
|
||||
end
|
||||
object Label1: TLabel
|
||||
Left = 16
|
||||
Height = 18
|
||||
Top = 24
|
||||
Width = 61
|
||||
Caption = 'FileName:'
|
||||
ParentColor = False
|
||||
end
|
||||
object DrawGrid1: TDrawGrid
|
||||
Left = 16
|
||||
Height = 200
|
||||
Top = 64
|
||||
Width = 448
|
||||
ColCount = 1
|
||||
DefaultColWidth = 80
|
||||
DefaultDrawing = False
|
||||
DefaultRowHeight = 96
|
||||
ExtendedSelect = False
|
||||
FixedCols = 0
|
||||
FixedRows = 0
|
||||
GridLineWidth = 0
|
||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goSmoothScroll]
|
||||
ScrollBars = ssVertical
|
||||
TabOrder = 1
|
||||
OnDrawCell = DrawGrid1DrawCell
|
||||
OnSelection = DrawGrid1Selection
|
||||
OnSelectCell = DrawGrid1SelectCell
|
||||
end
|
||||
object Button1: TButton
|
||||
Left = 160
|
||||
Height = 20
|
||||
Top = 400
|
||||
Width = 70
|
||||
AutoSize = True
|
||||
Caption = 'Cancel'
|
||||
ModalResult = 2
|
||||
TabOrder = 2
|
||||
end
|
||||
object Button2: TButton
|
||||
Left = 248
|
||||
Height = 20
|
||||
Top = 400
|
||||
Width = 71
|
||||
AutoSize = True
|
||||
Caption = 'Choose'
|
||||
ModalResult = 1
|
||||
OnClick = Button2Click
|
||||
TabOrder = 3
|
||||
end
|
||||
object Memo1: TMemo
|
||||
Left = 16
|
||||
Height = 112
|
||||
Top = 272
|
||||
Width = 448
|
||||
ReadOnly = True
|
||||
ScrollBars = ssAutoVertical
|
||||
TabOrder = 4
|
||||
end
|
||||
end
|
228
components/iphonelazext/newxibdialog.pas
Normal file
228
components/iphonelazext/newxibdialog.pas
Normal file
@ -0,0 +1,228 @@
|
||||
unit newXibDialog;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
MacOSAll,
|
||||
Types,Classes,SysUtils,FileUtil,LResources,Forms,Controls,Graphics,Dialogs,StdCtrls,LCLProc,
|
||||
Grids,
|
||||
//todo: use LCL file loading and drawing, instead of OSX
|
||||
CarbonGDIObjects, CarbonProc;
|
||||
|
||||
type
|
||||
|
||||
{ TnewXibForm }
|
||||
|
||||
TnewXibForm = class(TForm)
|
||||
Button1:TButton;
|
||||
Button2:TButton;
|
||||
DrawGrid1:TDrawGrid;
|
||||
Edit1:TEdit;
|
||||
Label1:TLabel;
|
||||
Memo1:TMemo;
|
||||
procedure Button2Click(Sender:TObject);
|
||||
procedure DrawGrid1DrawCell(Sender:TObject;aCol,aRow:Integer;aRect:TRect;
|
||||
aState:TGridDrawState);
|
||||
procedure DrawGrid1SelectCell(Sender:TObject;aCol,aRow:Integer;var CanSelect
|
||||
:Boolean);
|
||||
procedure DrawGrid1Selection(Sender:TObject;aCol,aRow:Integer);
|
||||
procedure Edit1KeyPress(Sender:TObject;var Key:char);
|
||||
procedure FormCreate(Sender:TObject);
|
||||
procedure FormDestroy(Sender:TObject);
|
||||
private
|
||||
{ private declarations }
|
||||
SelectedXib : String;
|
||||
Items : TList;
|
||||
CustomName : Boolean;
|
||||
public
|
||||
{ public declarations }
|
||||
procedure AddTemplate(const AName, SourceXibFile, ADescr, IconFile: AnsiString);
|
||||
function Execute(var FileName, SourceXibFile: AnsiString): Boolean;
|
||||
end;
|
||||
|
||||
var
|
||||
newXibForm: TnewXibForm;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.lfm}
|
||||
|
||||
type
|
||||
|
||||
{ TXibItem }
|
||||
|
||||
TXibItem = class(TObject)
|
||||
image : TBitmap;
|
||||
sourcefile : AnsiString;
|
||||
descr : AnsiString;
|
||||
name : AnsiString;
|
||||
constructor Create(const AName, ASourceFile, ADescr, IconFileName: AnsiString);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
{ TXibItem }
|
||||
|
||||
constructor TXibItem.Create(const AName,ASourceFile,ADescr, IconFileName:AnsiString);
|
||||
var
|
||||
url : CFURLRef;
|
||||
data : CGImageSourceRef;
|
||||
cf : CFStringRef;
|
||||
img : CGImageRef;
|
||||
ctx : CGContextRef;
|
||||
space : CGColorSpaceRef;
|
||||
r : CGRect;
|
||||
w : WideString;
|
||||
begin
|
||||
inherited Create;
|
||||
|
||||
w:=UTF8Decode(AName);
|
||||
if w<>'' then w[1]:=WideUpperCase(w[1])[1];
|
||||
name:=UTF8Encode(w);
|
||||
|
||||
sourcefile:=ASourceFile;
|
||||
descr:=ADescr;
|
||||
|
||||
if IconFileName<>'' then begin
|
||||
CreateCFString(IconFileName, cf);
|
||||
url:=CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault , cf,
|
||||
kCFURLPOSIXPathStyle, false, nil);
|
||||
data:=CGImageSourceCreateWithURL(url, nil);
|
||||
img:=CGImageSourceCreateImageAtIndex(data, 0, nil);
|
||||
|
||||
image:=TBitmap.Create;
|
||||
image.PixelFormat:=pf32bit;
|
||||
image.SetSize( 64, 64);
|
||||
image.BeginUpdate;
|
||||
space:=CGColorSpaceCreateDeviceRGB;
|
||||
ctx:=CGBitmapContextCreate(image.RawImage.Data, image.Width, image.Height, 8,
|
||||
image.Width*4, space, kCGImageAlphaPremultipliedFirst);
|
||||
|
||||
r.origin.x:=0; r.origin.y:=0;
|
||||
r.size.width:=image.Width; r.size.height:=image.Height;
|
||||
CGColorSpaceRelease(space);
|
||||
CGContextDrawImage(ctx, r, img);
|
||||
CGContextRelease(ctx);
|
||||
image.EndUpdate;
|
||||
CFRelease(img);
|
||||
CFRelease(data);
|
||||
CFRelease(url);
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TXibItem.Destroy;
|
||||
begin
|
||||
image.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TnewXibForm }
|
||||
|
||||
procedure TnewXibForm.FormCreate(Sender:TObject);
|
||||
begin
|
||||
Items:=TList.Create;
|
||||
end;
|
||||
|
||||
procedure TnewXibForm.DrawGrid1DrawCell(Sender:TObject;aCol,aRow:Integer;aRect:
|
||||
TRect;aState:TGridDrawState);
|
||||
var
|
||||
info : TXibItem;
|
||||
sz : TSize;
|
||||
x,y : Integer;
|
||||
idx : integer;
|
||||
begin
|
||||
idx:=DrawGrid1.ColCount*aRow+aCol;
|
||||
if (idx>=0) and (idx<Items.Count) then
|
||||
info:=TXibItem(Items[idx])
|
||||
else
|
||||
info:=nil;
|
||||
if not Assigned(info) then Exit;
|
||||
|
||||
if gdSelected in aState then begin
|
||||
DrawGrid1.Canvas.Brush.Color:=clHighlight;
|
||||
DrawGrid1.Canvas.Font.Color:=clHighlightText;
|
||||
end else begin
|
||||
DrawGrid1.Canvas.Brush.Color:=clWindow;
|
||||
DrawGrid1.Canvas.Font.Color:=clWindowText;
|
||||
end;
|
||||
|
||||
DrawGrid1.Canvas.FillRect(aRect);
|
||||
|
||||
if Assigned(info.image) then
|
||||
DrawGrid1.Canvas.Draw(aRect.Left+4, aRect.Top, info.image);
|
||||
|
||||
sz:=DrawGrid1.Canvas.TextExtent(info.name);
|
||||
x:=aRect.Left+ ((aRect.Right-aRect.Left) - sz.cx) div 2;
|
||||
y:=aRect.Top + info.image.Height+4;
|
||||
DrawGrid1.Canvas.TextOut(x, y, info.name);
|
||||
end;
|
||||
|
||||
procedure TnewXibForm.Button2Click(Sender:TObject);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TnewXibForm.DrawGrid1SelectCell(Sender:TObject;aCol,aRow:Integer;var
|
||||
CanSelect:Boolean);
|
||||
var
|
||||
idx : integer;
|
||||
begin
|
||||
idx:=DrawGrid1.ColCount*aRow+aCol;
|
||||
CanSelect:=(idx>=0) and (idx<Items.Count);
|
||||
if CanSelect then begin
|
||||
Memo1.Text:=TXibItem(Items[idx]).descr;
|
||||
if not CustomName then
|
||||
Edit1.Text:=TXibItem(Items[idx]).name;
|
||||
SelectedXib:=TXibItem(Items[idx]).sourcefile;
|
||||
end else begin
|
||||
Memo1.Text:='';
|
||||
SelectedXib:='';
|
||||
end;
|
||||
Button2.Enabled:=CanSelect;
|
||||
end;
|
||||
|
||||
procedure TnewXibForm.DrawGrid1Selection(Sender:TObject;aCol,aRow:Integer);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TnewXibForm.Edit1KeyPress(Sender:TObject;var Key:char);
|
||||
begin
|
||||
CustomName:=True;
|
||||
end;
|
||||
|
||||
procedure TnewXibForm.FormDestroy(Sender:TObject);
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
for i:=0 to Items.Count-1 do TObject(Items[i]).Free;
|
||||
end;
|
||||
|
||||
procedure TnewXibForm.AddTemplate(const AName,SourceXibFile,ADescr, IconFile:AnsiString);
|
||||
begin
|
||||
Items.Add( TXibItem.Create(AName, SourceXibFile, ADescr, IconFile));
|
||||
end;
|
||||
|
||||
function TnewXibForm.Execute(var FileName,SourceXibFile:AnsiString):Boolean;
|
||||
var
|
||||
w : integer;
|
||||
begin
|
||||
if Items.Count=0 then begin
|
||||
Result:=False;
|
||||
Exit;
|
||||
end;
|
||||
w:=DrawGrid1.ClientWidth div DrawGrid1.DefaultColWidth;
|
||||
if w=0 then w:=1;
|
||||
DrawGrid1.ColCount:=w;
|
||||
DrawGrid1.RowCount:=Items.Count div w;
|
||||
CustomName:=False;
|
||||
Result:=ShowModal = mrOK;
|
||||
if Result then begin
|
||||
FileName:=Edit1.Text;
|
||||
SourceXibFile:=SelectedXib;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -4,8 +4,8 @@ inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor
|
||||
ClientHeight = 474
|
||||
ClientWidth = 620
|
||||
OnClick = FrameClick
|
||||
DesignLeft = 611
|
||||
DesignTop = 128
|
||||
DesignLeft = 463
|
||||
DesignTop = 306
|
||||
object chkisPhone: TCheckBox[0]
|
||||
Left = 16
|
||||
Height = 18
|
||||
@ -154,7 +154,31 @@ inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor
|
||||
OnClick = btnShowInFinderClick
|
||||
TabOrder = 6
|
||||
end
|
||||
object nibsPopup: TPopupMenu[15]
|
||||
object btnAddXib: TButton[15]
|
||||
AnchorSideLeft.Control = btnRemoveXib
|
||||
AnchorSideRight.Control = btnRemoveXib
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 40
|
||||
Height = 20
|
||||
Top = 283
|
||||
Width = 74
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
AutoSize = True
|
||||
Caption = 'Add'
|
||||
OnClick = btnAddXibClick
|
||||
TabOrder = 7
|
||||
end
|
||||
object btnRemoveXib: TButton[16]
|
||||
Left = 40
|
||||
Height = 20
|
||||
Top = 312
|
||||
Width = 74
|
||||
AutoSize = True
|
||||
Caption = 'Remove'
|
||||
OnClick = btnRemoveXibClick
|
||||
TabOrder = 8
|
||||
end
|
||||
object nibsPopup: TPopupMenu[17]
|
||||
OnPopup = nibsPopupPopup
|
||||
left = 256
|
||||
top = 288
|
||||
|
@ -3,7 +3,7 @@
|
||||
LazarusResources.Add('TiPhoneProjectOptionsEditor','FORMDATA',[
|
||||
'TPF0'#241#27'TiPhoneProjectOptionsEditor'#26'iPhoneProjectOptionsEditor'#6'H'
|
||||
+'eight'#3#218#1#5'Width'#3'l'#2#12'ClientHeight'#3#218#1#11'ClientWidth'#3'l'
|
||||
+#2#7'OnClick'#7#10'FrameClick'#10'DesignLeft'#3'c'#2#9'DesignTop'#3#128#0#0
|
||||
+#2#7'OnClick'#7#10'FrameClick'#10'DesignLeft'#3#207#1#9'DesignTop'#3'2'#1#0
|
||||
+#242#2#0#9'TCheckBox'#10'chkisPhone'#4'Left'#2#16#6'Height'#2#18#3'Top'#2#16
|
||||
+#5'Width'#3#199#0#7'Caption'#6#29'is iPhone application project'#8'OnChange'
|
||||
+#7#16'chkisPhoneChange'#8'TabOrder'#2#0#0#0#242#2#1#6'TLabel'#8'lblAppID'#4
|
||||
@ -46,8 +46,15 @@ LazarusResources.Add('TiPhoneProjectOptionsEditor','FORMDATA',[
|
||||
+'t'#2#246#11'ParentColor'#8#10'ParentFont'#8#0#0#242#2#14#7'TButton'#15'btnS'
|
||||
+'howInFinder'#4'Left'#3#229#1#6'Height'#2#20#3'Top'#3#176#0#5'Width'#2'u'#7
|
||||
+'Anchors'#11#5'akTop'#7'akRight'#0#8'AutoSize'#9#7'Caption'#6#14'Show in Fin'
|
||||
+'der'#7'OnClick'#7#20'btnShowInFinderClick'#8'TabOrder'#2#6#0#0#242#2#15#10
|
||||
+'TPopupMenu'#9'nibsPopup'#7'OnPopup'#7#14'nibsPopupPopup'#4'left'#3#0#1#3'to'
|
||||
+'p'#3' '#1#0#9'TMenuItem'#9'mnuOpenIB'#7'Caption'#6#22'Open Interface Builde'
|
||||
+'r'#7'OnClick'#7#14'mnuOpenIBClick'#0#0#0#0
|
||||
+'der'#7'OnClick'#7#20'btnShowInFinderClick'#8'TabOrder'#2#6#0#0#242#2#15#7'T'
|
||||
+'Button'#9'btnAddXib'#22'AnchorSideLeft.Control'#7#12'btnRemoveXib'#23'Ancho'
|
||||
+'rSideRight.Control'#7#12'btnRemoveXib'#20'AnchorSideRight.Side'#7#9'asrBott'
|
||||
+'om'#4'Left'#2'('#6'Height'#2#20#3'Top'#3#27#1#5'Width'#2'J'#7'Anchors'#11#5
|
||||
+'akTop'#6'akLeft'#7'akRight'#0#8'AutoSize'#9#7'Caption'#6#3'Add'#7'OnClick'#7
|
||||
+#14'btnAddXibClick'#8'TabOrder'#2#7#0#0#242#2#16#7'TButton'#12'btnRemoveXib'
|
||||
+#4'Left'#2'('#6'Height'#2#20#3'Top'#3'8'#1#5'Width'#2'J'#8'AutoSize'#9#7'Cap'
|
||||
+'tion'#6#6'Remove'#7'OnClick'#7#17'btnRemoveXibClick'#8'TabOrder'#2#8#0#0#242
|
||||
+#2#17#10'TPopupMenu'#9'nibsPopup'#7'OnPopup'#7#14'nibsPopupPopup'#4'left'#3#0
|
||||
+#1#3'top'#3' '#1#0#9'TMenuItem'#9'mnuOpenIB'#7'Caption'#6#22'Open Interface '
|
||||
+'Builder'#7'OnClick'#7#14'mnuOpenIBClick'#0#0#0#0
|
||||
]);
|
||||
|
@ -19,9 +19,9 @@ unit project_iphone_options;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,SysUtils,FileUtil,LResources,Forms,StdCtrls,Masks,CheckLst,Buttons,
|
||||
Classes,SysUtils,FileUtil,LResources,Forms,StdCtrls,CheckLst,Buttons, Dialogs,
|
||||
Menus,IDEOptionsIntf,ProjectIntf,LazIDEIntf,iPhoneExtStr,
|
||||
iPhoneExtOptions, process, Controls;
|
||||
iPhoneExtOptions, Controls, LazFilesUtils, XcodeUtils, newXibDialog;
|
||||
|
||||
type
|
||||
|
||||
@ -29,6 +29,8 @@ type
|
||||
|
||||
TiPhoneProjectOptionsEditor = class(TAbstractIDEOptionsEditor)
|
||||
btnShowInFinder:TButton;
|
||||
btnAddXib:TButton;
|
||||
btnRemoveXib:TButton;
|
||||
Label5:TLabel;
|
||||
mnuOpenIB:TMenuItem;
|
||||
nibFilesBox:TCheckListBox;
|
||||
@ -45,7 +47,10 @@ type
|
||||
lblAppIDHint: TLabel;
|
||||
lblSDKVer: TLabel;
|
||||
nibsPopup:TPopupMenu;
|
||||
procedure btnAddXibClick(Sender:TObject);
|
||||
procedure btnRemoveXibClick(Sender:TObject);
|
||||
procedure btnShowInFinderClick(Sender:TObject);
|
||||
procedure Button1Click(Sender:TObject);
|
||||
procedure chkisPhoneChange(Sender:TObject);
|
||||
procedure cmbSDKsChange(Sender: TObject);
|
||||
procedure edtExcludeChange(Sender: TObject);
|
||||
@ -81,47 +86,8 @@ type
|
||||
property OnChanged: TNotifyEvent read fOnChanged write fOnChanged;
|
||||
end;
|
||||
|
||||
procedure EnumFilesAtDir(const PathUtf8, AMask : AnsiString; Dst: TStrings);
|
||||
procedure ExecCmdLineNoWait(const CmdLineUtf8: AnsiString);
|
||||
|
||||
implementation
|
||||
|
||||
procedure EnumFilesAtDir(const PathUtf8, AMask : AnsiString; Dst: TStrings);
|
||||
var
|
||||
mask : TMask;
|
||||
sr : TSearchRec;
|
||||
path : AnsiString;
|
||||
begin
|
||||
if (AMask='') or (trim(AMask)='*') then mask:=nil else mask:=TMask.Create(AMask);
|
||||
try
|
||||
path:=IncludeTrailingPathDelimiter(PathUtf8);
|
||||
if FindFirstUTF8(path+AllFilesMask, faAnyFile, sr) = 0 then begin
|
||||
repeat
|
||||
if (sr.Name<>'.') and (sr.Name<>'..') then
|
||||
if not Assigned(mask) or mask.Matches(sr.Name) then
|
||||
Dst.Add(path+sr.Name);
|
||||
until FindNextUTF8(sr)<>0;
|
||||
FindCloseUTF8(sr);
|
||||
end;
|
||||
finally
|
||||
mask.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ExecCmdLineNoWait(const CmdLineUtf8: AnsiString);
|
||||
var
|
||||
proc : TProcess;
|
||||
begin
|
||||
proc:=TProcess.Create(nil);
|
||||
try
|
||||
proc.CommandLine:=CmdLineUtf8;
|
||||
//proc.WaitOnExit:=WaitExit;
|
||||
proc.Execute;
|
||||
finally
|
||||
proc.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TiPhoneProjectOptionsEditor }
|
||||
|
||||
procedure TiPhoneProjectOptionsEditor.cmbSDKsChange(Sender: TObject);
|
||||
@ -148,6 +114,49 @@ begin
|
||||
if DirectoryExistsUTF8(path) then ExecCmdLineNoWait('open "'+path +'"');
|
||||
end;
|
||||
|
||||
procedure TiPhoneProjectOptionsEditor.btnAddXibClick(Sender:TObject);
|
||||
var
|
||||
FileName : AnsiString;
|
||||
SrcXib : AnsiString;
|
||||
|
||||
ResDir : AnsiString;
|
||||
begin
|
||||
newXibForm:=TnewXibForm.Create(Self);
|
||||
ScanForXibTemplates(
|
||||
XibTemplateDir( IncludeTrailingPathDelimiter(EnvOptions.PlatformsBaseDir)+iPhoneOSplatform),
|
||||
@newXibForm.AddTemplate);
|
||||
|
||||
if (newXibForm.Execute(FileName, SrcXib)) and (SrcXib<>'')then begin
|
||||
ResDir:=edtResDir.Text;
|
||||
LazarusIDE.ActiveProject.LongenFilename(ResDir);
|
||||
|
||||
ForceDirectoriesUTF8(ResDir);
|
||||
if not CopyFile(SrcXib, ChangeFileExt(IncludeTrailingPathDelimiter(ResDir)+FileName,'.xib')) then
|
||||
ShowMessage('Failed to create Nib file');
|
||||
RefreshXIBList;
|
||||
end;
|
||||
newXibForm.Free;
|
||||
newXibForm:=nil;
|
||||
end;
|
||||
|
||||
procedure TiPhoneProjectOptionsEditor.btnRemoveXibClick(Sender:TObject);
|
||||
var
|
||||
XibName : AnsiString;
|
||||
begin
|
||||
if nibFilesBox.ItemIndex<0 then Exit;
|
||||
|
||||
XibName:=edtResDir.Text;
|
||||
LazarusIDE.ActiveProject.LongenFilename(XibName);
|
||||
|
||||
XibName:=ChangeFileExt(IncludeTrailingPathDelimiter(XibName)+nibFilesBox.Items[nibFilesBox.ItemIndex],'.xib');
|
||||
if FileExistsUTF8(XibName) then DeleteFileUTF8(XibName);
|
||||
RefreshXIBList;
|
||||
end;
|
||||
|
||||
procedure TiPhoneProjectOptionsEditor.Button1Click(Sender:TObject);
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure TiPhoneProjectOptionsEditor.chkisPhoneChange(Sender:TObject);
|
||||
begin
|
||||
SetControlsEnabled(chkisPhone.Checked);
|
||||
|
186
components/iphonelazext/xcodeutils.pas
Normal file
186
components/iphonelazext/xcodeutils.pas
Normal file
@ -0,0 +1,186 @@
|
||||
unit XcodeUtils;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, PlistFile, LazFilesUtils;
|
||||
|
||||
const
|
||||
iPhoneOSplatform = 'iPhoneOS.platform';
|
||||
|
||||
// file names should utf8 encoded
|
||||
|
||||
|
||||
// Scanning Xcode platform for available SDKs
|
||||
|
||||
type
|
||||
TSDKFoundEvent = procedure (const Version: String;
|
||||
const DeviceSDKName, DeviceSDKPath, SimSDKName, SimSDKPath: String) of object;
|
||||
|
||||
function ScanForSDK(const PlatformDir: String; FoundProc: TSDKFoundEvent): Boolean;
|
||||
|
||||
// Scanning for Templates
|
||||
|
||||
function XibTemplateDir(const PlatformDir: AnsiString): AnsiString;
|
||||
|
||||
type
|
||||
TScanTemplateProc = procedure ( const TemplateName, XibFileName,
|
||||
Description, IconFileName: AnsiString) of object;
|
||||
|
||||
procedure ScanForXibTemplates(const TemplateDir: AnsiString; Callback: TScanTemplateProc);
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
TSDKDescription = record
|
||||
FullPath : String; {full SDK path}
|
||||
Name : String;
|
||||
Alternate : String; {alternate SDK -> iphonesimulator for iphoneos}
|
||||
Version : String;
|
||||
isSim : Boolean; {true for real iPhoneOS, false for iPhoneSimulator}
|
||||
end;
|
||||
|
||||
function ReadSDKSettings(const FileName: String; var Descr: TSDKDescription): Boolean;
|
||||
var
|
||||
plist : TPListFile;
|
||||
begin
|
||||
Result:=False;
|
||||
plist:=TPListFile.Create(FileName);
|
||||
|
||||
Descr.Name:=plist.GetStrValue('CanonicalName');
|
||||
Descr.Alternate:=plist.GetStrValue('AlternateSDK');
|
||||
Descr.Version:=plist.GetStrValue('Version');
|
||||
|
||||
plist.Free;
|
||||
end;
|
||||
|
||||
function isSDKDir(const SDKDir: String; var d: TSDKDescription): Boolean;
|
||||
var
|
||||
plist : String;
|
||||
begin
|
||||
plist := IncludeTrailingPathDelimiter(SDKDir)+'SDKSettings.plist';
|
||||
Result:=FileExists(plist);
|
||||
if not Result then Exit;
|
||||
ReadSDKSettings(plist, d);
|
||||
d.FullPath:=SDKDir;
|
||||
end;
|
||||
|
||||
function ScanForSDK(const PlatformDir: String; FoundProc: TSDKFoundEvent): Boolean;
|
||||
const
|
||||
PlatformName: array [Boolean] of String = ('iPhoneOS.platform','iPhoneSimulator.platform');
|
||||
SDKSubDir = PathDelim+'Developer'+PathDelim+'SDKs'+PathDelim;
|
||||
var
|
||||
isSim : Boolean;
|
||||
dir : String;
|
||||
sr : TSearchRec;
|
||||
sdks : array of TSDKDescription;
|
||||
descr : TSDKDescription;
|
||||
cnt : Integer;
|
||||
simname : String;
|
||||
simpath : String;
|
||||
i,j : Integer;
|
||||
|
||||
procedure AddDescription(const d: TSDKDescription);
|
||||
begin
|
||||
if cnt = length(sdks) then begin
|
||||
if cnt = 0 then SetLength(sdks, 16)
|
||||
else SetLength(sdks, cnt*2);
|
||||
end;
|
||||
sdks[cnt]:=d;
|
||||
inc(cnt);
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=Assigned(FoundProc);
|
||||
if not Result then Exit;
|
||||
|
||||
cnt:=0;
|
||||
|
||||
for isSim:=false to true do begin
|
||||
dir := IncludeTrailingPathDelimiter(PlatformDir) + PlatformName[isSim] + SDKSubDir;
|
||||
if FindFirst(dir+'*', faAnyFile, sr)=0 then begin
|
||||
repeat
|
||||
if (sr.Attr and faDirectory>0) and (ExtractFileExt(sr.Name) = '.sdk') then
|
||||
if isSDKDir( dir + sr.Name, descr) then begin
|
||||
descr.isSim:=isSim;
|
||||
AddDescription(descr);
|
||||
end;
|
||||
until FindNext(sr)<>0;
|
||||
FindClose(sr);
|
||||
end;
|
||||
end;
|
||||
|
||||
for i:=0 to cnt-1 do
|
||||
if not sdks[i].isSim then begin
|
||||
simname:='';
|
||||
simpath:='';
|
||||
for j:=0 to cnt-1 do
|
||||
if (sdks[j].isSim) and (sdks[i].Alternate=sdks[j].Name) then begin
|
||||
simname:=sdks[j].Name;
|
||||
simpath:=sdks[j].FullPath;
|
||||
end;
|
||||
FoundProc(sdks[i].Version, sdks[i].Name, sdks[i].FullPath, simname, simpath);
|
||||
end;
|
||||
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
|
||||
function XibTemplateDir(const PlatformDir: AnsiString): AnsiString;
|
||||
const
|
||||
TemplatePath = 'Developer/Library/Xcode/File Templates/User Interface';
|
||||
begin
|
||||
Result:=IncludeTrailingPathDelimiter(PlatformDir)+TemplatePath;
|
||||
end;
|
||||
|
||||
procedure ScanForXibTemplates(const TemplateDir: AnsiString; Callback: TScanTemplateProc);
|
||||
var
|
||||
dirs : TStringList;
|
||||
files : TStringList;
|
||||
i,j : Integer;
|
||||
plist : TPListFile;
|
||||
|
||||
xib : AnsiString;
|
||||
name : AnsiString;
|
||||
descr : AnsiString;
|
||||
const
|
||||
XibTemplateMask = '*.pbfiletemplate';
|
||||
IconFile = 'TemplateIcon.tiff';
|
||||
begin
|
||||
if not Assigned(Callback) or not DirectoryExists(TemplateDir) then Exit;
|
||||
|
||||
dirs:=TStringList.Create;
|
||||
files:=TStringList.Create;
|
||||
try
|
||||
EnumFilesAtDir( TemplateDir, XibTemplateMask, dirs );
|
||||
for i:=0 to dirs.Count-1 do begin
|
||||
if DirectoryExists(dirs[i]) then begin
|
||||
files.Clear;
|
||||
EnumFilesAtDir(dirs[i], files);
|
||||
|
||||
xib:='';
|
||||
for j:=0 to files.Count-1 do
|
||||
if AnsiLowerCase(ExtractFileExt(files[j]))='.plist' then begin
|
||||
plist:=TPListFile.Create(files[j]);
|
||||
xib:=plist.GetStrValue('MainTemplateFile');
|
||||
descr:=plist.GetStrValue('Description');
|
||||
name:=ChangeFileExt(xib, '');
|
||||
Break;
|
||||
end;
|
||||
|
||||
if xib<>'' then begin
|
||||
xib:=IncludeTrailingPathDelimiter(dirs[i])+xib;
|
||||
Callback(name, xib, descr, IncludeTrailingPathDelimiter(dirs[i])+IconFile);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
dirs.Free;
|
||||
files.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Reference in New Issue
Block a user