00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 @import <Foundation/Foundation.j>
00025 @import <AppKit/AppKit.j>
00026 @import <BlendKit/BlendKit.j>
00027
00028 var File = require("file");
00029
00030
00031 function main()
00032 {
00033 var index = 0,
00034 count = system.args.length,
00035
00036 outputFilePath = "",
00037 descriptorFiles = [],
00038 resourcesPath = nil,
00039 cibFiles = [],
00040 blendName = "Untitled";
00041
00042 for (; index < count; ++index)
00043 {
00044 var argument = system.args[index];
00045
00046 switch (argument)
00047 {
00048 case "-c":
00049 case "--cib": cibFiles.push(system.args[++index]);
00050 break;
00051
00052 case "-d":
00053 case "-descriptor": descriptorFiles.push(system.args[++index]);
00054 break;
00055
00056 case "-o": outputFilePath = system.args[++index];
00057 break;
00058
00059 case "-R": resourcesPath = system.args[++index];
00060 break;
00061
00062 default: jExtensionIndex = argument.indexOf(".j");
00063
00064 if ((jExtensionIndex > 0) && (jExtensionIndex === argument.length - ".j".length))
00065 descriptorFiles.push(argument);
00066 else
00067 cibFiles.push(argument);
00068 }
00069 }
00070
00071 if (descriptorFiles.length === 0)
00072 return buildBlendFromCibFiles(cibFiles);
00073
00074 objj_import(descriptorFiles, YES, function()
00075 {
00076 var themeDescriptorClasses = [BKThemeDescriptor allThemeDescriptorClasses],
00077 count = [themeDescriptorClasses count];
00078
00079 while (count--)
00080 {
00081 var theClass = themeDescriptorClasses[count],
00082 themeTemplate = [[BKThemeTemplate alloc] init];
00083
00084 [themeTemplate setValue:[theClass themeName] forKey:@"name"];
00085
00086 var objectTemplates = [theClass themedObjectTemplates],
00087 data = cibDataFromTopLevelObjects(objectTemplates.concat([themeTemplate])),
00088 temporaryCibFile = Packages.java.io.File.createTempFile("temp", ".cib"),
00089 temporaryCibFilePath = String(temporaryCibFile.getAbsolutePath());
00090
00091 File.write(temporaryCibFilePath, [data string], { charset:"UTF-8" });
00092
00093 cibFiles.push(temporaryCibFilePath);
00094 }
00095
00096 buildBlendFromCibFiles(cibFiles, outputFilePath, resourcesPath);
00097 });
00098 }
00099
00100 function cibDataFromTopLevelObjects(objects)
00101 {
00102 var data = [CPData data],
00103 archiver = [[CPKeyedArchiver alloc] initForWritingWithMutableData:data],
00104 objectData = [[_CPCibObjectData alloc] init];
00105
00106 objectData._fileOwner = [_CPCibCustomObject new];
00107 objectData._fileOwner._className = @"CPObject";
00108
00109 var index = 0,
00110 count = objects.length;
00111
00112 for (; index < count; ++index)
00113 {
00114 objectData._objectsValues[index] = objectData._fileOwner;
00115 objectData._objectsKeys[index] = objects[index];
00116 }
00117
00118 [archiver encodeObject:objectData forKey:@"CPCibObjectDataKey"];
00119
00120 [archiver finishEncoding];
00121
00122 return data;
00123 }
00124
00125 function getDirectory(aPath)
00126 {
00127 return (aPath).substr(0, (aPath).lastIndexOf('/') + 1)
00128 }
00129
00130 function buildBlendFromCibFiles(cibFiles, outputFilePath, resourcesPath)
00131 {
00132 var resourcesFile = nil;
00133
00134 if (resourcesPath)
00135 resourcesFile = new Packages.java.io.File(resourcesPath);
00136
00137 var count = cibFiles.length,
00138 replacedFiles = [],
00139 staticContent = @"";
00140
00141 while (count--)
00142 {
00143 var theme = themeFromCibFile(new Packages.java.io.File(cibFiles[count])),
00144
00145
00146 filePath = [theme name] + ".keyedtheme",
00147 fileContents = [[CPKeyedArchiver archivedDataWithRootObject:theme] string];
00148
00149 replacedFiles.push(filePath);
00150
00151 staticContent += MARKER_PATH + ';' + filePath.length + ';' + filePath + MARKER_TEXT + ';' + fileContents.length + ';' + fileContents;
00152 }
00153
00154 staticContent = "@STATIC;1.0;" + staticContent;
00155
00156 var blendName = File.basename(outputFilePath),
00157 extension = File.extname(outputFilePath);
00158
00159 if (extension.length)
00160 blendName = blendName.substr(0, blendName.length - extension.length);
00161
00162 var infoDictionary = [CPDictionary dictionary],
00163 staticContentName = blendName + ".sj";
00164
00165 [infoDictionary setObject:blendName forKey:@"CPBundleName"];
00166 [infoDictionary setObject:blendName forKey:@"CPBundleIdentifier"];
00167 [infoDictionary setObject:replacedFiles forKey:@"CPBundleReplacedFiles"];
00168 [infoDictionary setObject:staticContentName forKey:@"CPBundleExecutable"];
00169
00170 var outputFile = new Packages.java.io.File(outputFilePath).getCanonicalFile();
00171
00172 outputFile.mkdirs();
00173
00174 File.write(outputFilePath + "/Info.plist", [CPPropertyListCreate280NorthData(infoDictionary) string], { charset:"UTF-8" });
00175 File.write(outputFilePath + '/' + staticContentName, staticContent, { charset:"UTF-8" });
00176
00177 if (resourcesPath)
00178 rsync(new Packages.java.io.File(resourcesPath), new Packages.java.io.File(outputFilePath));
00179 }
00180
00181 function themeFromCibFile(aFile)
00182 {
00183 var cib = [[CPCib alloc] initWithContentsOfURL:aFile.getCanonicalPath()],
00184 topLevelObjects = [];
00185
00186 [cib _setAwakenCustomResources:NO];
00187 [cib instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObject:topLevelObjects forKey:CPCibTopLevelObjects]];
00188
00189 var count = topLevelObjects.length,
00190 theme = nil,
00191 templates = [];
00192
00193 while (count--)
00194 {
00195 var object = topLevelObjects[count];
00196
00197 templates = templates.concat([object blendThemeObjectTemplates]);
00198
00199 if ([object isKindOfClass:[BKThemeTemplate class]])
00200 theme = [[CPTheme alloc] initWithName:[object valueForKey:@"name"]];
00201 }
00202
00203 print("Building " + [theme name] + " theme");
00204
00205 [templates makeObjectsPerformSelector:@selector(blendAddThemedObjectAttributesToTheme:) withObject:theme];
00206
00207 return theme;
00208 }
00209
00210 function rsync(srcFile, dstFile)
00211 {
00212 var src, dst;
00213
00214 if (String(java.lang.System.getenv("OS")).indexOf("Windows") < 0)
00215 {
00216 src = srcFile.getAbsolutePath();
00217 dst = dstFile.getAbsolutePath();
00218 }
00219 else
00220 {
00221 src = exec(["cygpath", "-u", srcFile.getAbsolutePath() + '/']);
00222 dst = exec(["cygpath", "-u", dstFile.getAbsolutePath() + "/Resources"]);
00223 }
00224
00225 if (srcFile.exists())
00226 exec(["rsync", "-avz", src, dst]);
00227 }
00228
00229 function exec( command, showOutput)
00230 {
00231 var line = "",
00232 output = "",
00233
00234 process = Packages.java.lang.Runtime.getRuntime().exec(command),
00235 reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getInputStream()));
00236
00237 while (line = reader.readLine())
00238 {
00239 if (showOutput)
00240 System.out.println(line);
00241
00242 output += line + '\n';
00243 }
00244
00245 reader = new Packages.java.io.BufferedReader(new Packages.java.io.InputStreamReader(process.getErrorStream()));
00246
00247 while (line = reader.readLine())
00248 System.out.println(line);
00249
00250 try
00251 {
00252 if (process.waitFor() != 0)
00253 System.err.println("exit value = " + process.exitValue());
00254 }
00255 catch (anException)
00256 {
00257 System.err.println(anException);
00258 }
00259
00260 return output;
00261 }
00262
00263 @implementation CPObject (BlendAdditions)
00264
00265 - (CPArray)blendThemeObjectTemplates
00266 {
00267 var theClass = [self class];
00268
00269 if ([theClass isKindOfClass:[BKThemedObjectTemplate class]])
00270 return [self];
00271
00272 if ([theClass isKindOfClass:[CPView class]])
00273 {
00274 var templates = [],
00275 subviews = [self subviews],
00276 count = [subviews count];
00277
00278 while (count--)
00279 templates = templates.concat([subviews[count] blendThemeObjectTemplates]);
00280
00281 return templates;
00282 }
00283
00284 return [];
00285 }
00286
00287 @end
00288
00289 @implementation BKThemedObjectTemplate (BlendAdditions)
00290
00291 - (void)blendAddThemedObjectAttributesToTheme:(CPTheme)aTheme
00292 {
00293 var themedObject = [self valueForKey:@"themedObject"];
00294
00295 if (!themedObject)
00296 {
00297 var subviews = [self subviews];
00298
00299 if ([subviews count] > 0)
00300 themedObject = subviews[0];
00301 }
00302
00303 if (themedObject)
00304 {
00305 print(" Recording themed properties for " + [themedObject className] + ".");
00306
00307 [aTheme takeThemeFromObject:themedObject];
00308 }
00309 }
00310
00311 @end