Improved TableView nib support as well as including several nib2cib improvements.

Reviewed by me.
This commit is contained in:
Francisco Ryan Tolmasky I committed 2009-07-11 18:12:20 -07:00
1 parent 3761fb8037
commit afba1909bb
8 files changed
+346 -194

No files matched your search

+1 -1
View File
@@ -108,7 +108,7 @@ var _CPKeyedUnarchiverArrayClass = Ni
CPDictionary _replacementClasses;
CPDictionary _objects;
CPArray _objects;
CPDictionary _archive;
CPDictionary _plistObject;
+85
View File
@@ -0,0 +1,85 @@
/*
* Converter+Mac.j
* nib2cib
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import "Converter.j"
@implementation Converter (Mac)
- (void)convertedDataFromMacData:(CPData)data resourcesPath:(CPString)aResourcesPath
{
// Unarchive the NS data
var unarchiver = [[Nib2CibKeyedUnarchiver alloc] initForReadingWithData:data resourcesPath:aResourcesPath],
objectData = [unarchiver decodeObjectForKey:@"IB.objectdata"];
// Perform a bit of post-processing on views since all CP views are flipped.
// It's better to do this here (instead of say, in NSView::initWithCoder:),
// because at this point all the objects an mappings are stabilized.
var objects = [unarchiver allObjects],
count = [objects count];
while (count--)
{
var object = objects[count];
if (![object isKindOfClass:[CPView class]])
continue;
var superview = [object superview];
if (!superview || [superview NS_isFlipped])
continue;
var superviewHeight = CGRectGetHeight([superview bounds]),
frame = [object frame];
[object setFrameOrigin:CGPointMake(CGRectGetMinX(frame), superviewHeight - CGRectGetMaxY(frame))];
var NS_autoresizingMask = [object autoresizingMask];
autoresizingMask = NS_autoresizingMask & ~(CPViewMaxYMargin | CPViewMinYMargin);
if (!(NS_autoresizingMask & (CPViewMaxYMargin | CPViewMinYMargin | CPViewHeightSizable)))
autoresizingMask |= CPViewMinYMargin;
else
{
if (NS_autoresizingMask & CPViewMaxYMargin)
autoresizingMask |= CPViewMinYMargin;
if (NS_autoresizingMask & CPViewMinYMargin)
autoresizingMask |= CPViewMaxYMargin;
}
[object setAutoresizingMask:autoresizingMask];
}
// Re-archive the CP data.
var convertedData = [CPData data],
archiver = [[CPKeyedArchiver alloc] initForWritingWithMutableData:convertedData];
[archiver encodeObject:objectData forKey:@"CPCibObjectDataKey"];
[archiver finishEncoding];
return convertedData;
}
@end
+160
View File
@@ -0,0 +1,160 @@
/*
* Converter.j
* nib2cib
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPData.j>
var File = require("file"),
popen = require("os").popen;
NibFormatUndetermined = 0,
NibFormatMac = 1,
NibFormatIPhone = 2;
ConverterConversionException = @"ConverterConversionException";
@implementation Converter : CPObject
{
NibFormat format @accessors;
CPString inputPath @accessors;
CPString outputPath @accessors;
CPString resourcesPath @accessors;
}
- (id)init
{
self = [super init];
if (self)
[self setFormat:NibFormatUndetermined];
return self;
}
- (void)convert
{
try
{
if ([resourcesPath length] && !File.isReadable(resourcesPath))
[CPException raise:ConverterConversionException reason:@"Could not read Resources at path \"" + resourcesPath + "\""];
var stringContents = File.read(inputPath, { charset:"UTF-8" }),
inferredFormat = format;
if (inferredFormat === NibFormatUndetermined)
{
// Assume its a Mac file.
inferredFormat = NibFormatMac;
// Some .xibs are iPhone nibs, check the actual contents in this case.
if (File.extname(inputPath) !== ".nib" &&
stringContents.indexOf("<archive type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\"") !== -1)
inferredFormat = NibFormatIPhone;
if (inferredFormat === NibFormatMac)
CPLog("Auto-detected Cocoa Nib or Xib File");
else
CPLog("Auto-detected CocoaTouch Xib File");
}
var nibData = [self CPCompliantNibDataAtFilePath:inputPath];
if (inferredFormat === NibFormatMac)
var convertedData = [self convertedDataFromMacData:nibData resourcesPath:resourcesPath];
else
[CPException raise:ConverterConversionException reason:@"nib2cib does not understand this nib format."];
if (![outputPath length])
outputPath = cibExtension(inputPath);
File.write(outputPath, [convertedData string], { charset:"UTF-8" });
}
catch(anException)
{
print(anException);
}
}
- (CPData)CPCompliantNibDataAtFilePath:(CPString)aFilePath
{
// Compile xib or nib to make sure we have a non-new format nib.
var temporaryNibFilePath = File.createTempFile("temp", ".nib", true);
if (popen("/usr/bin/ibtool " + aFilePath + " --compile " + temporaryNibFilePath).wait() === 1)
throw "Could not compile file at " + aFilePath;
// Convert from binary plist to XML plist
var temporaryPlistFilePath = File.createTempFile("temp", ".plist", true);
if (popen("/usr/bin/plutil " + " -convert xml1 " + temporaryNibFilePath + " -o " + temporaryPlistFilePath).wait() === 1)
throw "Could not convert to xml plist for file at " + aFilePath;
if (!File.isReadable(temporaryPlistFilePath))
[CPException raise:ConverterConversionException reason:@"Unable to convert nib file."];
var plistContents = File.read(temporaryPlistFilePath, { charset:"UTF-8" });
// Minor NS keyed archive to CP keyed archive conversion.
// Use Java directly because rhino's string.replace is *so slow*. 4 seconds vs. 1 millisecond.
// plistContents = plistContents.replace(/\<key\>\s*CF\$UID\s*\<\/key\>/g, "<key>CP$UID</key>");
plistContents = String(java.lang.String(plistContents).replaceAll("\\<key\\>\\s*CF\\$UID\\s*\\<\/key\\>", "<key>CP\\$UID</key>"));
return [CPData dataWithString:plistContents];
}
@end
File.createTempFile = function(aName, anExtension, shouldDeleteOnExit)
{
var tempFile = Packages.java.io.File.createTempFile(aName, anExtension),
tempFilePath = String(tempFile.getAbsolutePath());
if (shouldDeleteOnExit)
tempFile.deleteOnExit();
return String(tempFilePath);
}
function cibExtension(aPath)
{
var start = aPath.length - 1;
while (aPath.charAt(start) === '/')
start--;
aPath = aPath.substr(0, start + 1);
var dotIndex = aPath.lastIndexOf('.');
if (dotIndex == -1)
return aPath + ".cib";
var slashIndex = aPath.lastIndexOf('/');
if (slashIndex > dotIndex)
return aPath + ".cib";
return aPath.substr(0, dotIndex) + ".cib";
}
@import "Converter+Mac.j"
+5
View File
@@ -40,6 +40,11 @@
return self;
}
- (BOOL)NS_isFlipped
{
return YES;
}
@end
@implementation NSClipView : CPClipView
+4 -4
View File
@@ -49,13 +49,13 @@ importClass(javax.imageio.ImageIO);
}
else
{
var resourceFile = [aCoder resourceFileForName:_resourceName];
if (!resourceFile)
var resourcePath = [aCoder resourcePathForName:_resourceName];
if (!resourcePath)
CPLog.warn("***WARNING: Resource named " + _resourceName + " not found in supplied resources path.");
else
{
var imageStream = ImageIO.createImageInputStream(resourceFile),
var imageStream = ImageIO.createImageInputStream(new Packages.java.io.File(resourcePath).getCanonicalFile()),
readers = ImageIO.getImageReaders(imageStream),
reader = null;
+7 -31
View File
@@ -56,42 +56,13 @@
_subviews = [];
var vFlags = [aCoder decodeIntForKey:@"NSvFlags"];
var autoresizingMaskNS = vFlags & 0x3F;
// swap Y coordinate flags:
_autoresizingMask = autoresizingMaskNS & ~(CPViewMaxYMargin | CPViewMinYMargin)
if (!(autoresizingMaskNS & (CPViewMaxYMargin | CPViewMinYMargin | CPViewHeightSizable)))
{
_autoresizingMask |= CPViewMinYMargin;
}
else
{
if (autoresizingMaskNS & CPViewMaxYMargin)
_autoresizingMask |= CPViewMinYMargin;
if (autoresizingMaskNS & CPViewMinYMargin)
_autoresizingMask |= CPViewMaxYMargin;
}
_autoresizingMask = vFlags & 0x3F;
_autoresizesSubviews = vFlags & (1 << 8);
_hitTests = YES;
_isHidden = NO;//[aCoder decodeObjectForKey:CPViewIsHiddenKey];
_opacity = 1.0;//[aCoder decodeIntForKey:CPViewOpacityKey];
if (YES/*[_superview isFlipped]*/)
{
var height = CGRectGetHeight([self bounds]),
count = [_subviews count];
while (count--)
{
var subview = _subviews[count],
frame = [subview frame];
[subview setFrameOrigin:CGPointMake(CGRectGetMinX(frame), height - CGRectGetMaxY(frame))];
}
}
_themeAttributes = {};
_themeState = CPThemeStateNormal;
@@ -101,6 +72,11 @@
return self;
}
- (BOOL)NS_isFlipped
{
return NO;
}
@end
@implementation NSView : CPView
+47 -23
View File
@@ -1,51 +1,75 @@
/*
* NSKeyedArchiver.j
* nib2cib
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPKeyedUnarchiver.j>
var File = require("file");
@implementation Nib2CibKeyedUnarchiver : CPKeyedUnarchiver
{
File resourcesFile;
CPString resourcesPath;
}
- (id)initForReadingWithData:(CPData)data resourcesFile:(File)aResourcesFile
- (id)initForReadingWithData:(CPData)data resourcesPath:(CPString)aResourcesPath
{
self = [super initForReadingWithData:data];
if (self)
resourcesFile = aResourcesFile;
resourcesPath = aResourcesPath;
return self;
}
- (File)resourcesFile
- (CPArray)allObjects
{
return resourcesFile;
return _objects;
}
- (File)resourceFileForName:(CPString)aName
- (CPString)resourcePathForName:(CPString)aName
{
var moreFiles = [resourcesFile.listFiles()];
if (!resourcesPath)
return NULL;
do
var pathGroups = [File.list(resourcesPath)];
while (pathGroups.length > 0)
{
var files = moreFiles.shift(),
var paths = pathGroups.shift(),
index = 0,
count = files.length;
count = paths.length;
for (; index < count; ++index)
{
var file = files[index].getCanonicalFile(),
name = String(file.getName());
if (name === aName)
return file;
if (file.isDirectory())
moreFiles.push(file.listFiles());
var path = files[index];
if (File.basename(path) === aName)
return path;
if (File.isDirectory(path))
pathGroups.push(File.list(path));
}
}
while (moreFiles.length > 0)
return NULL;
}
+37 -135
View File
@@ -20,14 +20,15 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/Foundation.j>
@import <AppKit/CPCib.j>
@import "NSFoundation.j"
@import "NSAppKit.j"
@import "Nib2CibKeyedUnarchiver.j"
@import "Converter.j"
var File = require("file");
@@ -35,118 +36,15 @@ importPackage(java.io);
CPLogRegister(CPLogPrint);
function exec(command)
{
var p = Packages.java.lang.Runtime.getRuntime().exec(command);
var result = p.waitFor();
var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(p.getInputStream()));
while (s = reader.readLine())
print(s);
var reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(p.getErrorStream()));
while (s = reader.readLine())
print(s);
return result;
}
function printUsage()
{
java.lang.System.out.println("usage: nib2cib INPUT_FILE [OUTPUT_FILE] [-F /path/to/required/framework]");
print("usage: nib2cib INPUT_FILE [OUTPUT_FILE] [-F /path/to/required/framework] [-R path/to/resources]");
java.lang.System.exit(1);
}
function cibExtension(aPath)
{
var start = aPath.length - 1;
while (aPath.charAt(start) === '/')
start--;
aPath = aPath.substr(0, start + 1);
var dotIndex = aPath.lastIndexOf('.');
if (dotIndex == -1)
return aPath + ".cib";
var slashIndex = aPath.lastIndexOf('/');
if (slashIndex > dotIndex)
return aPath + ".cib";
return aPath.substr(0, dotIndex) + ".cib";
}
function convert(inputFileName, outputFileName, resourcesPath)
{
var resourcesFile = nil;
if (resourcesPath)
{
resourcesFile = new java.io.File(resourcesPath).getCanonicalFile();
if (!resourcesFile.canRead())
{
print("Could not find Resources at " + resourcesFile);
return;
}
}
// Make sure we can read the file
if (!(new Packages.java.io.File(inputFileName)).canRead())
{
print("Could not read file at " + inputFileName);
return;
}
// Compile xib or nib to make sure we have a non-new format nib.
var temporaryNibFile = java.io.File.createTempFile("temp", ".nib"),
temporaryNibFilePath = temporaryNibFile.getAbsolutePath();
temporaryNibFile.deleteOnExit();
if (exec(["/usr/bin/ibtool", inputFileName, "--compile", temporaryNibFilePath]))
{
print("Could not compile file at " + inputFileName);
return;
}
// Convert from binary plist to XML plist
var temporaryPlistFile = java.io.File.createTempFile("temp", ".plist"),
temporaryPlistFilePath = String(temporaryPlistFile.getAbsolutePath());
temporaryPlistFile.deleteOnExit();
if (exec(["/usr/bin/plutil", "-convert", "xml1", temporaryNibFilePath, "-o", temporaryPlistFilePath]))
{
print("Could not convert to xml plist for file at " + inputFileName);
return;
}
var data = [CPData dataWithString:File.read(String(temporaryPlistFilePath), { charset:"UTF-8" })];
// Minor NSKeyedArchive to CPKeyedArchive conversion.
[data setString:[data string].replace(/\<key\>\s*CF\$UID\s*\<\/key\>/g, "<key>CP$UID</key>")];
// Unarchive the NS data
var unarchiver = [[Nib2CibKeyedUnarchiver alloc] initForReadingWithData:data resourcesFile:resourcesFile],
objectData = [unarchiver decodeObjectForKey:@"IB.objectdata"],
data = [CPData data],
archiver = [[CPKeyedArchiver alloc] initForWritingWithMutableData:data];
// Re-archive the CP data.
[archiver encodeObject:objectData forKey:@"CPCibObjectDataKey"];
[archiver finishEncoding];
File.write(outputFileName, [data string], { charset:"UTF-8" });
}
function loadFrameworks(frameworkPaths, aCallback)
{
if (frameworkPaths.length === 0)
if (!frameworkPaths || frameworkPaths.length === 0)
return aCallback();
var frameworkPath = frameworkPaths.shift(),
@@ -167,6 +65,8 @@ function loadFrameworks(frameworkPaths, aCallback)
java.lang.System.exit(1);
}
print("Loading " + [infoDictionary objectForKey:@"CPBundleName"]);
var files = [infoDictionary objectForKey:@"CPBundleReplacedFiles"],
count = files.length;
@@ -175,14 +75,18 @@ function loadFrameworks(frameworkPaths, aCallback)
var context = new objj_context();
context.didCompleteCallback = function() { loadFrameworks(frameworkPaths, aCallback) };
print("2he");
while (count--)
{
print(frameworkPath + '/' + files[count]);
context.pushFragment(fragment_create_file(frameworkPath + '/' + files[count], new objj_bundle(""), YES, NULL));
context.evaluate();
}
print("hmmm");
context.evaluate();print("wha???");
}
else
loadFrameworks(frameworkPaths, aCallback);
print("so far so good...");
}
function main()
@@ -190,41 +94,39 @@ function main()
var count = arguments.length;
if (count < 1)
printUsage();
return printUsage();
var index = 0,
inputFileName = nil,
outputFileName = nil,
resourcesPath = nil,
frameworkPaths = [];
frameworkPaths = [],
converter = [[Converter alloc] init];
for (; index < count; ++index)
{
switch(arguments[index])
{
case "-help":
case "--help": printUsage();
case "-F": frameworkPaths.push(arguments[++index]);
break;
case "-R": resourcesPath = arguments[++index];
break;
default: if (inputFileName && inputFileName.length > 0)
outputFileName = arguments[index];
else
inputFileName = arguments[index];
case "--help": printUsage();
break;
case "--mac": [converter setFormat:NibFormatMac];
break;
case "-F": frameworkPaths.push(arguments[++index]);
break;
case "-R": [converter setResourcesPath:arguments[++index]];
break;
default: if ([converter inputPath])
[converter setOutputPath:arguments[index]];
else
[converter setInputPath:arguments[index]];
}
}
if (!outputFileName || outputFileName.length < 1)
outputFileName = cibExtension(inputFileName);
if (frameworkPaths.length)
loadFrameworks(frameworkPaths, function() { convert(inputFileName, outputFileName, resourcesPath); });
else
convert(inputFileName, outputFileName, resourcesPath);
loadFrameworks(frameworkPaths, function()
{
[converter convert];
});
}