/core/externals/update-engine/externals/gdata-objectivec-client/Examples/SpreadsheetSample/SpreadsheetSampleWindowController.m

http://macfuse.googlecode.com/ · Objective C · 548 lines · 347 code · 139 blank · 62 comment · 58 complexity · 408fe80a6b12beae34b16580a5861092 MD5 · raw file

  1. /* Copyright (c) 2007 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. //
  16. // SpreadsheetSampleWindowController.m
  17. //
  18. #import "SpreadsheetSampleWindowController.h"
  19. @interface SpreadsheetSampleWindowController (PrivateMethods)
  20. - (void)updateUI;
  21. - (void)fetchFeedOfSpreadsheets;
  22. - (void)fetchSelectedSpreadsheet;
  23. - (void)fetchSelectedWorksheet;
  24. - (GDataServiceGoogleSpreadsheet *)spreadsheetService;
  25. - (GDataEntrySpreadsheet *)selectedSpreadsheet;
  26. - (GDataEntryWorksheet *)selectedWorksheet;
  27. - (GDataEntryBase *)selectedEntry;
  28. - (GDataFeedSpreadsheet *)spreadsheetFeed;
  29. - (void)setSpreadsheetFeed:(GDataFeedSpreadsheet *)feed;
  30. - (NSError *)spreadsheetFetchError;
  31. - (void)setSpreadsheetFetchError:(NSError *)error;
  32. - (GDataFeedWorksheet *)worksheetFeed;
  33. - (void)setWorksheetFeed:(GDataFeedWorksheet *)feed;
  34. - (NSError *)worksheetFetchError;
  35. - (void)setWorksheetFetchError:(NSError *)error;
  36. - (GDataFeedBase *)entryFeed;
  37. - (void)setEntryFeed:(GDataFeedBase *)feed;
  38. - (NSError *)entryFetchError;
  39. - (void)setEntryFetchError:(NSError *)error;
  40. @end
  41. @implementation SpreadsheetSampleWindowController
  42. static SpreadsheetSampleWindowController* gSpreadsheetSampleWindowController = nil;
  43. + (SpreadsheetSampleWindowController *)sharedSpreadsheetSampleWindowController {
  44. if (!gSpreadsheetSampleWindowController) {
  45. gSpreadsheetSampleWindowController = [[SpreadsheetSampleWindowController alloc] init];
  46. }
  47. return gSpreadsheetSampleWindowController;
  48. }
  49. - (id)init {
  50. return [self initWithWindowNibName:@"SpreadsheetSampleWindow"];
  51. }
  52. - (void)windowDidLoad {
  53. }
  54. - (void)awakeFromNib {
  55. // Set the result text fields to have a distinctive color and mono-spaced font
  56. // to aid in understanding of each query operation.
  57. [mSpreadsheetResultTextField setTextColor:[NSColor darkGrayColor]];
  58. [mWorksheetResultTextField setTextColor:[NSColor darkGrayColor]];
  59. [mEntryResultTextField setTextColor:[NSColor darkGrayColor]];
  60. NSFont *resultTextFont = [NSFont fontWithName:@"Monaco" size:9];
  61. [mSpreadsheetResultTextField setFont:resultTextFont];
  62. [mWorksheetResultTextField setFont:resultTextFont];
  63. [mEntryResultTextField setFont:resultTextFont];
  64. [self updateUI];
  65. }
  66. - (void)dealloc {
  67. [mSpreadsheetFeed release];
  68. [mSpreadsheetFetchError release];
  69. [mWorksheetFeed release];
  70. [mWorksheetFetchError release];
  71. [mEntryFeed release];
  72. [mEntryFetchError release];
  73. [super dealloc];
  74. }
  75. #pragma mark -
  76. - (void)updateUI {
  77. // spreadsheet list display
  78. [mSpreadsheetTable reloadData];
  79. if (mIsSpreadsheetFetchPending) {
  80. [mSpreadsheetProgressIndicator startAnimation:self];
  81. } else {
  82. [mSpreadsheetProgressIndicator stopAnimation:self];
  83. }
  84. // spreadsheet fetch result or selected item
  85. NSString *spreadsheetResultStr = @"";
  86. if (mSpreadsheetFetchError) {
  87. spreadsheetResultStr = [mSpreadsheetFetchError description];
  88. } else {
  89. GDataEntrySpreadsheet *spreadsheet = [self selectedSpreadsheet];
  90. if (spreadsheet) {
  91. spreadsheetResultStr = [spreadsheet description];
  92. } else {
  93. }
  94. }
  95. [mSpreadsheetResultTextField setString:spreadsheetResultStr];
  96. // Worksheet list display
  97. [mWorksheetTable reloadData];
  98. if (mIsWorksheetFetchPending) {
  99. [mWorksheetProgressIndicator startAnimation:self];
  100. } else {
  101. [mWorksheetProgressIndicator stopAnimation:self];
  102. }
  103. // Worksheet fetch result or selected item
  104. NSString *worksheetResultStr = @"";
  105. if (mWorksheetFetchError) {
  106. worksheetResultStr = [mWorksheetFetchError description];
  107. } else {
  108. GDataEntryWorksheet *worksheet = [self selectedWorksheet];
  109. if (worksheet) {
  110. worksheetResultStr = [worksheet description];
  111. }
  112. }
  113. [mWorksheetResultTextField setString:worksheetResultStr];
  114. // cell/list entry display
  115. [mEntryTable reloadData];
  116. if (mIsEntryFetchPending) {
  117. [mEntryProgressIndicator startAnimation:self];
  118. } else {
  119. [mEntryProgressIndicator stopAnimation:self];
  120. }
  121. // entry fetch result or selected item
  122. NSString *entryResultStr = @"";
  123. if (mEntryFetchError) {
  124. entryResultStr = [mEntryFetchError description];
  125. } else {
  126. GDataEntryBase *entry = [self selectedEntry];
  127. if (entry) {
  128. entryResultStr = [entry description];
  129. }
  130. }
  131. [mEntryResultTextField setString:entryResultStr];
  132. }
  133. #pragma mark IBActions
  134. - (IBAction)getSpreadsheetClicked:(id)sender {
  135. NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
  136. NSString *username = [mUsernameField stringValue];
  137. username = [username stringByTrimmingCharactersInSet:whitespace];
  138. if ([username rangeOfString:@"@"].location == NSNotFound) {
  139. // if no domain was supplied, add @gmail.com
  140. username = [username stringByAppendingString:@"@gmail.com"];
  141. }
  142. [mUsernameField setStringValue:username];
  143. [self fetchFeedOfSpreadsheets];
  144. }
  145. - (IBAction)feedSegmentClicked:(id)sender {
  146. // user switched between cell and list feed
  147. [self fetchSelectedWorksheet];
  148. }
  149. - (IBAction)loggingCheckboxClicked:(id)sender {
  150. [GTMHTTPFetcher setLoggingEnabled:[sender state]];
  151. }
  152. #pragma mark -
  153. // get a spreadsheet service object with the current username/password
  154. //
  155. // A "service" object handles networking tasks. Service objects
  156. // contain user authentication information as well as networking
  157. // state information (such as cookies and the "last modified" date for
  158. // fetched data.)
  159. - (GDataServiceGoogleSpreadsheet *)spreadsheetService {
  160. static GDataServiceGoogleSpreadsheet* service = nil;
  161. if (!service) {
  162. service = [[GDataServiceGoogleSpreadsheet alloc] init];
  163. [service setShouldCacheResponseData:YES];
  164. [service setServiceShouldFollowNextLinks:YES];
  165. }
  166. // username/password may change
  167. NSString *username = [mUsernameField stringValue];
  168. NSString *password = [mPasswordField stringValue];
  169. [service setUserCredentialsWithUsername:username
  170. password:password];
  171. return service;
  172. }
  173. // get the spreadsheet selected in the top list, or nil if none
  174. - (GDataEntrySpreadsheet *)selectedSpreadsheet {
  175. NSArray *spreadsheets = [mSpreadsheetFeed entries];
  176. int rowIndex = [mSpreadsheetTable selectedRow];
  177. if ([spreadsheets count] > 0 && rowIndex > -1) {
  178. GDataEntrySpreadsheet *spreadsheet = [spreadsheets objectAtIndex:rowIndex];
  179. return spreadsheet;
  180. }
  181. return nil;
  182. }
  183. // get the Worksheet selected in the second list, or nil if none
  184. - (GDataEntryWorksheet *)selectedWorksheet {
  185. NSArray *Worksheets = [mWorksheetFeed entries];
  186. int rowIndex = [mWorksheetTable selectedRow];
  187. if ([Worksheets count] > 0 && rowIndex > -1) {
  188. GDataEntryWorksheet *Worksheet = [Worksheets objectAtIndex:rowIndex];
  189. return Worksheet;
  190. }
  191. return nil;
  192. }
  193. // get the cell or list entry selected in the bottom list
  194. - (GDataEntryBase *)selectedEntry {
  195. NSArray *entries = [mEntryFeed entries];
  196. int rowIndex = [mEntryTable selectedRow];
  197. if ([entries count] > 0 && rowIndex > -1) {
  198. GDataEntryBase *entry = [entries objectAtIndex:rowIndex];
  199. return entry;
  200. }
  201. return nil;
  202. }
  203. #pragma mark Fetch feed of all of the user's spreadsheets
  204. // begin retrieving the list of the user's spreadsheets
  205. - (void)fetchFeedOfSpreadsheets {
  206. [self setSpreadsheetFeed:nil];
  207. [self setSpreadsheetFetchError:nil];
  208. [self setWorksheetFeed:nil];
  209. [self setWorksheetFetchError:nil];
  210. [self setEntryFeed:nil];
  211. [self setEntryFetchError:nil];
  212. mIsSpreadsheetFetchPending = YES;
  213. GDataServiceGoogleSpreadsheet *service = [self spreadsheetService];
  214. NSURL *feedURL = [NSURL URLWithString:kGDataGoogleSpreadsheetsPrivateFullFeed];
  215. [service fetchFeedWithURL:feedURL
  216. delegate:self
  217. didFinishSelector:@selector(feedTicket:finishedWithFeed:error:)];
  218. [self updateUI];
  219. }
  220. // spreadsheet list fetch callback
  221. - (void)feedTicket:(GDataServiceTicket *)ticket
  222. finishedWithFeed:(GDataFeedSpreadsheet *)feed
  223. error:(NSError *)error {
  224. [self setSpreadsheetFeed:feed];
  225. [self setSpreadsheetFetchError:error];
  226. mIsSpreadsheetFetchPending = NO;
  227. [self updateUI];
  228. }
  229. #pragma mark Fetch a spreadsheet's Worksheets
  230. // for the spreadsheet selected in the top list, begin retrieving the list of
  231. // Worksheets
  232. - (void)fetchSelectedSpreadsheet {
  233. GDataEntrySpreadsheet *spreadsheet = [self selectedSpreadsheet];
  234. if (spreadsheet) {
  235. NSURL *feedURL = [spreadsheet worksheetsFeedURL];
  236. if (feedURL) {
  237. [self setWorksheetFeed:nil];
  238. [self setWorksheetFetchError:nil];
  239. mIsWorksheetFetchPending = YES;
  240. [self setEntryFeed:nil];
  241. [self setEntryFetchError:nil];
  242. GDataServiceGoogleSpreadsheet *service = [self spreadsheetService];
  243. [service fetchFeedWithURL:feedURL
  244. delegate:self
  245. didFinishSelector:@selector(worksheetsTicket:finishedWithFeed:error:)];
  246. [self updateUI];
  247. }
  248. }
  249. }
  250. // fetch worksheet feed callback
  251. - (void)worksheetsTicket:(GDataServiceTicket *)ticket
  252. finishedWithFeed:(GDataFeedWorksheet *)feed
  253. error:(NSError *)error {
  254. [self setWorksheetFeed:feed];
  255. [self setWorksheetFetchError:error];
  256. mIsWorksheetFetchPending = NO;
  257. [self updateUI];
  258. }
  259. #pragma mark Fetch a worksheet's entries
  260. // for the worksheet selected, fetch either a cell feed or a list feed
  261. // of its contents, depending on the segmented control's setting
  262. - (void)fetchSelectedWorksheet {
  263. GDataEntryWorksheet *worksheet = [self selectedWorksheet];
  264. if (worksheet) {
  265. // the segmented control lets the user retrieve cell entries (position 0)
  266. // or list entries (position 1)
  267. int segmentIndex = [mFeedSelectorSegments selectedSegment];
  268. NSURL *feedURL;
  269. if (segmentIndex == 0) {
  270. feedURL = [[worksheet cellsLink] URL];
  271. } else {
  272. feedURL = [worksheet listFeedURL];
  273. }
  274. if (feedURL) {
  275. [self setEntryFeed:nil];
  276. [self setEntryFetchError:nil];
  277. mIsEntryFetchPending = YES;
  278. GDataServiceGoogleSpreadsheet *service = [self spreadsheetService];
  279. [service fetchFeedWithURL:feedURL
  280. delegate:self
  281. didFinishSelector:@selector(entriesTicket:finishedWithFeed:error:)];
  282. [self updateUI];
  283. }
  284. }
  285. }
  286. // fetch entries callback
  287. - (void)entriesTicket:(GDataServiceTicket *)ticket
  288. finishedWithFeed:(GDataFeedBase *)feed
  289. error:(NSError *)error {
  290. [self setEntryFeed:feed];
  291. [self setEntryFetchError:error];
  292. mIsEntryFetchPending = NO;
  293. [self updateUI];
  294. }
  295. #pragma mark TableView delegate methods
  296. //
  297. // table view delegate methods
  298. //
  299. - (void)tableViewSelectionDidChange:(NSNotification *)notification {
  300. id obj = [notification object];
  301. if (obj == mSpreadsheetTable) {
  302. // the user clicked on a spreadsheet, so fetch its Worksheets
  303. [self fetchSelectedSpreadsheet];
  304. } else if (obj == mWorksheetTable) {
  305. [self fetchSelectedWorksheet];
  306. } else {
  307. [self updateUI];
  308. }
  309. }
  310. // table view data source methods
  311. - (int)numberOfRowsInTableView:(NSTableView *)tableView {
  312. if (tableView == mSpreadsheetTable) {
  313. return [[mSpreadsheetFeed entries] count];
  314. } else if (tableView == mWorksheetTable) {
  315. return [[mWorksheetFeed entries] count];
  316. } else {
  317. return [[mEntryFeed entries] count];
  318. }
  319. }
  320. - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row {
  321. if (tableView == mSpreadsheetTable) {
  322. // get the spreadsheet entry's title
  323. GDataEntrySpreadsheet *spreadsheet = [[mSpreadsheetFeed entries] objectAtIndex:row];
  324. return [[spreadsheet title] stringValue];
  325. } else if (tableView == mWorksheetTable) {
  326. // get the worksheet entry's title
  327. GDataEntryWorksheet *worksheetEntry = [[mWorksheetFeed entries] objectAtIndex:row];
  328. return [[worksheetEntry title] stringValue];
  329. } else {
  330. // entry table; get a string for the cell or the list item
  331. GDataEntryBase *entry = [[mEntryFeed entries] objectAtIndex:row];
  332. NSString *displayStr;
  333. if ([entry isKindOfClass:[GDataEntrySpreadsheetCell class]]) {
  334. // format cell entry data
  335. GDataSpreadsheetCell *cell = [(GDataEntrySpreadsheetCell *)entry cell];
  336. NSString *resultStr = [cell resultString]; // like "3.1415926"
  337. NSString *inputStr = [cell inputString]; // like "=pi()"
  338. NSString *title = [[entry title] stringValue]; // like "A3"
  339. // show the input string (like =pi()) only if it differs
  340. // from the result string
  341. if (!inputStr || (resultStr && [inputStr isEqual:resultStr])) {
  342. inputStr = @"";
  343. }
  344. displayStr = [NSString stringWithFormat:@"%@: %@ %@",
  345. title, inputStr, (resultStr ? resultStr : @"")];
  346. } else {
  347. // format list entry data
  348. //
  349. // a list entry we will show as a sequence of (name,value) items from
  350. // the entry's custom elements
  351. GDataEntrySpreadsheetList *listEntry = (GDataEntrySpreadsheetList *)entry;
  352. NSDictionary *customElements = [listEntry customElementDictionary];
  353. NSMutableArray *array = [NSMutableArray array];
  354. NSEnumerator *enumerator = [customElements objectEnumerator];
  355. GDataSpreadsheetCustomElement *element;
  356. while ((element = [enumerator nextObject]) != nil) {
  357. NSString *elemStr = [NSString stringWithFormat:@"(%@, %@)",
  358. [element name], [element stringValue]];
  359. [array addObject:elemStr];
  360. }
  361. displayStr = [array componentsJoinedByString:@", "];
  362. }
  363. return displayStr;
  364. }
  365. }
  366. #pragma mark Setters and Getters
  367. - (GDataFeedSpreadsheet *)spreadsheetFeed {
  368. return mSpreadsheetFeed;
  369. }
  370. - (void)setSpreadsheetFeed:(GDataFeedSpreadsheet *)feed {
  371. [mSpreadsheetFeed autorelease];
  372. mSpreadsheetFeed = [feed retain];
  373. }
  374. - (NSError *)spreadsheetFetchError {
  375. return mSpreadsheetFetchError;
  376. }
  377. - (void)setSpreadsheetFetchError:(NSError *)error {
  378. [mSpreadsheetFetchError release];
  379. mSpreadsheetFetchError = [error retain];
  380. }
  381. - (GDataFeedWorksheet *)worksheetFeed {
  382. return mWorksheetFeed;
  383. }
  384. - (void)setWorksheetFeed:(GDataFeedWorksheet *)feed {
  385. [mWorksheetFeed autorelease];
  386. mWorksheetFeed = [feed retain];
  387. }
  388. - (NSError *)worksheetFetchError {
  389. return mWorksheetFetchError;
  390. }
  391. - (void)setWorksheetFetchError:(NSError *)error {
  392. [mWorksheetFetchError release];
  393. mWorksheetFetchError = [error retain];
  394. }
  395. - (GDataFeedBase *)entryFeed {
  396. return mEntryFeed;
  397. }
  398. - (void)setEntryFeed:(GDataFeedBase *)feed {
  399. [mEntryFeed autorelease];
  400. mEntryFeed = [feed retain];
  401. }
  402. - (NSError *)entryFetchError {
  403. return mEntryFetchError;
  404. }
  405. - (void)setEntryFetchError:(NSError *)error {
  406. [mEntryFetchError release];
  407. mEntryFetchError = [error retain];
  408. }
  409. @end