![]() |
API 0.9.5
|
00001 /* 00002 * CPCib.j 00003 * AppKit 00004 * 00005 * Created by Francisco Tolmasky. 00006 * Copyright 2008, 280 North, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 00024 00025 00026 CPCibOwner = @"CPCibOwner"; 00027 CPCibTopLevelObjects = @"CPCibTopLevelObjects"; 00028 CPCibReplacementClasses = @"CPCibReplacementClasses"; 00029 CPCibExternalObjects = @"CPCibExternalObjects"; 00030 00031 var CPCibObjectDataKey = @"CPCibObjectDataKey"; 00032 00037 @implementation CPCib : CPObject 00038 { 00039 CPData _data; 00040 CPBundle _bundle; 00041 BOOL _awakenCustomResources; 00042 00043 id _loadDelegate; 00044 } 00045 00046 - (id)initWithContentsOfURL:(CPURL)aURL 00047 { 00048 self = [super init]; 00049 00050 if (self) 00051 { 00052 _data = [CPURLConnection sendSynchronousRequest:[CPURLRequest requestWithURL:aURL] returningResponse:nil]; 00053 _awakenCustomResources = YES; 00054 } 00055 00056 return self; 00057 } 00058 00059 - (id)initWithContentsOfURL:(CPURL)aURL loadDelegate:(id)aLoadDelegate 00060 { 00061 self = [super init]; 00062 00063 if (self) 00064 { 00065 [CPURLConnection connectionWithRequest:[CPURLRequest requestWithURL:aURL] delegate:self]; 00066 00067 _awakenCustomResources = YES; 00068 00069 _loadDelegate = aLoadDelegate; 00070 } 00071 00072 return self; 00073 } 00074 00075 - (id)initWithCibNamed:(CPString)aName bundle:(CPBundle)aBundle 00076 { 00077 if (![aName hasSuffix:@".cib"]) 00078 aName = [aName stringByAppendingString:@".cib"]; 00079 00080 // If aBundle is nil, use mainBundle, but ONLY for searching for the nib, not for resources later. 00081 self = [self initWithContentsOfURL:[aBundle || [CPBundle mainBundle] pathForResource:aName]]; 00082 00083 if (self) 00084 _bundle = aBundle; 00085 00086 return self; 00087 } 00088 00089 - (id)initWithCibNamed:(CPString)aName bundle:(CPBundle)aBundle loadDelegate:(id)aLoadDelegate 00090 { 00091 if (![aName hasSuffix:@".cib"]) 00092 aName = [aName stringByAppendingString:@".cib"]; 00093 00094 // If aBundle is nil, use mainBundle, but ONLY for searching for the nib, not for resources later. 00095 self = [self initWithContentsOfURL:[aBundle || [CPBundle mainBundle] pathForResource:aName] loadDelegate:aLoadDelegate]; 00096 00097 if (self) 00098 _bundle = aBundle; 00099 00100 return self; 00101 } 00102 00103 - (void)_setAwakenCustomResources:(BOOL)shouldAwakenCustomResources 00104 { 00105 _awakenCustomResources = shouldAwakenCustomResources; 00106 } 00107 00108 - (BOOL)_awakenCustomResources 00109 { 00110 return _awakenCustomResources; 00111 } 00112 00113 - (BOOL)instantiateCibWithExternalNameTable:(CPDictionary)anExternalNameTable 00114 { 00115 var bundle = _bundle, 00116 owner = [anExternalNameTable objectForKey:CPCibOwner]; 00117 00118 if (!bundle && owner) 00119 bundle = [CPBundle bundleForClass:[owner class]]; 00120 00121 var unarchiver = [[_CPCibKeyedUnarchiver alloc] initForReadingWithData:_data bundle:bundle awakenCustomResources:_awakenCustomResources], 00122 replacementClasses = [anExternalNameTable objectForKey:CPCibReplacementClasses]; 00123 00124 if (replacementClasses) 00125 { 00126 var key = nil, 00127 keyEnumerator = [replacementClasses keyEnumerator]; 00128 00129 while (key = [keyEnumerator nextObject]) 00130 [unarchiver setClass:[replacementClasses objectForKey:key] forClassName:key]; 00131 } 00132 00133 [unarchiver setExternalObjectsForProxyIdentifiers:[anExternalNameTable objectForKey:CPCibExternalObjects]]; 00134 00135 var objectData = [unarchiver decodeObjectForKey:CPCibObjectDataKey]; 00136 00137 if (!objectData || ![objectData isKindOfClass:[_CPCibObjectData class]]) 00138 return NO; 00139 00140 var topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects]; 00141 00142 [objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects]; 00143 [objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects]; 00144 [objectData awakeWithOwner:owner topLevelObjects:topLevelObjects]; 00145 00146 // Display Visible Windows. 00147 [objectData displayVisibleWindows]; 00148 00149 return YES; 00150 } 00151 00152 - (BOOL)instantiateCibWithOwner:(id)anOwner topLevelObjects:(CPArray)topLevelObjects 00153 { 00154 return [self instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObjectsAndKeys:anOwner, CPCibOwner, topLevelObjects, CPCibTopLevelObjects]]; 00155 } 00156 00157 @end 00158 00159 @implementation CPCib (CPURLConnectionDelegate) 00160 00161 - (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data 00162 { 00163 // FIXME: Why aren't we getting connection:didFailWithError: 00164 if (!data) 00165 return [self connection:aConnection didFailWithError:nil]; 00166 00167 _data = [CPData dataWithRawString:data]; 00168 } 00169 00170 - (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError 00171 { 00172 if ([_loadDelegate respondsToSelector:@selector(cibDidFailToLoad:)]) 00173 [_loadDelegate cibDidFailToLoad:self]; 00174 00175 _loadDelegate = nil; 00176 } 00177 00178 - (void)connectionDidFinishLoading:(CPURLConnection)aConnection 00179 { 00180 if ([_loadDelegate respondsToSelector:@selector(cibDidFinishLoading:)]) 00181 [_loadDelegate cibDidFinishLoading:self]; 00182 00183 _loadDelegate = nil; 00184 } 00185 00186 @end