API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPCib.j
Go to the documentation of this file.
1 /*
2  * CPCib.j
3  * AppKit
4  *
5  * Created by Francisco Tolmasky.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 
25 
26 CPCibOwner = @"CPCibOwner";
27 CPCibTopLevelObjects = @"CPCibTopLevelObjects";
28 CPCibReplacementClasses = @"CPCibReplacementClasses";
29 CPCibExternalObjects = @"CPCibExternalObjects";
30 
31 var CPCibObjectDataKey = @"CPCibObjectDataKey";
32 
37 @implementation CPCib : CPObject
38 {
39  CPData _data;
40  CPBundle _bundle;
41  BOOL _awakenCustomResources;
42 
43  id _loadDelegate;
44 }
45 
46 - (id)initWithContentsOfURL:(CPURL)aURL
47 {
48  self = [super init];
49 
50  if (self)
51  {
53 
54  if (!_data)
55  return nil;
56 
57  _awakenCustomResources = YES;
58  }
59 
60  return self;
61 }
62 
63 - (id)initWithContentsOfURL:(CPURL)aURL loadDelegate:(id)aLoadDelegate
64 {
65  self = [super init];
66 
67  if (self)
68  {
70 
71  _awakenCustomResources = YES;
72 
73  _loadDelegate = aLoadDelegate;
74  }
75 
76  return self;
77 }
78 
79 - (id)initWithCibNamed:(CPString)aName bundle:(CPBundle)aBundle
80 {
81  if (![aName hasSuffix:@".cib"])
82  aName = [aName stringByAppendingString:@".cib"];
83 
84  // If aBundle is nil, use mainBundle, but ONLY for searching for the nib, not for resources later.
85  self = [self initWithContentsOfURL:[aBundle || [CPBundle mainBundle] pathForResource:aName]];
86 
87  if (self)
88  _bundle = aBundle;
89 
90  return self;
91 }
92 
93 - (id)initWithCibNamed:(CPString)aName bundle:(CPBundle)aBundle loadDelegate:(id)aLoadDelegate
94 {
95  if (![aName hasSuffix:@".cib"])
96  aName = [aName stringByAppendingString:@".cib"];
97 
98  // If aBundle is nil, use mainBundle, but ONLY for searching for the nib, not for resources later.
99  self = [self initWithContentsOfURL:[aBundle || [CPBundle mainBundle] pathForResource:aName] loadDelegate:aLoadDelegate];
100 
101  if (self)
102  _bundle = aBundle;
103 
104  return self;
105 }
106 
107 - (void)_setAwakenCustomResources:(BOOL)shouldAwakenCustomResources
108 {
109  _awakenCustomResources = shouldAwakenCustomResources;
110 }
111 
112 - (BOOL)_awakenCustomResources
113 {
114  return _awakenCustomResources;
115 }
116 
117 - (BOOL)instantiateCibWithExternalNameTable:(CPDictionary)anExternalNameTable
118 {
119  var bundle = _bundle,
120  owner = [anExternalNameTable objectForKey:CPCibOwner];
121 
122  if (!bundle && owner)
123  bundle = [CPBundle bundleForClass:[owner class]];
124 
125  var unarchiver = [[_CPCibKeyedUnarchiver alloc] initForReadingWithData:_data bundle:bundle awakenCustomResources:_awakenCustomResources],
126  replacementClasses = [anExternalNameTable objectForKey:CPCibReplacementClasses];
127 
128  if (replacementClasses)
129  {
130  var key = nil,
131  keyEnumerator = [replacementClasses keyEnumerator];
132 
133  while ((key = [keyEnumerator nextObject]) !== nil)
134  [unarchiver setClass:[replacementClasses objectForKey:key] forClassName:key];
135  }
136 
137  [unarchiver setExternalObjectsForProxyIdentifiers:[anExternalNameTable objectForKey:CPCibExternalObjects]];
138 
139  var objectData = [unarchiver decodeObjectForKey:CPCibObjectDataKey];
140 
141  if (!objectData || ![objectData isKindOfClass:[_CPCibObjectData class]])
142  return NO;
143 
144  var topLevelObjects = [anExternalNameTable objectForKey:CPCibTopLevelObjects];
145 
146  [objectData instantiateWithOwner:owner topLevelObjects:topLevelObjects];
147  [objectData establishConnectionsWithOwner:owner topLevelObjects:topLevelObjects];
148  [objectData awakeWithOwner:owner topLevelObjects:topLevelObjects];
149 
150  // Display Visible Windows.
151  [objectData displayVisibleWindows];
152 
153  return YES;
154 }
155 
156 - (BOOL)instantiateCibWithOwner:(id)anOwner topLevelObjects:(CPArray)topLevelObjects
157 {
158  return [self instantiateCibWithExternalNameTable:[CPDictionary dictionaryWithObjects:[anOwner, topLevelObjects] forKeys:[CPCibOwner, CPCibTopLevelObjects]]];
159 }
160 
161 @end
162 
164 
165 - (void)connection:(CPURLConnection)aConnection didReceiveData:(CPString)data
166 {
167  // FIXME: Why aren't we getting connection:didFailWithError:
168  if (!data)
169  return [self connection:aConnection didFailWithError:nil];
170 
171  _data = [CPData dataWithRawString:data];
172 }
173 
174 - (void)connection:(CPURLConnection)aConnection didFailWithError:(CPError)anError
175 {
176  if ([_loadDelegate respondsToSelector:@selector(cibDidFailToLoad:)])
177  [_loadDelegate cibDidFailToLoad:self];
178 
179  _loadDelegate = nil;
180 }
181 
182 - (void)connectionDidFinishLoading:(CPURLConnection)aConnection
183 {
184  if ([_loadDelegate respondsToSelector:@selector(cibDidFinishLoading:)])
185  [_loadDelegate cibDidFinishLoading:self];
186 
187  _loadDelegate = nil;
188 }
189 
190 @end